Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Add logging metadata provider * [CI] Compile example using Swift 5.7 * [CI] Run unit tests with Swift 5.7
- Loading branch information
Showing
6 changed files
with
169 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
//===----------------------------------------------------------------------===// | ||
// | ||
// This source file is part of the Swift OpenTelemetry open source project | ||
// | ||
// Copyright (c) 2023 Moritz Lang and the Swift OpenTelemetry project authors | ||
// Licensed under Apache License v2.0 | ||
// | ||
// See LICENSE.txt for license information | ||
// | ||
// SPDX-License-Identifier: Apache-2.0 | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
import InstrumentationBaggage | ||
import Logging | ||
|
||
#if swift(>=5.5) && canImport(_Concurrency) | ||
@available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) | ||
extension Logger.MetadataProvider { | ||
/// A metadata provider exposing the current trace and span ID. | ||
/// | ||
/// - Parameters: | ||
/// - traceIDKey: The metadata key of the trace ID. Defaults to "trace-id". | ||
/// - spanIDKey: The metadata key of the span ID. Defaults to "span-id". | ||
/// - Returns: A metadata provider ready to use with Logging. | ||
public static func otel(traceIDKey: String = "trace-id", spanIDKey: String = "span-id") -> Logger.MetadataProvider { | ||
.init { | ||
guard let spanContext = Baggage.current?.spanContext else { return [:] } | ||
return [ | ||
traceIDKey: "\(spanContext.traceID)", | ||
spanIDKey: "\(spanContext.spanID)", | ||
] | ||
} | ||
} | ||
|
||
/// A metadata provider exposing the current trace and span ID. | ||
public static let otel = Logger.MetadataProvider.otel() | ||
} | ||
#endif |
123 changes: 123 additions & 0 deletions
123
Tests/OpenTelemetryTests/Logging/MetadataProviderTests.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
//===----------------------------------------------------------------------===// | ||
// | ||
// This source file is part of the Swift OpenTelemetry open source project | ||
// | ||
// Copyright (c) 2023 Moritz Lang and the Swift OpenTelemetry project authors | ||
// Licensed under Apache License v2.0 | ||
// | ||
// See LICENSE.txt for license information | ||
// | ||
// SPDX-License-Identifier: Apache-2.0 | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
import InstrumentationBaggage | ||
@testable import Logging | ||
@testable import OpenTelemetry | ||
import XCTest | ||
|
||
final class MetadataProviderTests: XCTestCase { | ||
func test_providesMetadataFromSpanContext_withDefaultLabels() throws { | ||
#if swift(>=5.5) && canImport(_Concurrency) | ||
guard #available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) else { | ||
throw XCTSkip("Task locals are not supported on this platform.") | ||
} | ||
|
||
let stream = InterceptingStream() | ||
var logger = Logger(label: "test") | ||
logger.handler = StreamLogHandler(label: "test", stream: stream, metadataProvider: .otel) | ||
|
||
let spanContext = OTel.SpanContext( | ||
traceID: .random(), | ||
spanID: .random(), | ||
traceFlags: .sampled, | ||
isRemote: true | ||
) | ||
|
||
var baggage = Baggage.topLevel | ||
baggage.spanContext = spanContext | ||
Baggage.$current.withValue(baggage) { | ||
logger.info("This is a test message", metadata: ["explicit": "42"]) | ||
} | ||
|
||
XCTAssertEqual(stream.strings.count, 1) | ||
let message = try XCTUnwrap(stream.strings.first) | ||
|
||
XCTAssertTrue(message.contains("span-id=\(spanContext.spanID)")) | ||
XCTAssertTrue(message.contains("trace-id=\(spanContext.traceID)")) | ||
XCTAssertTrue(message.contains("explicit=42")) | ||
XCTAssertTrue(message.contains("This is a test message")) | ||
#endif | ||
} | ||
|
||
func test_providesMetadataFromSpanContext_withCustomLabels() throws { | ||
#if swift(>=5.5) && canImport(_Concurrency) | ||
guard #available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) else { | ||
throw XCTSkip("Task locals are not supported on this platform.") | ||
} | ||
|
||
let stream = InterceptingStream() | ||
var logger = Logger(label: "test") | ||
let metadataProvider = Logger.MetadataProvider.otel(traceIDKey: "custom_trace_id", spanIDKey: "custom_span_id") | ||
logger.handler = StreamLogHandler(label: "test", stream: stream, metadataProvider: metadataProvider) | ||
|
||
let spanContext = OTel.SpanContext( | ||
traceID: .random(), | ||
spanID: .random(), | ||
traceFlags: .sampled, | ||
isRemote: true | ||
) | ||
|
||
var baggage = Baggage.topLevel | ||
baggage.spanContext = spanContext | ||
Baggage.$current.withValue(baggage) { | ||
logger.info("This is a test message", metadata: ["explicit": "42"]) | ||
} | ||
|
||
XCTAssertEqual(stream.strings.count, 1) | ||
let message = try XCTUnwrap(stream.strings.first) | ||
|
||
XCTAssertTrue(message.contains("custom_span_id=\(spanContext.spanID)")) | ||
XCTAssertTrue(message.contains("custom_trace_id=\(spanContext.traceID)")) | ||
XCTAssertTrue(message.contains("explicit=42")) | ||
XCTAssertTrue(message.contains("This is a test message")) | ||
#endif | ||
} | ||
|
||
func test_doesNotProvideMetadataWithoutSpanContext() throws { | ||
#if swift(>=5.5) && canImport(_Concurrency) | ||
guard #available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) else { | ||
throw XCTSkip("Task locals are not supported on this platform.") | ||
} | ||
|
||
let stream = InterceptingStream() | ||
var logger = Logger(label: "test") | ||
let metadataProvider = Logger.MetadataProvider.otel | ||
logger.handler = StreamLogHandler(label: "test", stream: stream, metadataProvider: metadataProvider) | ||
|
||
logger.info("This is a test message", metadata: ["explicit": "42"]) | ||
|
||
XCTAssertEqual(stream.strings.count, 1) | ||
let message = try XCTUnwrap(stream.strings.first) | ||
|
||
XCTAssertFalse(message.contains("trace-id")) | ||
XCTAssertFalse(message.contains("span-id")) | ||
XCTAssertTrue(message.contains("explicit=42")) | ||
XCTAssertTrue(message.contains("This is a test message")) | ||
#endif | ||
} | ||
} | ||
|
||
final class InterceptingStream: TextOutputStream { | ||
var interceptedText: String? | ||
var strings = [String]() | ||
|
||
func write(_ string: String) { | ||
strings.append(string) | ||
interceptedText = (interceptedText ?? "") + string | ||
} | ||
} | ||
|
||
#if compiler(>=5.6) | ||
extension InterceptingStream: @unchecked Sendable {} | ||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters