diff --git a/processor/k8sattributesprocessor/config.go b/processor/k8sattributesprocessor/config.go index 18bbedd048cc..3003c86e9b9d 100644 --- a/processor/k8sattributesprocessor/config.go +++ b/processor/k8sattributesprocessor/config.go @@ -77,8 +77,8 @@ type ExtractConfig struct { // k8s.node.name, k8s.namespace.name, k8s.pod.start_time, // k8s.replicaset.name, k8s.replicaset.uid, // k8s.daemonset.name, k8s.daemonset.uid, - // k8s.job.name, k8s.job.uid, - // k8s.statefulset.name, and k8s.statefulset.uid + // k8s.job.name, k8s.job.uid, k8s.cronjob.name, + // k8s.statefulset.name, k8s.statefulset.uid // // 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. diff --git a/processor/k8sattributesprocessor/internal/kube/client.go b/processor/k8sattributesprocessor/internal/kube/client.go index 5e783a0f6893..3615414e22ae 100644 --- a/processor/k8sattributesprocessor/internal/kube/client.go +++ b/processor/k8sattributesprocessor/internal/kube/client.go @@ -43,6 +43,7 @@ type WatchClient struct { informer cache.SharedInformer namespaceInformer cache.SharedInformer replicasetRegex *regexp.Regexp + cronJobRegex *regexp.Regexp deleteQueue []deleteRequest stopCh chan struct{} @@ -63,6 +64,10 @@ type WatchClient struct { // format: [deployment-name]-[Random-String-For-ReplicaSet] var rRegex = regexp.MustCompile(`^(.*)-[0-9a-zA-Z]+$`) +// Extract CronJob name from the Job name. Job name is created using +// format: [cronjob-name]-[time-hash-int] +var cronJobRegex = regexp.MustCompile(`^(.*)-[0-9]+$`) + // New initializes a new k8s Client. func New(logger *zap.Logger, apiCfg k8sconfig.APIConfig, rules ExtractionRules, filters Filters, associations []Association, exclude Excludes, newClientSet APIClientsetProvider, newInformer InformerProvider, newNamespaceInformer InformerProviderNamespace) (Client, error) { c := &WatchClient{ @@ -72,6 +77,7 @@ func New(logger *zap.Logger, apiCfg k8sconfig.APIConfig, rules ExtractionRules, Associations: associations, Exclude: exclude, replicasetRegex: rRegex, + cronJobRegex: cronJobRegex, stopCh: make(chan struct{}), } go c.deleteLoop(time.Second*30, defaultPodDeleteGracePeriod) @@ -296,7 +302,7 @@ func (c *WatchClient) extractPodAttributes(pod *api_v1.Pod) map[string]string { c.Rules.DaemonSetUID || c.Rules.DaemonSetName || c.Rules.JobUID || c.Rules.JobName || c.Rules.StatefulSetUID || c.Rules.StatefulSetName || - c.Rules.Deployment { + c.Rules.Deployment || c.Rules.CronJobName { for _, ref := range pod.OwnerReferences { switch ref.Kind { case "ReplicaSet": @@ -328,6 +334,12 @@ func (c *WatchClient) extractPodAttributes(pod *api_v1.Pod) map[string]string { tags[conventions.AttributeK8SStatefulSetName] = ref.Name } case "Job": + if c.Rules.CronJobName { + parts := c.cronJobRegex.FindStringSubmatch(ref.Name) + if len(parts) == 2 { + tags[conventions.AttributeK8SCronJobName] = parts[1] + } + } if c.Rules.JobUID { tags[conventions.AttributeK8SJobUID] = string(ref.UID) } diff --git a/processor/k8sattributesprocessor/internal/kube/client_test.go b/processor/k8sattributesprocessor/internal/kube/client_test.go index 5a877d36c7eb..ab3c94899539 100644 --- a/processor/k8sattributesprocessor/internal/kube/client_test.go +++ b/processor/k8sattributesprocessor/internal/kube/client_test.go @@ -464,7 +464,7 @@ func TestExtractionRules(t *testing.T) { { APIVersion: "batch/v1", Kind: "Job", - Name: "pi", + Name: "auth-cronjob-27667920", UID: "59f27ac1-5c71-42e5-abe9-2c499d603706", }, { @@ -545,7 +545,15 @@ func TestExtractionRules(t *testing.T) { JobName: true, }, attributes: map[string]string{ - "k8s.job.name": "pi", + "k8s.job.name": "auth-cronjob-27667920", + }, + }, { + name: "cronJob", + rules: ExtractionRules{ + CronJobName: true, + }, + attributes: map[string]string{ + "k8s.cronjob.name": "auth-cronjob", }, }, { name: "statefulsetUID", diff --git a/processor/k8sattributesprocessor/internal/kube/kube.go b/processor/k8sattributesprocessor/internal/kube/kube.go index 7b58ce55f680..52bea4d0f625 100644 --- a/processor/k8sattributesprocessor/internal/kube/kube.go +++ b/processor/k8sattributesprocessor/internal/kube/kube.go @@ -182,6 +182,7 @@ type FieldFilter struct { // ExtractionRules is used to specify the information that needs to be extracted // from pods and added to the spans as tags. type ExtractionRules struct { + CronJobName bool Deployment bool DaemonSetUID bool DaemonSetName bool diff --git a/processor/k8sattributesprocessor/options.go b/processor/k8sattributesprocessor/options.go index a248ed6ca176..0793f6e10016 100644 --- a/processor/k8sattributesprocessor/options.go +++ b/processor/k8sattributesprocessor/options.go @@ -114,6 +114,8 @@ func withExtractMetadata(fields ...string) option { p.rules.JobName = true case conventions.AttributeK8SJobUID: p.rules.JobUID = true + case conventions.AttributeK8SCronJobName: + p.rules.CronJobName = true case metadataNode, conventions.AttributeK8SNodeName: p.rules.Node = true case conventions.AttributeContainerID: diff --git a/unreleased/k8sattributes-cronjob.yaml b/unreleased/k8sattributes-cronjob.yaml new file mode 100755 index 000000000000..5393bc90c39d --- /dev/null +++ b/unreleased/k8sattributes-cronjob.yaml @@ -0,0 +1,16 @@ +# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' +change_type: enhancement + +# The name of the component, or a single word describing the area of concern, (e.g. filelogreceiver) +component: k8sattributesprocessor + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: "Add support for discovering Kubernetes CronJob name" + +# One or more tracking issues related to the change +issues: [141] + +# (Optional) One or more lines of additional information to render under the primary note. +# These lines will be padded with 2 spaces and then inserted directly into the document. +# Use pipe (|) for multiline entries. +subtext: