Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(origindetection): implement LocalData struct for DogStatsD #32757

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion comp/core/tagger/impl/tagger.go
Original file line number Diff line number Diff line change
Expand Up @@ -470,7 +470,7 @@ func (t *TaggerWrapper) EnrichTags(tb tagset.TagsAccumulator, originInfo taggert
// Accumulate tags for pod UID
if originInfo.ExternalData.PodUID != "" {
if err := t.AccumulateTagsFor(types.NewEntityID(types.KubernetesPodUID, originInfo.ExternalData.PodUID), cardinality, tb); err != nil {
t.log.Tracef("Cannot get tags for entity %s: %s", originInfo.ContainerID, err)
t.log.Tracef("Cannot get tags for entity %s: %s", originInfo.ExternalData.PodUID, err)
}
}

Expand Down
45 changes: 45 additions & 0 deletions comp/core/tagger/origindetection/origindetection.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,14 @@ const (
// ProductOriginAPM is the ProductOrigin for APM.
ProductOriginAPM ProductOrigin = iota

// Local Data Prefixes
// These prefixes are used to build the Local Data list.

// LocalDataContainerIDPrefix is the prefix used for the Container ID sent in the Local Data list.
LocalDataContainerIDPrefix = "ci-"
// LocalDataInodePrefix is the prefix used for the Inode sent in the Local Data list.
LocalDataInodePrefix = "in-"

// External Data Prefixes
// These prefixes are used to build the External Data Environment Variable.

Expand Down Expand Up @@ -63,13 +71,49 @@ type ExternalData struct {
// GenerateContainerIDFromExternalData generates a container ID from the external data.
type GenerateContainerIDFromExternalData func(externalData ExternalData) (string, error)

// ParseLocalData parses the local data string into a LocalData struct.
func ParseLocalData(rawLocalData string) (LocalData, error) {
if rawLocalData == "" {
return LocalData{}, nil
}

var localData LocalData
var parsingError error

if strings.Contains(rawLocalData, ",") {
// The Local Data can contain a list.
items := strings.Split(rawLocalData, ",")
for _, item := range items {
if strings.HasPrefix(item, LocalDataContainerIDPrefix) {
localData.ContainerID = item[len(LocalDataContainerIDPrefix):]
} else if strings.HasPrefix(item, LocalDataInodePrefix) {
localData.Inode, parsingError = strconv.ParseUint(item[len(LocalDataInodePrefix):], 10, 64)
}
}
} else {
// The Local Data can contain a single value.
if strings.HasPrefix(rawLocalData, LocalDataContainerIDPrefix) {
localData.ContainerID = rawLocalData[len(LocalDataContainerIDPrefix):]
} else if strings.HasPrefix(rawLocalData, LocalDataInodePrefix) {
localData.Inode, parsingError = strconv.ParseUint(rawLocalData[len(LocalDataInodePrefix):], 10, 64)
} else {
// Container ID with old format: <container-id>
localData.ContainerID = rawLocalData
}
}

return localData, parsingError
}

// ParseExternalData parses the external data string into an ExternalData struct.
func ParseExternalData(externalEnv string) (ExternalData, error) {
if externalEnv == "" {
return ExternalData{}, nil
}

var externalData ExternalData
var parsingError error

for _, item := range strings.Split(externalEnv, ",") {
switch {
case strings.HasPrefix(item, ExternalDataInitPrefix):
Expand All @@ -80,5 +124,6 @@ func ParseExternalData(externalEnv string) (ExternalData, error) {
externalData.PodUID = item[len(ExternalDataPodUIDPrefix):]
}
}

return externalData, parsingError
}
59 changes: 59 additions & 0 deletions comp/core/tagger/origindetection/origindetection_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,65 @@ import (
"github.com/stretchr/testify/assert"
)

func TestParseLocalData(t *testing.T) {
tests := []struct {
name string
rawLocalData string
expected LocalData
expectError bool
}{
{
name: "Empty string",
rawLocalData: "",
expected: LocalData{},
expectError: false,
},
{
name: "Single container ID",
rawLocalData: "ci-abc123",
expected: LocalData{ContainerID: "abc123"},
expectError: false,
},
{
name: "Single inode",
rawLocalData: "in-12345",
expected: LocalData{Inode: 12345},
expectError: false,
},
{
name: "Multiple values",
rawLocalData: "ci-abc123,in-12345",
expected: LocalData{ContainerID: "abc123", Inode: 12345},
expectError: false,
},
{
name: "Invalid inode",
rawLocalData: "in-invalid",
expected: LocalData{},
expectError: true,
},
{
name: "Old container format",
rawLocalData: "abc123",
expected: LocalData{ContainerID: "abc123"},
expectError: false,
},
}

for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
result, err := ParseLocalData(tc.rawLocalData)

if tc.expectError {
assert.Error(t, err)
} else {
assert.Equal(t, tc.expected, result)
}

})
}
}

func TestParseExternalData(t *testing.T) {
tests := []struct {
name string
Expand Down
11 changes: 6 additions & 5 deletions comp/dogstatsd/server/enrich.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,13 @@ type enrichConfig struct {
}

// extractTagsMetadata returns tags (client tags + host tag) and information needed to query tagger (origins, cardinality).
func extractTagsMetadata(tags []string, originFromUDS string, originFromMsg []byte, externalData origindetection.ExternalData, conf enrichConfig) ([]string, string, taggertypes.OriginInfo, metrics.MetricSource) {
func extractTagsMetadata(tags []string, originFromUDS string, localData origindetection.LocalData, externalData origindetection.ExternalData, conf enrichConfig) ([]string, string, taggertypes.OriginInfo, metrics.MetricSource) {
host := conf.defaultHostname
metricSource := metrics.MetricSourceDogstatsd
origin := taggertypes.OriginInfo{
ContainerIDFromSocket: originFromUDS,
ContainerID: string(originFromMsg),
ContainerID: localData.ContainerID,
LocalData: localData,
ExternalData: externalData,
ProductOrigin: origindetection.ProductOriginDogStatsD,
}
Expand Down Expand Up @@ -112,7 +113,7 @@ func tsToFloatForSamples(ts time.Time) float64 {

func enrichMetricSample(dest []metrics.MetricSample, ddSample dogstatsdMetricSample, origin string, listenerID string, conf enrichConfig) []metrics.MetricSample {
metricName := ddSample.name
tags, hostnameFromTags, extractedOrigin, metricSource := extractTagsMetadata(ddSample.tags, origin, ddSample.containerID, ddSample.externalData, conf)
tags, hostnameFromTags, extractedOrigin, metricSource := extractTagsMetadata(ddSample.tags, origin, ddSample.localData, ddSample.externalData, conf)

if !isExcluded(metricName, conf.metricPrefix, conf.metricPrefixBlacklist) {
metricName = conf.metricPrefix + metricName
Expand Down Expand Up @@ -192,7 +193,7 @@ func enrichEventAlertType(dogstatsdAlertType alertType) metricsevent.AlertType {
}

func enrichEvent(event dogstatsdEvent, origin string, conf enrichConfig) *metricsevent.Event {
tags, hostnameFromTags, extractedOrigin, _ := extractTagsMetadata(event.tags, origin, event.containerID, event.externalData, conf)
tags, hostnameFromTags, extractedOrigin, _ := extractTagsMetadata(event.tags, origin, event.localData, event.externalData, conf)

enrichedEvent := &metricsevent.Event{
Title: event.title,
Expand Down Expand Up @@ -229,7 +230,7 @@ func enrichServiceCheckStatus(status serviceCheckStatus) servicecheck.ServiceChe
}

func enrichServiceCheck(serviceCheck dogstatsdServiceCheck, origin string, conf enrichConfig) *servicecheck.ServiceCheck {
tags, hostnameFromTags, extractedOrigin, _ := extractTagsMetadata(serviceCheck.tags, origin, serviceCheck.containerID, serviceCheck.externalData, conf)
tags, hostnameFromTags, extractedOrigin, _ := extractTagsMetadata(serviceCheck.tags, origin, serviceCheck.localData, serviceCheck.externalData, conf)

enrichedServiceCheck := &servicecheck.ServiceCheck{
CheckName: serviceCheck.name,
Expand Down
2 changes: 1 addition & 1 deletion comp/dogstatsd/server/enrich_bench_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ func BenchmarkExtractTagsMetadata(b *testing.B) {
sb.ResetTimer()

for n := 0; n < sb.N; n++ {
tags, _, _, _ = extractTagsMetadata(baseTags, "", []byte{}, origindetection.ExternalData{}, conf)
tags, _, _, _ = extractTagsMetadata(baseTags, "", origindetection.LocalData{}, origindetection.ExternalData{}, conf)
}
})
}
Expand Down
Loading
Loading