Skip to content

Commit 808f7f1

Browse files
craig[bot]aa-joshi
andcommitted
Merge #148259
148259: cli(debug.zip): add fallback for Datadog multiline log upload request r=aa-joshi a=aa-joshi We are relying on Datadog log API to upload logs and table data. We are receiving cryptic `Decompression error` with 4xx error code. We are suspecting due to request size >5MB post decompression on Datadog end. However, Datadog log API documentation has mentioned that log lines greater than 5MB will get truncated. To address this, we are introducing a fallback for Datadog multiline uplaod where will make Datadog API request for each line from the respective batch. Epic: None Part of: CRDB-51111 Release note: None Co-authored-by: Akshay Joshi <[email protected]>
2 parents 93519ae + 0f3ac49 commit 808f7f1

File tree

1 file changed

+30
-1
lines changed

1 file changed

+30
-1
lines changed

pkg/cli/zip_upload.go

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -729,7 +729,7 @@ func uploadZipTables(ctx context.Context, uploadID string, debugDirPath string)
729729
if _, err := uploadLogsToDatadog(
730730
chunk.payload, debugZipUploadOpts.ddAPIKey, debugZipUploadOpts.ddSite,
731731
); err != nil {
732-
fmt.Fprintf(os.Stderr, "failed to upload a part of %s: %s\n", chunk.tableName, err)
732+
uploadIndividualLogToDatadog(chunk)
733733
}
734734
}()
735735
}
@@ -757,6 +757,25 @@ func uploadZipTables(ctx context.Context, uploadID string, debugDirPath string)
757757
return nil
758758
}
759759

760+
// uploadIndividualLogToDatadog is a fallback function to upload the logs to datadog. We would receive cryptic "Decompression error"
761+
// errors from datadog. We are suspecting it is due to the logs being >5MB in size. So, we are uploading individual log
762+
// lines to datadog instead of the whole payload.
763+
func uploadIndividualLogToDatadog(chunk *tableDumpChunk) {
764+
logs, _ := getLogLinesFromPayload(chunk.payload)
765+
var stdErr error
766+
for _, logMap := range logs {
767+
logLine, _ := json.Marshal(logMap)
768+
if _, err := uploadLogsToDatadog(
769+
logLine, debugZipUploadOpts.ddAPIKey, debugZipUploadOpts.ddSite,
770+
); err != nil && stdErr == nil {
771+
stdErr = err
772+
}
773+
}
774+
if stdErr != nil {
775+
fmt.Fprintf(os.Stderr, "failed to upload a part of %s: %s\n", chunk.tableName, stdErr)
776+
}
777+
}
778+
760779
type ddArchivePayload struct {
761780
Type string `json:"type"`
762781
Attributes ddArchiveAttributes `json:"attributes"`
@@ -838,6 +857,7 @@ type logUploadSig struct {
838857
// number of lines and the size of the payload. But in case of CRDB logs, the
839858
// average size of 1000 lines is well within the limit (5MB). So, we are only
840859
// splitting based on the number of lines.
860+
// TODO(obs-india): consider log size in sig calculation
841861
func (s logUploadSig) split() []logUploadSig {
842862
var (
843863
noOfNewSignals = len(s.logLines)/datadogMaxLogLinesPerReq + 1
@@ -1249,6 +1269,15 @@ func makeDDMultiLineLogPayload(logLines [][]byte) []byte {
12491269
return buf.Bytes()
12501270
}
12511271

1272+
func getLogLinesFromPayload(payload []byte) ([]map[string]any, error) {
1273+
var logs []map[string]any
1274+
err := json.Unmarshal(payload, &logs)
1275+
if err != nil {
1276+
return nil, fmt.Errorf("failed to log lines: %w", err)
1277+
}
1278+
return logs, nil
1279+
}
1280+
12521281
// humanReadableSize converts the given number of bytes to a human readable
12531282
// format. Lowest unit is bytes and the highest unit is petabytes.
12541283
func humanReadableSize(bytes int) string {

0 commit comments

Comments
 (0)