diff --git a/pkg/executor/slow_query.go b/pkg/executor/slow_query.go index b0762e5c3083b..d8d71c04394f7 100644 --- a/pkg/executor/slow_query.go +++ b/pkg/executor/slow_query.go @@ -594,6 +594,10 @@ func splitByColon(line string) (fields []string, values []string) { fields = append(fields, line[start:current]) parseKey = false current += 2 // bypass ": " + if current >= lineLength { + // last empty value + values = append(values, "") + } } else { start = current if current < lineLength && (line[current] == '{' || line[current] == '[') { @@ -607,6 +611,13 @@ func splitByColon(line string) (fields []string, values []string) { for current < lineLength && line[current] != ' ' { current++ } + // Meet empty value cases: "Key: Key:" + if current > 0 && line[current-1] == ':' { + values = append(values, "") + current = start + parseKey = true + continue + } } values = append(values, line[start:min(current, len(line))]) parseKey = true @@ -616,6 +627,10 @@ func splitByColon(line string) (fields []string, values []string) { logutil.BgLogger().Warn("slow query parse slow log error", zap.String("Error", errMsg), zap.String("Log", line)) return nil, nil } + if len(fields) != len(values) { + logutil.BgLogger().Warn("slow query parse slow log error", zap.Int("field_count", len(fields)), zap.Int("value_count", len(values)), zap.String("Log", line)) + return nil, nil + } return fields, values } diff --git a/pkg/executor/slow_query_test.go b/pkg/executor/slow_query_test.go index 9305c9820261b..dd6428b711302 100644 --- a/pkg/executor/slow_query_test.go +++ b/pkg/executor/slow_query_test.go @@ -533,7 +533,7 @@ func TestSplitbyColon(t *testing.T) { { "123a", []string{"123a"}, - []string{}, + []string{""}, }, { "1a: 2b", @@ -586,9 +586,16 @@ func TestSplitbyColon(t *testing.T) { []string{"Time"}, []string{"2021-09-08T14:39:54.506967433+08:00"}, }, + { + + "Cop_proc_avg: 0 Cop_proc_addr: Cop_proc_max: Cop_proc_min: ", + []string{"Cop_proc_avg", "Cop_proc_addr", "Cop_proc_max", "Cop_proc_min"}, + []string{"0", "", "", ""}, + }, } for _, c := range cases { resFields, resValues := splitByColon(c.line) + logutil.BgLogger().Info(c.line) require.Equal(t, c.fields, resFields) require.Equal(t, c.values, resValues) }