diff --git a/Sources/Exporters/OpenTelemetryProtocolCommon/logs/LogRecordAdapter.swift b/Sources/Exporters/OpenTelemetryProtocolCommon/logs/LogRecordAdapter.swift index cdba8324..be361057 100644 --- a/Sources/Exporters/OpenTelemetryProtocolCommon/logs/LogRecordAdapter.swift +++ b/Sources/Exporters/OpenTelemetryProtocolCommon/logs/LogRecordAdapter.swift @@ -45,10 +45,8 @@ public class LogRecordAdapter { protoLogRecord.timeUnixNano = logRecord.timestamp.timeIntervalSince1970.toNanoseconds - if let body = logRecord.body, !body.isEmpty { - var protoBody = Opentelemetry_Proto_Common_V1_AnyValue() - protoBody.stringValue = body - protoLogRecord.body = protoBody + if let body = logRecord.body, !body.description.isEmpty { + protoLogRecord.body = Opentelemetry_Proto_Common_V1_AnyValue() } diff --git a/Sources/OpenTelemetryApi/Context/ActivityContextManager.swift b/Sources/OpenTelemetryApi/Context/ActivityContextManager.swift index 2f5596d5..40478e52 100644 --- a/Sources/OpenTelemetryApi/Context/ActivityContextManager.swift +++ b/Sources/OpenTelemetryApi/Context/ActivityContextManager.swift @@ -68,14 +68,12 @@ class ActivityContextManager: ContextManager { } func removeContextValue(forKey key: OpenTelemetryContextKeys, value: AnyObject) { - let activityIdent = os_activity_get_identifier(OS_ACTIVITY_CURRENT, nil) rlock.lock() - if let currentValue = contextMap[activityIdent]?[key.rawValue], - currentValue === value - { - contextMap[activityIdent]?[key.rawValue] = nil - if contextMap[activityIdent]?.isEmpty ?? false { - contextMap[activityIdent] = nil + + for (activityKey, activity) in contextMap where value === activity[key.rawValue] { + contextMap[activityKey]?[key.rawValue] = nil + if contextMap[activityKey]?.isEmpty ?? false { + contextMap[activityKey] = nil } } if let scope = objectScope.object(forKey: value) { diff --git a/Sources/OpenTelemetryApi/Logs/DefaultLogger.swift b/Sources/OpenTelemetryApi/Logs/DefaultLogger.swift index 72d76dce..ab7a184a 100644 --- a/Sources/OpenTelemetryApi/Logs/DefaultLogger.swift +++ b/Sources/OpenTelemetryApi/Logs/DefaultLogger.swift @@ -53,7 +53,7 @@ public class DefaultLogger: Logger { return self } - func setBody(_ body: String) -> Self { + func setBody(_ body: AttributeValue) -> Self { return self } diff --git a/Sources/OpenTelemetryApi/Logs/LogRecordBuilder.swift b/Sources/OpenTelemetryApi/Logs/LogRecordBuilder.swift index 3c72752a..907471bd 100644 --- a/Sources/OpenTelemetryApi/Logs/LogRecordBuilder.swift +++ b/Sources/OpenTelemetryApi/Logs/LogRecordBuilder.swift @@ -34,7 +34,7 @@ public protocol LogRecordBuilder { /// /// - Parameter body: string value of the log /// - Returns: self - func setBody(_ body: String) -> Self + func setBody(_ body: AttributeValue) -> Self /// set attributes assoicated with the log. /// diff --git a/Sources/OpenTelemetrySdk/Logs/Data/ReadableLogRecord.swift b/Sources/OpenTelemetrySdk/Logs/Data/ReadableLogRecord.swift index a32cffd0..98b5a317 100644 --- a/Sources/OpenTelemetrySdk/Logs/Data/ReadableLogRecord.swift +++ b/Sources/OpenTelemetrySdk/Logs/Data/ReadableLogRecord.swift @@ -7,7 +7,7 @@ import Foundation import OpenTelemetryApi public struct ReadableLogRecord : Codable { - public init(resource: Resource, instrumentationScopeInfo: InstrumentationScopeInfo, timestamp: Date, observedTimestamp: Date? = nil, spanContext: SpanContext? = nil, severity: Severity? = nil, body: String? = nil, attributes: [String : AttributeValue]) { + public init(resource: Resource, instrumentationScopeInfo: InstrumentationScopeInfo, timestamp: Date, observedTimestamp: Date? = nil, spanContext: SpanContext? = nil, severity: Severity? = nil, body: AttributeValue? = nil, attributes: [String : AttributeValue]) { self.resource = resource self.instrumentationScopeInfo = instrumentationScopeInfo self.timestamp = timestamp @@ -24,7 +24,7 @@ public struct ReadableLogRecord : Codable { public private(set) var observedTimestamp : Date? public private(set) var spanContext : SpanContext? public private(set) var severity : Severity? - public private(set) var body: String? + public private(set) var body: AttributeValue? public private(set) var attributes : [String: AttributeValue] } diff --git a/Sources/OpenTelemetrySdk/Logs/LogRecordBuilderSdk.swift b/Sources/OpenTelemetrySdk/Logs/LogRecordBuilderSdk.swift index 7a52e834..ade416f5 100644 --- a/Sources/OpenTelemetrySdk/Logs/LogRecordBuilderSdk.swift +++ b/Sources/OpenTelemetrySdk/Logs/LogRecordBuilderSdk.swift @@ -14,7 +14,7 @@ public class LogRecordBuilderSdk: EventBuilder { private var includeSpanContext: Bool private var timestamp: Date? private var observedTimestamp: Date? - private var body: String? + private var body: AttributeValue? private var severity: Severity? private var attributes: AttributesDictionary private var spanContext: SpanContext? @@ -53,7 +53,7 @@ public class LogRecordBuilderSdk: EventBuilder { return self } - public func setBody(_ body: String) -> Self { + public func setBody(_ body: AttributeValue) -> Self { self.body = body return self } diff --git a/Tests/ExportersTests/OpenTelemetryProtocol/LogRecordAdapterTests.swift b/Tests/ExportersTests/OpenTelemetryProtocol/LogRecordAdapterTests.swift index a909d634..39467c9d 100644 --- a/Tests/ExportersTests/OpenTelemetryProtocol/LogRecordAdapterTests.swift +++ b/Tests/ExportersTests/OpenTelemetryProtocol/LogRecordAdapterTests.swift @@ -43,7 +43,7 @@ class LogRecordAdapterTests : XCTestCase { observedTimestamp: Date.distantPast, spanContext: spanContext, severity: .fatal, - body: "Hello, world", + body: AttributeValue.string("Hello, world"), attributes: ["event.name":AttributeValue.string("name"), "event.domain": AttributeValue.string("domain")]) let protoLog = LogRecordAdapter.toProtoLogRecord(logRecord: logRecord) diff --git a/Tests/ExportersTests/OpenTelemetryProtocol/OtlpHttpLogRecordExporterTests.swift b/Tests/ExportersTests/OpenTelemetryProtocol/OtlpHttpLogRecordExporterTests.swift index e34be308..1c24259f 100644 --- a/Tests/ExportersTests/OpenTelemetryProtocol/OtlpHttpLogRecordExporterTests.swift +++ b/Tests/ExportersTests/OpenTelemetryProtocol/OtlpHttpLogRecordExporterTests.swift @@ -34,7 +34,7 @@ class OtlpHttpLogRecordExporterTests: XCTestCase { } func testExport() { - let testBody = "Hello world " + String(Int.random(in: 1...100)) + let testBody = AttributeValue.string("Hello world " + String(Int.random(in: 1...100))) let logRecord = ReadableLogRecord(resource: Resource(), instrumentationScopeInfo: InstrumentationScopeInfo(name: "scope"), timestamp: Date(), @@ -57,7 +57,7 @@ class OtlpHttpLogRecordExporterTests: XCTestCase { XCTAssertNoThrow(try testServer.receiveBodyAndVerify() { body in var contentsBuffer = ByteBuffer(buffer: body) let contents = contentsBuffer.readString(length: contentsBuffer.readableBytes)! - XCTAssertTrue(contents.contains(testBody)) + XCTAssertTrue(testBody.description.contains(contents)) }) XCTAssertNoThrow(try testServer.receiveEnd()) diff --git a/Tests/ExportersTests/OpenTelemetryProtocol/OtlpLogRecordExporterTests.swift b/Tests/ExportersTests/OpenTelemetryProtocol/OtlpLogRecordExporterTests.swift index 42f751a8..aa079fd5 100644 --- a/Tests/ExportersTests/OpenTelemetryProtocol/OtlpLogRecordExporterTests.swift +++ b/Tests/ExportersTests/OpenTelemetryProtocol/OtlpLogRecordExporterTests.swift @@ -74,7 +74,7 @@ class OtlpLogRecordExporterTests: XCTestCase { observedTimestamp: Date.distantPast, spanContext: spanContext, severity: .fatal, - body: "Hello, world", + body: AttributeValue.string("Hello, world"), attributes: ["event.name":AttributeValue.string("name"), "event.domain": AttributeValue.string("domain")]) let exporter = OtlpLogExporter(channel: channel) @@ -122,7 +122,7 @@ class OtlpLogRecordExporterTests: XCTestCase { observedTimestamp: Date.distantPast, spanContext: spanContext, severity: .fatal, - body: "Hello, world", + body: AttributeValue.string("Hello, world"), attributes: ["event.name":AttributeValue.string("name"), "event.domain": AttributeValue.string("domain")]) let exporter = OtlpLogExporter(channel: channel) exporter.shutdown() @@ -139,7 +139,7 @@ class OtlpLogRecordExporterTests: XCTestCase { observedTimestamp: Date.distantPast, spanContext: spanContext, severity: .fatal, - body: "Hello, world", + body: AttributeValue.string("Hello, world"), attributes: ["event.name":AttributeValue.string("name"), "event.domain": AttributeValue.string("domain")]) let result = exporter.export(logRecords: [logRecord]) diff --git a/Tests/OpenTelemetryApiTests/Context/ActivityContextManagerTests.swift b/Tests/OpenTelemetryApiTests/Context/ActivityContextManagerTests.swift index 28f40ad5..f9ba900f 100644 --- a/Tests/OpenTelemetryApiTests/Context/ActivityContextManagerTests.swift +++ b/Tests/OpenTelemetryApiTests/Context/ActivityContextManagerTests.swift @@ -308,6 +308,45 @@ class ActivityContextManagerTests: XCTestCase { XCTAssert(OpenTelemetry.instance.contextProvider.activeSpan === nil) } + + @available(macOS 10.15, iOS 13.0, tvOS 13.0, *) + func testRemoveContextValuesFromSpan() { + + //Create a span + let span1 = defaultTracer.spanBuilder(spanName: "span1").startSpan() + ActivityContextManager.instance.setCurrentContextValue(forKey: .span, value: span1) + XCTAssert(ActivityContextManager.instance.getCurrentContextValue(forKey: .span) === span1) + + //Add it to one parent in one thread + let parent1 = defaultTracer.spanBuilder(spanName: "parent1").startSpan() + ActivityContextManager.instance.setCurrentContextValue(forKey: .span, value: parent1) + XCTAssert(ActivityContextManager.instance.getCurrentContextValue(forKey: .span) === parent1) + + DispatchQueue.global().async { + let activeSpan = ActivityContextManager.instance.getCurrentContextValue(forKey: .span) + XCTAssert(activeSpan === parent1) + ActivityContextManager.instance.setCurrentContextValue(forKey: .span, value: span1) + parent1.end() + } + + //Add it to another parent in another thread + let parent2 = defaultTracer.spanBuilder(spanName: "parent2").startSpan() + ActivityContextManager.instance.setCurrentContextValue(forKey: .span, value: parent2) + XCTAssert(ActivityContextManager.instance.getCurrentContextValue(forKey: .span) === parent2) + + DispatchQueue.global().async { + let activeSpan = ActivityContextManager.instance.getCurrentContextValue(forKey: .span) + XCTAssert(activeSpan === parent2) + ActivityContextManager.instance.setCurrentContextValue(forKey: .span, value: span1) + parent2.end() + } + + //remove all the contexts from the span and check if the Context is nil + sleep(1) + ActivityContextManager.instance.removeContextValue(forKey: .span, value: span1) + XCTAssert(ActivityContextManager.instance.getCurrentContextValue(forKey: .span) === nil) + } + @available(macOS 10.15, iOS 13.0, tvOS 13.0, *) func testActiveSpanIsKeptPerTaskAsync() async { let expectation1 = self.expectation(description: "firstSpan created") diff --git a/Tests/OpenTelemetryApiTests/Logs/DefaultLoggerTests.swift b/Tests/OpenTelemetryApiTests/Logs/DefaultLoggerTests.swift index 1df6873c..063c59be 100644 --- a/Tests/OpenTelemetryApiTests/Logs/DefaultLoggerTests.swift +++ b/Tests/OpenTelemetryApiTests/Logs/DefaultLoggerTests.swift @@ -28,7 +28,7 @@ class DefaultLoggerTests : XCTestCase { .setTimestamp(Date()) .setObservedTimestamp(Date()) .setSeverity(.debug) - .setBody("hello, world") + .setBody(AttributeValue.string("hello, world")) .emit()) XCTAssertNoThrow(defaultLogger.eventBuilder(name: "Event").emit()) diff --git a/Tests/OpenTelemetrySdkTests/Logs/ReadableLogRecordTests.swift b/Tests/OpenTelemetrySdkTests/Logs/ReadableLogRecordTests.swift index f00a7ecc..01cef1ad 100644 --- a/Tests/OpenTelemetrySdkTests/Logs/ReadableLogRecordTests.swift +++ b/Tests/OpenTelemetrySdkTests/Logs/ReadableLogRecordTests.swift @@ -17,7 +17,7 @@ class ReadableLogRecordTests : XCTestCase { let provider = LoggerProviderBuilder().with(logLimits: LogLimits(maxAttributeCount: 1, maxAttributeLength: 1)).with(processors: [processor]).build() let logger = provider.get(instrumentationScopeName: "temp") logger.logRecordBuilder() - .setBody("hello, world") + .setBody(AttributeValue.string("hello, world")) .setSeverity(.debug) .setObservedTimestamp(observedTimestamp) .setAttributes(["firstAttribute": AttributeValue.string("only the 'o' will be captured"), "secondAttribute": AttributeValue.string("this attribute will be dropped")]) @@ -25,7 +25,7 @@ class ReadableLogRecordTests : XCTestCase { let logRecord = processor.onEmitCalledLogRecord XCTAssertEqual(logRecord?.observedTimestamp, observedTimestamp) - XCTAssertEqual(logRecord?.body, "hello, world") + XCTAssertEqual(logRecord?.body, AttributeValue.string("hello, world")) XCTAssertEqual(logRecord?.attributes.count, 1) let key = logRecord?.attributes.keys.first XCTAssertEqual(logRecord?.attributes[key!]?.description.count, 1)