diff --git a/Sources/Tracing/SpanProtocol.swift b/Sources/Tracing/SpanProtocol.swift index 7ec5d1e..30eef12 100644 --- a/Sources/Tracing/SpanProtocol.swift +++ b/Sources/Tracing/SpanProtocol.swift @@ -537,6 +537,16 @@ extension SpanAttributes { } } + /// Similar to `subscript(_:)` however returns the stored `SpanAttribute` rather than going through `SpanAttributeConvertible`. + public func get(_ name: String) -> SpanAttribute? { + self._attributes[name] + } + + /// Similar to `subscript(_:)` however accepts a `SpanAttribute` rather than going through `SpanAttributeConvertible`. + public mutating func set(_ name: String, value: SpanAttribute?) { + self._attributes[name] = value + } + /// - Parameter callback: The function to call for each attribute. public func forEach(_ callback: (String, SpanAttribute) -> Void) { self._attributes.forEach { diff --git a/Tests/TracingTests/SpanTests.swift b/Tests/TracingTests/SpanTests.swift index 85d6009..1ddd03b 100644 --- a/Tests/TracingTests/SpanTests.swift +++ b/Tests/TracingTests/SpanTests.swift @@ -181,15 +181,48 @@ final class SpanTests: XCTestCase { XCTAssertEqual(child.links.count, 1) XCTAssertEqual(child.links[0].baggage[TestBaggageContextKey.self], "test") - #if swift(>=5.2) XCTAssertEqual(child.links[0].attributes.sampleHttp.statusCode, 418) - #endif guard case .some(.int64(let statusCode)) = child.links[0].attributes["http.status_code"]?.toSpanAttribute() else { XCTFail("Expected int value for http.status_code") return } XCTAssertEqual(statusCode, 418) } + + func testSpanAttributeSetterGetter() { + var parentBaggage = Baggage.topLevel + parentBaggage[TestBaggageContextKey.self] = "test" + + let parent = TestSpan( + operationName: "client", + startTime: .now(), + baggage: parentBaggage, + kind: .client, + onEnd: { _ in } + ) + let childBaggage = Baggage.topLevel + let child = TestSpan( + operationName: "server", + startTime: .now(), + baggage: childBaggage, + kind: .server, + onEnd: { _ in } + ) + + var attributes = SpanAttributes() + attributes.set("http.status_code", value: .int32(418)) + child.addLink(parent, attributes: attributes) + + XCTAssertEqual(child.links.count, 1) + XCTAssertEqual(child.links[0].baggage[TestBaggageContextKey.self], "test") + XCTAssertEqual(child.links[0].attributes.sampleHttp.statusCode, 418) + guard case .some(.int32(let statusCode)) = child.links[0].attributes["http.status_code"]?.toSpanAttribute() else { + XCTFail("Expected int value for http.status_code") + return + } + XCTAssertEqual(statusCode, 418) + XCTAssertEqual(attributes.get("http.status_code"), SpanAttribute.int32(418)) + } } // ==== ----------------------------------------------------------------------------------------------------------------