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

Add semantic conventions to k8s-tagger for pod metadata #3544

Merged
Show file tree
Hide file tree
Changes from 3 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
4 changes: 2 additions & 2 deletions processor/k8sprocessor/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,8 @@ type ExtractConfig struct {
// The field accepts a list of strings.
//
// Metadata fields supported right now are,
// namespace, podName, podUID, deployment, cluster, node and startTime
//
// k8s.namespace.name, k8s.pod.name, k8s.pod.uid, k8s.deployment.name, k8s.cluster.name,
// k8s.node.name and k8s.pod.start_time
// Specifying anything other than these values will result in an error.
// By default all of the fields are extracted and added to spans and metrics.
Metadata []string `mapstructure:"metadata"`
Expand Down
2 changes: 1 addition & 1 deletion processor/k8sprocessor/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ func TestLoadConfig(t *testing.T) {
APIConfig: k8sconfig.APIConfig{AuthType: k8sconfig.AuthTypeKubeConfig},
Passthrough: false,
Extract: ExtractConfig{
Metadata: []string{"podName", "podUID", "deployment", "cluster", "namespace", "node", "startTime"},
Metadata: []string{"k8s.pod.name", "k8s.pod.uid", "k8s.deployment.name", "k8s.cluster.name", "k8s.namespace.name", "k8s.node.name", "k8s.pod.start_time"},
Annotations: []FieldExtractConfig{
{TagName: "a1", Key: "annotation-one"},
{TagName: "a2", Key: "annotation-two", Regex: "field=(?P<value>.+)"},
Expand Down
38 changes: 38 additions & 0 deletions processor/k8sprocessor/factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,14 @@ package k8sprocessor

import (
"context"
"fmt"

"go.opentelemetry.io/collector/component"
"go.opentelemetry.io/collector/config"
"go.opentelemetry.io/collector/consumer"
"go.opentelemetry.io/collector/processor/processorhelper"
"go.opentelemetry.io/collector/translator/conventions"
"go.uber.org/zap"

"github.com/open-telemetry/opentelemetry-collector-contrib/internal/k8sconfig"
"github.com/open-telemetry/opentelemetry-collector-contrib/processor/k8sprocessor/kube"
Expand Down Expand Up @@ -149,6 +152,8 @@ func createKubernetesProcessor(
) (*kubernetesprocessor, error) {
kp := &kubernetesprocessor{logger: params.Logger}

warnDeprecatedMetadataConfig(kp.logger, cfg)

allOptions := append(createProcessorOpts(cfg), options...)

for _, opt := range allOptions {
Expand Down Expand Up @@ -191,3 +196,36 @@ func createProcessorOpts(cfg config.Processor) []Option {

return opts
}

func warnDeprecatedMetadataConfig(logger *zap.Logger, cfg config.Processor) {
oCfg := cfg.(*Config)
for _, field := range oCfg.Extract.Metadata {
chaitanyaphalak marked this conversation as resolved.
Show resolved Hide resolved
var oldName, newName string
switch field {
case metdataNamespace:
oldName = metdataNamespace
newName = conventions.AttributeK8sNamespace
case metadataPodName:
oldName = metadataPodName
newName = conventions.AttributeK8sPod
case metadataPodUID:
oldName = metadataPodUID
newName = conventions.AttributeK8sPodUID
case metadataStartTime:
oldName = metadataStartTime
newName = metadataPodStartTime
case metadataDeployment:
oldName = metadataDeployment
newName = conventions.AttributeK8sDeployment
case metadataCluster:
oldName = metadataCluster
newName = conventions.AttributeK8sCluster
case metadataNode:
oldName = metadataNode
newName = conventions.AttributeK8sNodeName
}
if oldName != "" {
logger.Warn(fmt.Sprintf("%s has been deprecated in favor of %s for k8s-tagger processor", oldName, newName))
}
chaitanyaphalak marked this conversation as resolved.
Show resolved Hide resolved
}
}
33 changes: 18 additions & 15 deletions processor/k8sprocessor/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"os"
"regexp"

"go.opentelemetry.io/collector/translator/conventions"
"k8s.io/apimachinery/pkg/selection"

"github.com/open-telemetry/opentelemetry-collector-contrib/internal/k8sconfig"
Expand All @@ -30,14 +31,16 @@ const (
filterOPNotEquals = "not-equals"
filterOPExists = "exists"
filterOPDoesNotExist = "does-not-exist"

// Used for maintaining backward compatibility
metdataNamespace = "namespace"
metadataPodName = "podName"
metadataPodUID = "podUID"
metadataStartTime = "startTime"
metadataDeployment = "deployment"
metadataCluster = "cluster"
metadataNode = "node"
// Will be removed when new fields get merged to https://github.com/open-telemetry/opentelemetry-collector/blob/main/translator/conventions/opentelemetry.go
metadataPodStartTime = "k8s.pod.start_time"
)

// Option represents a configuration option that can be passes.
Expand Down Expand Up @@ -68,30 +71,30 @@ func WithExtractMetadata(fields ...string) Option {
return func(p *kubernetesprocessor) error {
if len(fields) == 0 {
fields = []string{
metdataNamespace,
metadataPodName,
metadataPodUID,
metadataStartTime,
metadataDeployment,
metadataCluster,
metadataNode,
conventions.AttributeK8sNamespace,
conventions.AttributeK8sPod,
conventions.AttributeK8sPodUID,
metadataPodStartTime,
conventions.AttributeK8sDeployment,
conventions.AttributeK8sCluster,
conventions.AttributeK8sNodeName,
}
}
for _, field := range fields {
switch field {
case metdataNamespace:
case metdataNamespace, conventions.AttributeK8sNamespace:
chaitanyaphalak marked this conversation as resolved.
Show resolved Hide resolved
p.rules.Namespace = true
case metadataPodName:
case metadataPodName, conventions.AttributeK8sPod:
p.rules.PodName = true
case metadataPodUID:
case metadataPodUID, conventions.AttributeK8sPodUID:
p.rules.PodUID = true
case metadataStartTime:
case metadataStartTime, metadataPodStartTime:
p.rules.StartTime = true
case metadataDeployment:
case metadataDeployment, conventions.AttributeK8sDeployment:
p.rules.Deployment = true
case metadataCluster:
case metadataCluster, conventions.AttributeK8sCluster:
p.rules.Cluster = true
case metadataNode:
case metadataNode, conventions.AttributeK8sNodeName:
p.rules.Node = true
default:
return fmt.Errorf("\"%s\" is not a supported metadata field", field)
Expand Down
12 changes: 12 additions & 0 deletions processor/k8sprocessor/options_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"testing"

"github.com/stretchr/testify/assert"
"go.opentelemetry.io/collector/translator/conventions"
"k8s.io/apimachinery/pkg/selection"

"github.com/open-telemetry/opentelemetry-collector-contrib/internal/k8sconfig"
Expand Down Expand Up @@ -219,6 +220,17 @@ func TestWithExtractMetadata(t *testing.T) {
assert.False(t, p.rules.StartTime)
assert.False(t, p.rules.Deployment)
assert.False(t, p.rules.Node)

p = &kubernetesprocessor{}

assert.NoError(t, WithExtractMetadata(conventions.AttributeK8sNamespace, conventions.AttributeK8sPod, conventions.AttributeK8sPodUID)(p))
assert.True(t, p.rules.Namespace)
assert.False(t, p.rules.Cluster)
assert.True(t, p.rules.PodName)
assert.True(t, p.rules.PodUID)
assert.False(t, p.rules.StartTime)
assert.False(t, p.rules.Deployment)
assert.False(t, p.rules.Node)
}

func TestWithFilterLabels(t *testing.T) {
Expand Down
6 changes: 3 additions & 3 deletions processor/k8sprocessor/processor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,7 @@ func TestProcessorNoAttrs(t *testing.T) {
t,
NewFactory().CreateDefaultConfig(),
nil,
WithExtractMetadata(metadataPodName),
WithExtractMetadata(conventions.AttributeK8sPod),
)

ctx := client.NewContext(context.Background(), &client.Client{IP: "1.1.1.1"})
Expand Down Expand Up @@ -701,7 +701,7 @@ func TestMetricsProcessorHostname(t *testing.T) {
p, err := newMetricsProcessor(
NewFactory().CreateDefaultConfig(),
next,
WithExtractMetadata(metadataPodName),
WithExtractMetadata(conventions.AttributeK8sPod),
withExtractKubernetesProcessorInto(&kp),
)
require.NoError(t, err)
Expand Down Expand Up @@ -771,7 +771,7 @@ func TestMetricsProcessorHostnameWithPodAssociation(t *testing.T) {
p, err := newMetricsProcessor(
NewFactory().CreateDefaultConfig(),
next,
WithExtractMetadata(metadataPodName),
WithExtractMetadata(conventions.AttributeK8sPod),
withExtractKubernetesProcessorInto(&kp),
)
require.NoError(t, err)
Expand Down
22 changes: 15 additions & 7 deletions processor/k8sprocessor/testdata/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,21 @@ processors:
extract:
metadata:
# extract the following well-known metadata fields
- podName
- podUID
- deployment
- cluster
- namespace
- node
- startTime
- k8s.pod.name
- k8s.pod.uid
- k8s.deployment.name
- k8s.cluster.name
- k8s.namespace.name
- k8s.node.name
- k8s.pod.start_time
# the following metadata fields configuration options are deprecated
# - podName
# - podUID
# - deployment
# - cluster
# - namespace
# - node
# - startTime

annotations:
- tag_name: a1 # extracts value of annotation with key `annotation-one` and inserts it as a tag with key `a1`
Expand Down