Skip to content

Commit 2894e66

Browse files
fix(logging): fix stdout log http request format (#7083)
1 parent d96cb02 commit 2894e66

File tree

2 files changed

+46
-8
lines changed

2 files changed

+46
-8
lines changed

β€Žlogging/logging.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -920,6 +920,41 @@ type structuredLogEntry struct {
920920
TraceSampled bool `json:"logging.googleapis.com/trace_sampled,omitempty"`
921921
}
922922

923+
func convertSnakeToMixedCase(snakeStr string) string {
924+
words := strings.Split(snakeStr, "_")
925+
mixedStr := words[0]
926+
for _, word := range words[1:] {
927+
mixedStr += strings.Title(word)
928+
}
929+
return mixedStr
930+
}
931+
932+
func (s structuredLogEntry) MarshalJSON() ([]byte, error) {
933+
// extract structuredLogEntry into json map
934+
type Alias structuredLogEntry
935+
var mapData map[string]interface{}
936+
data, err := json.Marshal(Alias(s))
937+
if err == nil {
938+
err = json.Unmarshal(data, &mapData)
939+
}
940+
if err == nil {
941+
// ensure all inner dicts use mixed case instead of snake case
942+
innerDicts := [3]string{"httpRequest", "logging.googleapis.com/operation", "logging.googleapis.com/sourceLocation"}
943+
for _, field := range innerDicts {
944+
if fieldData, ok := mapData[field]; ok {
945+
formattedFieldData := make(map[string]interface{})
946+
for k, v := range fieldData.(map[string]interface{}) {
947+
formattedFieldData[convertSnakeToMixedCase(k)] = v
948+
}
949+
mapData[field] = formattedFieldData
950+
}
951+
}
952+
// serialize json map into raw bytes
953+
return json.Marshal(mapData)
954+
}
955+
return data, err
956+
}
957+
923958
func serializeEntryToWriter(entry *logpb.LogEntry, w io.Writer) error {
924959
jsonifiedEntry := structuredLogEntry{
925960
Severity: entry.Severity.String(),

β€Žlogging/logging_test.go

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1281,12 +1281,14 @@ func TestRedirectOutputFormats(t *testing.T) {
12811281
Method: "POST",
12821282
},
12831283
},
1284+
12841285
Payload: "this is text payload",
12851286
},
1286-
want: `{"message":"this is text payload","severity":"DEBUG","httpRequest":{"request_method":"POST","request_url":"https://example.com/test"},` +
1287-
`"timestamp":"seconds:1000","logging.googleapis.com/labels":{"key1":"value1","key2":"value2"},"logging.googleapis.com/insertId":"0000AAA01",` +
1288-
`"logging.googleapis.com/operation":{"id":"0123456789","producer":"test"},"logging.googleapis.com/sourceLocation":{"file":"acme.go","line":100,"function":"main"},` +
1289-
`"logging.googleapis.com/spanId":"000000000001","logging.googleapis.com/trace":"projects/P/ABCD12345678AB12345678","logging.googleapis.com/trace_sampled":true}`,
1287+
want: `{"httpRequest":{"requestMethod":"POST","requestUrl":"https://example.com/test"},"logging.googleapis.com/insertId":"0000AAA01",` +
1288+
`"logging.googleapis.com/labels":{"key1":"value1","key2":"value2"},"logging.googleapis.com/operation":{"id":"0123456789","producer":"test"},` +
1289+
`"logging.googleapis.com/sourceLocation":{"file":"acme.go","function":"main","line":100},"logging.googleapis.com/spanId":"000000000001",` +
1290+
`"logging.googleapis.com/trace":"projects/P/ABCD12345678AB12345678","logging.googleapis.com/trace_sampled":true,` +
1291+
`"message":"this is text payload","severity":"DEBUG","timestamp":"seconds:1000"}`,
12901292
},
12911293
{
12921294
name: "full data redirect with json payload",
@@ -1318,10 +1320,11 @@ func TestRedirectOutputFormats(t *testing.T) {
13181320
"Latency": 321,
13191321
},
13201322
},
1321-
want: `{"message":{"Latency":321,"Message":"message part of the payload"},"severity":"DEBUG","httpRequest":{"request_method":"POST","request_url":"https://example.com/test"},` +
1322-
`"timestamp":"seconds:1000","logging.googleapis.com/labels":{"key1":"value1","key2":"value2"},"logging.googleapis.com/insertId":"0000AAA01",` +
1323-
`"logging.googleapis.com/operation":{"id":"0123456789","producer":"test"},"logging.googleapis.com/sourceLocation":{"file":"acme.go","line":100,"function":"main"},` +
1324-
`"logging.googleapis.com/spanId":"000000000001","logging.googleapis.com/trace":"projects/P/ABCD12345678AB12345678","logging.googleapis.com/trace_sampled":true}`,
1323+
want: `{"httpRequest":{"requestMethod":"POST","requestUrl":"https://example.com/test"},"logging.googleapis.com/insertId":"0000AAA01",` +
1324+
`"logging.googleapis.com/labels":{"key1":"value1","key2":"value2"},"logging.googleapis.com/operation":{"id":"0123456789","producer":"test"},` +
1325+
`"logging.googleapis.com/sourceLocation":{"file":"acme.go","function":"main","line":100},"logging.googleapis.com/spanId":"000000000001",` +
1326+
`"logging.googleapis.com/trace":"projects/P/ABCD12345678AB12345678","logging.googleapis.com/trace_sampled":true,` +
1327+
`"message":{"Latency":321,"Message":"message part of the payload"},"severity":"DEBUG","timestamp":"seconds:1000"}`,
13251328
},
13261329
{
13271330
name: "error on redirect with proto payload",

0 commit comments

Comments
 (0)