diff --git a/internal/model1/fields.go b/internal/model1/fields.go index bb935b9bab..44665e8286 100644 --- a/internal/model1/fields.go +++ b/internal/model1/fields.go @@ -4,10 +4,7 @@ package model1 import ( - "fmt" "reflect" - "regexp" - "strings" ) // Fields represents a collection of row fields. @@ -16,34 +13,24 @@ type Fields []string // Customize returns a subset of fields. func (f Fields) Customize(cols []int, out Fields, extractionInfoBag ExtractionInfoBag) { for i, c := range cols { - if c < 0 { - // If current index can retrieve an extractionInfo from extractionInfoBag, - // meaning this column has to retrieve the actual value from other field. - // For example: `LABELS[kubernetes.io/hostname]` needs to extract the value from column `LABELS` - if extractionInfo, ok := extractionInfoBag[i]; ok { - idxInFields := extractionInfo.IdxInFields - key := extractionInfo.Key + extractionInfo, ok := extractionInfoBag[i] - // Escape dots from the key - // For example: `kubernetes.io/hostname` needs to be escaped to `kubernetes\.io/hostname` - escapedKey := strings.ReplaceAll(key, ".", "\\.") - - // Extract the value by using regex - pattern := fmt.Sprintf(`%s=([^ ]+)`, escapedKey) - regex := regexp.MustCompile(pattern) - - // Find the value in the field that store original values - matches := regex.FindStringSubmatch(f[idxInFields]) - if len(matches) > 1 { - out[i] = matches[1] - continue - } - } + // If the extractionInfo is existed in extractionInfoBag, + // meaning this column has to retrieve the actual value from other field. + // For example: `LABELS[kubernetes.io/hostname]` needs to extract the value from column `LABELS` + if c < 0 && ok { + idxInFields := extractionInfo.IdxInFields + escapedKey := escapeDots(extractionInfo.Key) + out[i] = extractValueFromField(escapedKey, f[idxInFields]) + continue + } + if c < 0 && !ok { out[i] = NAValue continue } + if c < len(f) { out[i] = f[c] } diff --git a/internal/model1/helpers.go b/internal/model1/helpers.go index fb0ac597a7..e16f205cdf 100644 --- a/internal/model1/helpers.go +++ b/internal/model1/helpers.go @@ -6,6 +6,7 @@ package model1 import ( "fmt" "math" + "regexp" "sort" "strings" @@ -164,3 +165,23 @@ func lessNumber(s1, s2 string) bool { return sortorder.NaturalLess(v1, v2) } + +// Escape dots from the string +// For example: `kubernetes.io/hostname` needs to be escaped to `kubernetes\.io/hostname` +func escapeDots(s string) string { + return strings.ReplaceAll(s, ".", "\\.") +} + +func extractValueFromField(key string, field string) string { + // Extract the value by using regex + pattern := fmt.Sprintf(`%s=([^ ]+)`, key) + regex := regexp.MustCompile(pattern) + + // Find the value in the field that store original values + matches := regex.FindStringSubmatch(field) + if len(matches) > 1 { + return matches[1] + } + + return "" +} diff --git a/internal/model1/helpers_test.go b/internal/model1/helpers_test.go index 3e6a04272f..84cb30c320 100644 --- a/internal/model1/helpers_test.go +++ b/internal/model1/helpers_test.go @@ -87,3 +87,29 @@ func BenchmarkDurationToSecond(b *testing.B) { durationToSeconds(t) } } + +func TestEscapeDots(t *testing.T) { + var s string + + s = escapeDots("kubernetes.io/hostname") + assert.Equal(t, "kubernetes\\.io/hostname", s) + + s = escapeDots("kubernetes-io/hostname") + assert.Equal(t, "kubernetes-io/hostname", s) +} + +func TestExtractValueFromFields(t *testing.T) { + k := escapeDots("kubernetes.io/hostname") + f := "kubernetes.io/arch=amd64 kubernetes.io/hostname=a-b-c-d kubernetes.io/os=linux" + + var s string + + s = extractValueFromField(k, f) + assert.Equal(t, "a-b-c-d", s) + + s = extractValueFromField(k, "kubernetes.io/hostname=e-f-g-h "+f) + assert.Equal(t, "e-f-g-h", s) + + s = extractValueFromField("random-key", f) + assert.Equal(t, "", s) +}