From 104f2025265886386cfe3ca0a1e92fd05821e011 Mon Sep 17 00:00:00 2001 From: James Muldoon Date: Wed, 12 Feb 2025 14:06:58 +0900 Subject: [PATCH 1/3] Add Kubernetes semantics to SpanAttributes Built out a suite of Kubernetes SpanAttributes conforming to SemConv of Otel. This adheres to https://opentelemetry.io/docs/specs/semconv/resource/k8s/. --- .../SpanAttributes+KubernetesSemantics.swift | 643 ++++++++++++++++++ .../KubernetesSemanticsTests.swift | 119 ++++ 2 files changed, 762 insertions(+) create mode 100644 Sources/TracingOpenTelemetrySemanticConventions/SpanAttributes+KubernetesSemantics.swift create mode 100644 Tests/TracingOpenTelemetrySemanticConventionsTests/KubernetesSemanticsTests.swift diff --git a/Sources/TracingOpenTelemetrySemanticConventions/SpanAttributes+KubernetesSemantics.swift b/Sources/TracingOpenTelemetrySemanticConventions/SpanAttributes+KubernetesSemantics.swift new file mode 100644 index 0000000..457c450 --- /dev/null +++ b/Sources/TracingOpenTelemetrySemanticConventions/SpanAttributes+KubernetesSemantics.swift @@ -0,0 +1,643 @@ +import Tracing + +extension SpanAttributes { + /// Kubernetes attributes. + /// + /// OpenTelemetry Spec: [Kubernetes attributes](https://opentelemetry.io/docs/specs/semconv/resource/k8s/) + public var k8s: KubernetesAttributes { + get { + .init(attributes: self) + } + set { + self = newValue.attributes + } + } +} + +/// Kubernetes attributes. +/// +/// OpenTelemetry Spec: [Kubernetes attributes](https://opentelemetry.io/docs/specs/semconv/resource/k8s/) +@dynamicMemberLookup +public struct KubernetesAttributes: SpanAttributeNamespace { + public var attributes: SpanAttributes + + public init(attributes: SpanAttributes) { + self.attributes = attributes + } + + // Mark - General + + public struct NestedSpanAttributes: NestedSpanAttributesProtocol { + public init() {} + } + + // Mark: - Cluster + + public var cluster: ClusterAttributes { + get { + .init(attributes: self.attributes) + } + set { + self.attributes = newValue.attributes + } + } + + public struct ClusterAttributes: SpanAttributeNamespace { + public var attributes: SpanAttributes + private let resource: String + + public init(attributes: SpanAttributes) { + self.attributes = attributes + self.resource = "cluster" + } + + /// Semantic conventions for Kubernetes labels. + public var labels: MetadataAttributes { + get { + .init(attributes: self.attributes, resource: self.resource, group: "label") + } + set { + self.attributes = newValue.attributes + } + } + + /// Semantic conventions for Kubernetes labels. + public var annotations: MetadataAttributes { + get { + .init(attributes: self.attributes, resource: self.resource, group: "annotation") + } + set { + self.attributes = newValue.attributes + } + } + + public struct NestedSpanAttributes: NestedSpanAttributesProtocol { + public init() {} + + /// Cluster Attributes + /// + /// "cluster" name; e.g. "swift-distributed-tracing-cluster". + public var name: Key { "k8s.cluster.name" } + /// "cluster" uid; e.g. "218fc5a9-a5f1-4b54-aa05-46717d0ab26d". + public var uid: Key { "k8s.cluster.uid" } + } + } + + // Mark - Container + + public var container: ContainerAttributes { + get { + .init(attributes: self.attributes) + } + set { + self.attributes = newValue.attributes + } + } + + public struct ContainerAttributes: SpanAttributeNamespace { + public var attributes: SpanAttributes + private let resource: String + + public init(attributes: SpanAttributes) { + self.attributes = attributes + self.resource = "container" + } + + /// Semantic conventions for Kubernetes labels. + public var labels: MetadataAttributes { + get { + .init(attributes: self.attributes, resource: self.resource, group: "label") + } + set { + self.attributes = newValue.attributes + } + } + + /// Semantic conventions for Kubernetes labels. + public var annotations: MetadataAttributes { + get { + .init(attributes: self.attributes, resource: self.resource, group: "annotation") + } + set { + self.attributes = newValue.attributes + } + } + + public struct NestedSpanAttributes: NestedSpanAttributesProtocol { + public init() {} + + /// Pod Attributes + /// + /// "container" name; e.g. "webserver". + public var name: Key { "k8s.container.name" } + /// "container" restart count; e.g. 3. + public var restartCount: Key { "k8s.container.restart_count" } + /// "container" last_terminated_reason; e.g. "Evicted". + public var lastTerminatedReason: Key { "k8s.container.last_terminated_reason" } + } + } + + // Mark - CronJob + + public var cronjob: CronJobAttributes { + get { + .init(attributes: self.attributes) + } + set { + self.attributes = newValue.attributes + } + } + + public struct CronJobAttributes: SpanAttributeNamespace { + public var attributes: SpanAttributes + private let resource: String + + public init(attributes: SpanAttributes) { + self.attributes = attributes + self.resource = "cronjob" + } + + /// Semantic conventions for Kubernetes labels. + public var labels: MetadataAttributes { + get { + .init(attributes: self.attributes, resource: self.resource, group: "label") + } + set { + self.attributes = newValue.attributes + } + } + + /// Semantic conventions for Kubernetes labels. + public var annotations: MetadataAttributes { + get { + .init(attributes: self.attributes, resource: self.resource, group: "annotation") + } + set { + self.attributes = newValue.attributes + } + } + + public struct NestedSpanAttributes: NestedSpanAttributesProtocol { + public init() {} + + /// CronJob Attributes + /// + /// "cronjob" name; e.g. "swift". + public var name: Key { "k8s.cronjob.name" } + /// "cronjob" uid; e.g. "70360e9a-f5ac-43c3-a996-3b949de67288". + public var uid: Key { "k8s.cronjob.uid" } + } + } + + // Mark - DaemonSet + + public var daemonset: DaemonSetAttributes { + get { + .init(attributes: self.attributes) + } + set { + self.attributes = newValue.attributes + } + } + + public struct DaemonSetAttributes: SpanAttributeNamespace { + public var attributes: SpanAttributes + private let resource: String + + public init(attributes: SpanAttributes) { + self.attributes = attributes + self.resource = "daemonset" + } + + /// Semantic conventions for Kubernetes labels. + public var labels: MetadataAttributes { + get { + .init(attributes: self.attributes, resource: self.resource, group: "label") + } + set { + self.attributes = newValue.attributes + } + } + + /// Semantic conventions for Kubernetes labels. + public var annotations: MetadataAttributes { + get { + .init(attributes: self.attributes, resource: self.resource, group: "annotation") + } + set { + self.attributes = newValue.attributes + } + } + + public struct NestedSpanAttributes: NestedSpanAttributesProtocol { + public init() {} + + /// DaemonSet Attributes + /// + /// "daemonset" name; e.g. "swift". + public var name: Key { "k8s.daemonset.name" } + /// "daemonset" uid; e.g. "34330774-22fb-411d-a986-374e813ac952". + public var uid: Key { "k8s.daemonset.uid" } + } + } + + // Mark - Deployment + + public var deployment: DeploymentAttributes { + get { + .init(attributes: self.attributes) + } + set { + self.attributes = newValue.attributes + } + } + + public struct DeploymentAttributes: SpanAttributeNamespace { + public var attributes: SpanAttributes + private let resource: String + + public init(attributes: SpanAttributes) { + self.attributes = attributes + self.resource = "deployment" + } + + /// Semantic conventions for Kubernetes labels. + public var labels: MetadataAttributes { + get { + .init(attributes: self.attributes, resource: self.resource, group: "label") + } + set { + self.attributes = newValue.attributes + } + } + + /// Semantic conventions for Kubernetes labels. + public var annotations: MetadataAttributes { + get { + .init(attributes: self.attributes, resource: self.resource, group: "annotation") + } + set { + self.attributes = newValue.attributes + } + } + + public struct NestedSpanAttributes: NestedSpanAttributesProtocol { + public init() {} + + /// Deployment Attributes + /// + /// "deployment" name; e.g. "swift". + public var name: Key { "k8s.deployment.name" } + /// "deployment" uid; e.g. "b9e5e87b-6d18-4525-bb8e-5efd00cad377". + public var uid: Key { "k8s.deployment.uid" } + } + } + + // Mark - Job + + public var job: JobAttributes { + get { + .init(attributes: self.attributes) + } + set { + self.attributes = newValue.attributes + } + } + + public struct JobAttributes: SpanAttributeNamespace { + public var attributes: SpanAttributes + private let resource: String + + public init(attributes: SpanAttributes) { + self.attributes = attributes + self.resource = "job" + } + + /// Semantic conventions for Kubernetes labels. + public var labels: MetadataAttributes { + get { + .init(attributes: self.attributes, resource: self.resource, group: "label") + } + set { + self.attributes = newValue.attributes + } + } + + /// Semantic conventions for Kubernetes labels. + public var annotations: MetadataAttributes { + get { + .init(attributes: self.attributes, resource: self.resource, group: "annotation") + } + set { + self.attributes = newValue.attributes + } + } + + public struct NestedSpanAttributes: NestedSpanAttributesProtocol { + public init() {} + + /// Job Attributes + /// + /// "job" name; e.g. "swift". + public var name: Key { "k8s.job.name" } + /// "job" uid; e.g. "250c0a82-2ea8-4ed1-99c8-b238b1b86784". + public var uid: Key { "k8s.job.uid" } + } + } + + // Mark - Namespace + + public var namespace: NamespaceAttributes { + get { + .init(attributes: self.attributes) + } + set { + self.attributes = newValue.attributes + } + } + + public struct NamespaceAttributes: SpanAttributeNamespace { + public var attributes: SpanAttributes + private let resource: String + + public init(attributes: SpanAttributes) { + self.attributes = attributes + self.resource = "namespace" + } + + /// Semantic conventions for Kubernetes labels. + public var labels: MetadataAttributes { + get { + .init(attributes: self.attributes, resource: self.resource, group: "label") + } + set { + self.attributes = newValue.attributes + } + } + + /// Semantic conventions for Kubernetes labels. + public var annotations: MetadataAttributes { + get { + .init(attributes: self.attributes, resource: self.resource, group: "annotation") + } + set { + self.attributes = newValue.attributes + } + } + + public struct NestedSpanAttributes: NestedSpanAttributesProtocol { + public init() {} + + /// Cluster Attributes + /// + /// "cluster" name; e.g. "default". + public var name: Key { "k8s.namespace.name" } + } + } + + + // Mark - Node + + /// Kubernetes attributes. + /// + /// OpenTelemetry Spec: [Kubernetes attributes](https://opentelemetry.io/docs/specs/semconv/resource/k8s/) + public var node: NodeAttributes { + get { + .init(attributes: self.attributes) + } + set { + self.attributes = newValue.attributes + } + } + public struct NodeAttributes: SpanAttributeNamespace { + public var attributes: SpanAttributes + private let resource: String + + public init(attributes: SpanAttributes) { + self.attributes = attributes + self.resource = "node" + } + + /// Semantic conventions for Kubernetes labels. + public var labels: MetadataAttributes { + get { + .init(attributes: self.attributes, resource: self.resource, group: "label") + } + set { + self.attributes = newValue.attributes + } + } + + /// Semantic conventions for Kubernetes labels. + public var annotations: MetadataAttributes { + get { + .init(attributes: self.attributes, resource: self.resource, group: "annotation") + } + set { + self.attributes = newValue.attributes + } + } + + public struct NestedSpanAttributes: NestedSpanAttributesProtocol { + public init() {} + + /// Cluster Attributes + /// + /// "cluster" name; e.g. "node-1". + public var name: Key { "k8s.node.name" } + /// "cluster" uid; e.g. "1eb3a0c6-0477-4080-a9cb-0cb7db65c6a2". + public var uid: Key { "k8s.node.uid" } + } + } + + // Mark - Pod + + public var pod: PodAttributes { + get { + .init(attributes: self.attributes) + } + set { + self.attributes = newValue.attributes + } + } + + public struct PodAttributes: SpanAttributeNamespace { + public var attributes: SpanAttributes + private let resource: String + + public init(attributes: SpanAttributes) { + self.attributes = attributes + self.resource = "pod" + } + + /// Semantic conventions for Kubernetes labels. + public var labels: MetadataAttributes { + get { + .init(attributes: self.attributes, resource: self.resource, group: "label") + } + set { + self.attributes = newValue.attributes + } + } + + /// Semantic conventions for Kubernetes labels. + public var annotations: MetadataAttributes { + get { + .init(attributes: self.attributes, resource: self.resource, group: "annotation") + } + set { + self.attributes = newValue.attributes + } + } + + public struct NestedSpanAttributes: NestedSpanAttributesProtocol { + public init() {} + + /// Pod Attributes + /// + /// "pod" name; e.g. "swift-2425ff6a-e3149". + public var name: Key { "k8s.pod.name" } + /// "pod" uid; e.g. "efb22509-5650-41e8-bf78-5dac6e54fcbf". + public var uid: Key { "k8s.pod.uid" } + } + } + + // Mark - ReplicaSet + + public var replicaset: ReplicaSetAttributes { + get { + .init(attributes: self.attributes) + } + set { + self.attributes = newValue.attributes + } + } + + public struct ReplicaSetAttributes: SpanAttributeNamespace { + public var attributes: SpanAttributes + private let resource: String + + public init(attributes: SpanAttributes) { + self.attributes = attributes + self.resource = "replicaset" + } + + /// Semantic conventions for Kubernetes labels. + public var labels: MetadataAttributes { + get { + .init(attributes: self.attributes, resource: self.resource, group: "label") + } + set { + self.attributes = newValue.attributes + } + } + + /// Semantic conventions for Kubernetes labels. + public var annotations: MetadataAttributes { + get { + .init(attributes: self.attributes, resource: self.resource, group: "annotation") + } + set { + self.attributes = newValue.attributes + } + } + + public struct NestedSpanAttributes: NestedSpanAttributesProtocol { + public init() {} + + /// ReplicaSet Attributes + /// + /// "replicaset" name; e.g. "swift-2425ff6a". + public var name: Key { "k8s.replicaset.name" } + /// "replicaset" uid; e.g. "6eb14149-78db-49ac-a019-edb6fd06de4c". + public var uid: Key { "k8s.replicaset.uid" } + } + } + + // Mark - StatefulSet + public var statefulset: StatefulSetAttributes { + get { + .init(attributes: self.attributes) + } + set { + self.attributes = newValue.attributes + } + } + + public struct StatefulSetAttributes: SpanAttributeNamespace { + public var attributes: SpanAttributes + private let resource: String + + public init(attributes: SpanAttributes) { + self.attributes = attributes + self.resource = "statefulset" + } + + /// Semantic conventions for Kubernetes labels. + public var labels: MetadataAttributes { + get { + .init(attributes: self.attributes, resource: self.resource, group: "label") + } + set { + self.attributes = newValue.attributes + } + } + + /// Semantic conventions for Kubernetes labels. + public var annotations: MetadataAttributes { + get { + .init(attributes: self.attributes, resource: self.resource, group: "annotation") + } + set { + self.attributes = newValue.attributes + } + } + + public struct NestedSpanAttributes: NestedSpanAttributesProtocol { + public init() {} + + /// StatefulSet Attributes + /// + /// "statefulset" name; e.g. "swift". + public var name: Key { "k8s.statefulset.name" } + /// "statefulset" uid; e.g. "030f007b-179d-4f68-80f4-5e5a1b2ded07". + public var uid: Key { "k8s.statefulset.uid" } + } + } +} + +// Mark - Kubernetes Resource Metadata Labels/Annotations +extension KubernetesAttributes { + /// Semantic conventions for Kubernetes resource metadata. + /// + /// Note: OpenTelemetry Spec documents only pod resource, but any resource + /// may be labeled. In lieu of extensibility, this has been setup to work + /// with any specified resource. + /// + /// OpenTelemetry Spec: [Kubernetes attributes](https://opentelemetry.io/docs/specs/semconv/resource/k8s) + public struct MetadataAttributes { + var attributes: SpanAttributes + private let group: String + private let resource: String + + init(attributes: SpanAttributes, resource: String, group: String) { + self.attributes = attributes + self.group = group + self.resource = resource + } + + /// Set the given value for the given Kubernetes pod's metadata. + /// + /// e.g. for the k8s resource's label/annotation + /// - if the label is: "com.apple.swift/foo.bar=baz" + /// then "k8s..label.": "k8s.pod.label.com.apple.swift/foo.bar" + /// - if the annotation is: "com.apple.swift/foo.bar=baz" + /// then "k8s..annotation.": "k8s.pod.annotation.com.apple.swift/foo.bar" + /// - Parameters: + /// - value: The value for the given metadata label/annotation. + /// - metadata: The key name of the Kubernetes resource's label/annotation. + public mutating func setValue(_ value: String, forKey key: String) { + self.attributes["k8s.\(self.resource).\(self.group).\(key)"] = value + } + } +} diff --git a/Tests/TracingOpenTelemetrySemanticConventionsTests/KubernetesSemanticsTests.swift b/Tests/TracingOpenTelemetrySemanticConventionsTests/KubernetesSemanticsTests.swift new file mode 100644 index 0000000..6a6ee47 --- /dev/null +++ b/Tests/TracingOpenTelemetrySemanticConventionsTests/KubernetesSemanticsTests.swift @@ -0,0 +1,119 @@ +import Tracing +@testable import TracingOpenTelemetrySemanticConventions +import XCTest + +final class KubernetesSemanticsTests: XCTestCase { + private var attributes = SpanAttributes() + + override func setUp() { + self.attributes = [:] + } + + func test_Kubernetes() { + self.attributes.k8s.cluster.name = "swift-distributed-tracing-cluster" + self.attributes.k8s.cluster.uid = "218fc5a9-a5f1-4b54-aa05-46717d0ab26d" + self.attributes.k8s.node.name = "node-1" + self.attributes.k8s.node.uid = "1eb3a0c6-0477-4080-a9cb-0cb7db65c6a2" + self.attributes.k8s.namespace.name = "default" + self.attributes.k8s.pod.name = "swift-2425ff6a-e3149" + self.attributes.k8s.pod.uid = "efb22509-5650-41e8-bf78-5dac6e54fcbf" + self.attributes.k8s.container.name = "webserver" + self.attributes.k8s.container.restartCount = 3 + self.attributes.k8s.container.lastTerminatedReason = "Evicted" + self.attributes.k8s.replicaset.name = "swift-2425ff6a" + self.attributes.k8s.replicaset.uid = "6eb14149-78db-49ac-a019-edb6fd06de4c" + self.attributes.k8s.deployment.name = "swift" + self.attributes.k8s.deployment.uid = "b9e5e87b-6d18-4525-bb8e-5efd00cad377" + self.attributes.k8s.statefulset.name = "swift" + self.attributes.k8s.statefulset.uid = "030f007b-179d-4f68-80f4-5e5a1b2ded07" + self.attributes.k8s.daemonset.name = "swift" + self.attributes.k8s.daemonset.uid = "34330774-22fb-411d-a986-374e813ac952" + self.attributes.k8s.job.name = "swift" + self.attributes.k8s.job.uid = "250c0a82-2ea8-4ed1-99c8-b238b1b86784" + self.attributes.k8s.cronjob.name = "swift" + self.attributes.k8s.cronjob.uid = "70360e9a-f5ac-43c3-a996-3b949de67288" + + XCTAssertSpanAttributesEqual(self.attributes, [ + "k8s.cluster.name": "swift-distributed-tracing-cluster", + "k8s.cluster.uid": "218fc5a9-a5f1-4b54-aa05-46717d0ab26d", + "k8s.node.name": "node-1", + "k8s.node.uid": "1eb3a0c6-0477-4080-a9cb-0cb7db65c6a2", + "k8s.namespace.name": "default", + "k8s.pod.name": "swift-2425ff6a-e3149", + "k8s.pod.uid": "efb22509-5650-41e8-bf78-5dac6e54fcbf", + "k8s.container.name": "webserver", + "k8s.container.restart_count": 3, + "k8s.container.last_terminated_reason": "Evicted", + "k8s.replicaset.name": "swift-2425ff6a", + "k8s.replicaset.uid": "6eb14149-78db-49ac-a019-edb6fd06de4c", + "k8s.deployment.name": "swift", + "k8s.deployment.uid": "b9e5e87b-6d18-4525-bb8e-5efd00cad377", + "k8s.statefulset.name": "swift", + "k8s.statefulset.uid": "030f007b-179d-4f68-80f4-5e5a1b2ded07", + "k8s.daemonset.name": "swift", + "k8s.daemonset.uid": "34330774-22fb-411d-a986-374e813ac952", + "k8s.job.name": "swift", + "k8s.job.uid": "250c0a82-2ea8-4ed1-99c8-b238b1b86784", + "k8s.cronjob.name": "swift", + "k8s.cronjob.uid": "70360e9a-f5ac-43c3-a996-3b949de67288", + ]) + } + + func test_KubernetesLabel() { + self.attributes.k8s.cluster.labels.setValue("baz-cluster", forKey: "com.apple.swift/foo.bar") + self.attributes.k8s.container.labels.setValue("baz-container", forKey: "com.apple.swift/foo.bar") + self.attributes.k8s.cronjob.labels.setValue("baz-cronjob", forKey: "com.apple.swift/foo.bar") + self.attributes.k8s.daemonset.labels.setValue("baz-daemonset", forKey: "com.apple.swift/foo.bar") + self.attributes.k8s.deployment.labels.setValue("baz-deployment", forKey: "com.apple.swift/foo.bar") + self.attributes.k8s.job.labels.setValue("baz-job", forKey: "com.apple.swift/foo.bar") + self.attributes.k8s.namespace.labels.setValue("baz-namespace", forKey: "com.apple.swift/foo.bar") + self.attributes.k8s.node.labels.setValue("baz-node", forKey: "com.apple.swift/foo.bar") + self.attributes.k8s.pod.labels.setValue("baz-pod", forKey: "com.apple.swift/foo.bar") + self.attributes.k8s.replicaset.labels.setValue("baz-rs", forKey: "com.apple.swift/foo.bar") + self.attributes.k8s.statefulset.labels.setValue("baz-statefulset", forKey: "com.apple.swift/foo.bar") + + + XCTAssertSpanAttributesEqual(self.attributes, [ + "k8s.cluster.label.com.apple.swift/foo.bar": "baz-cluster", + "k8s.container.label.com.apple.swift/foo.bar": "baz-container", + "k8s.cronjob.label.com.apple.swift/foo.bar": "baz-cronjob", + "k8s.daemonset.label.com.apple.swift/foo.bar": "baz-daemonset", + "k8s.deployment.label.com.apple.swift/foo.bar": "baz-deployment", + "k8s.job.label.com.apple.swift/foo.bar": "baz-job", + "k8s.namespace.label.com.apple.swift/foo.bar": "baz-namespace", + "k8s.node.label.com.apple.swift/foo.bar": "baz-node", + "k8s.pod.label.com.apple.swift/foo.bar": "baz-pod", + "k8s.replicaset.label.com.apple.swift/foo.bar": "baz-rs", + "k8s.statefulset.label.com.apple.swift/foo.bar": "baz-statefulset", + ]) + } + + func test_KubernetesAnnotation() { + self.attributes.k8s.cluster.annotations.setValue("baz-cluster", forKey: "com.apple.swift/foo.bar") + self.attributes.k8s.container.annotations.setValue("baz-container", forKey: "com.apple.swift/foo.bar") + self.attributes.k8s.cronjob.annotations.setValue("baz-cronjob", forKey: "com.apple.swift/foo.bar") + self.attributes.k8s.daemonset.annotations.setValue("baz-daemonset", forKey: "com.apple.swift/foo.bar") + self.attributes.k8s.deployment.annotations.setValue("baz-deployment", forKey: "com.apple.swift/foo.bar") + self.attributes.k8s.job.annotations.setValue("baz-job", forKey: "com.apple.swift/foo.bar") + self.attributes.k8s.namespace.annotations.setValue("baz-namespace", forKey: "com.apple.swift/foo.bar") + self.attributes.k8s.node.annotations.setValue("baz-node", forKey: "com.apple.swift/foo.bar") + self.attributes.k8s.pod.annotations.setValue("baz-pod", forKey: "com.apple.swift/foo.bar") + self.attributes.k8s.replicaset.annotations.setValue("baz-rs", forKey: "com.apple.swift/foo.bar") + self.attributes.k8s.statefulset.annotations.setValue("baz-statefulset", forKey: "com.apple.swift/foo.bar") + + + XCTAssertSpanAttributesEqual(self.attributes, [ + "k8s.cluster.annotation.com.apple.swift/foo.bar": "baz-cluster", + "k8s.container.annotation.com.apple.swift/foo.bar": "baz-container", + "k8s.cronjob.annotation.com.apple.swift/foo.bar": "baz-cronjob", + "k8s.daemonset.annotation.com.apple.swift/foo.bar": "baz-daemonset", + "k8s.deployment.annotation.com.apple.swift/foo.bar": "baz-deployment", + "k8s.job.annotation.com.apple.swift/foo.bar": "baz-job", + "k8s.namespace.annotation.com.apple.swift/foo.bar": "baz-namespace", + "k8s.node.annotation.com.apple.swift/foo.bar": "baz-node", + "k8s.pod.annotation.com.apple.swift/foo.bar": "baz-pod", + "k8s.replicaset.annotation.com.apple.swift/foo.bar": "baz-rs", + "k8s.statefulset.annotation.com.apple.swift/foo.bar": "baz-statefulset", + ]) + } +} From 74d1fd2612527842e4b29012cbe75f450374030a Mon Sep 17 00:00:00 2001 From: James Muldoon Date: Wed, 12 Feb 2025 14:51:47 +0900 Subject: [PATCH 2/3] Add missing license headers Missed in initial push --- .../SpanAttributes+KubernetesSemantics.swift | 14 ++++++++++++++ .../KubernetesSemanticsTests.swift | 14 ++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/Sources/TracingOpenTelemetrySemanticConventions/SpanAttributes+KubernetesSemantics.swift b/Sources/TracingOpenTelemetrySemanticConventions/SpanAttributes+KubernetesSemantics.swift index 457c450..ac22b18 100644 --- a/Sources/TracingOpenTelemetrySemanticConventions/SpanAttributes+KubernetesSemantics.swift +++ b/Sources/TracingOpenTelemetrySemanticConventions/SpanAttributes+KubernetesSemantics.swift @@ -1,3 +1,17 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the Swift Distributed Tracing open source project +// +// Copyright (c) 2023 Apple Inc. and the Swift Distributed Tracing project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of Swift Distributed Tracing project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + import Tracing extension SpanAttributes { diff --git a/Tests/TracingOpenTelemetrySemanticConventionsTests/KubernetesSemanticsTests.swift b/Tests/TracingOpenTelemetrySemanticConventionsTests/KubernetesSemanticsTests.swift index 6a6ee47..5137072 100644 --- a/Tests/TracingOpenTelemetrySemanticConventionsTests/KubernetesSemanticsTests.swift +++ b/Tests/TracingOpenTelemetrySemanticConventionsTests/KubernetesSemanticsTests.swift @@ -1,3 +1,17 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the Swift Distributed Tracing open source project +// +// Copyright (c) 2023 Apple Inc. and the Swift Distributed Tracing project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of Swift Distributed Tracing project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + import Tracing @testable import TracingOpenTelemetrySemanticConventions import XCTest From 28b3f740d2082a5e563d9ff8be8cbbd2a1adf284 Mon Sep 17 00:00:00 2001 From: James Muldoon Date: Wed, 12 Feb 2025 14:54:33 +0900 Subject: [PATCH 3/3] Corrected docstring parameter metadata should have been key --- .../SpanAttributes+KubernetesSemantics.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/TracingOpenTelemetrySemanticConventions/SpanAttributes+KubernetesSemantics.swift b/Sources/TracingOpenTelemetrySemanticConventions/SpanAttributes+KubernetesSemantics.swift index ac22b18..6bc6393 100644 --- a/Sources/TracingOpenTelemetrySemanticConventions/SpanAttributes+KubernetesSemantics.swift +++ b/Sources/TracingOpenTelemetrySemanticConventions/SpanAttributes+KubernetesSemantics.swift @@ -649,7 +649,7 @@ extension KubernetesAttributes { /// then "k8s..annotation.": "k8s.pod.annotation.com.apple.swift/foo.bar" /// - Parameters: /// - value: The value for the given metadata label/annotation. - /// - metadata: The key name of the Kubernetes resource's label/annotation. + /// - key: The key name of the Kubernetes resource's label/annotation. public mutating func setValue(_ value: String, forKey key: String) { self.attributes["k8s.\(self.resource).\(self.group).\(key)"] = value }