Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add OTelLogHandler that sends OTelLogEntry to an OTelLogEntryProcessor
- Loading branch information
Showing
4 changed files
with
155 additions
and
0 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
//===----------------------------------------------------------------------===// | ||
// | ||
// This source file is part of the Swift OTel open source project | ||
// | ||
// Copyright (c) 2024 Moritz Lang and the Swift OTel project authors | ||
// Licensed under Apache License v2.0 | ||
// | ||
// See LICENSE.txt for license information | ||
// | ||
// SPDX-License-Identifier: Apache-2.0 | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
import Logging | ||
|
||
@_spi(Logging) | ||
public struct OTelLogEntry: Equatable, Sendable { | ||
public let body: String | ||
public let level: Logger.Level | ||
public let metadata: Logger.Metadata? | ||
public let timeNanosecondsSinceEpoch: UInt64 | ||
} |
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,62 @@ | ||
//===----------------------------------------------------------------------===// | ||
// | ||
// This source file is part of the Swift OTel open source project | ||
// | ||
// Copyright (c) 2024 Moritz Lang and the Swift OTel project authors | ||
// Licensed under Apache License v2.0 | ||
// | ||
// See LICENSE.txt for license information | ||
// | ||
// SPDX-License-Identifier: Apache-2.0 | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
import AsyncAlgorithms | ||
import Logging | ||
import NIOConcurrencyHelpers | ||
import ServiceLifecycle | ||
import Logging | ||
import Tracing | ||
|
||
@_spi(Logging) | ||
public struct OTelLogHandler: Sendable, LogHandler { | ||
public var metadata: Logging.Logger.Metadata | ||
public var logLevel: Logging.Logger.Level | ||
private let processor: any OTelLogEntryProcessor | ||
|
||
public init( | ||
processor: any OTelLogEntryProcessor, | ||
logLevel: Logger.Level, | ||
metadata: Logger.Metadata = [:] | ||
) { | ||
self.processor = processor | ||
self.logLevel = logLevel | ||
self.metadata = metadata | ||
} | ||
|
||
public subscript(metadataKey key: String) -> Logging.Logger.Metadata.Value? { | ||
get { metadata[key] } | ||
set { metadata[key] = newValue } | ||
} | ||
|
||
public func log( | ||
level: Logger.Level, | ||
message: Logger.Message, | ||
metadata: Logger.Metadata?, | ||
source: String, | ||
file: String, | ||
function: String, | ||
line: UInt | ||
) { | ||
let instant = DefaultTracerClock().now | ||
|
||
let message = OTelLogEntry( | ||
body: message.description, | ||
level: level, | ||
metadata: metadata, | ||
timeNanosecondsSinceEpoch: instant.nanosecondsSinceEpoch | ||
) | ||
|
||
processor.onLog(message) | ||
} | ||
} |
31 changes: 31 additions & 0 deletions
31
Sources/OTel/Logging/Processing/OTelLogEntryProcessor.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,31 @@ | ||
//===----------------------------------------------------------------------===// | ||
// | ||
// This source file is part of the Swift OTel open source project | ||
// | ||
// Copyright (c) 2024 Moritz Lang and the Swift OTel project authors | ||
// Licensed under Apache License v2.0 | ||
// | ||
// See LICENSE.txt for license information | ||
// | ||
// SPDX-License-Identifier: Apache-2.0 | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
import ServiceLifecycle | ||
import ServiceContextModule | ||
|
||
/// Log processors allow for processing logs throughout their lifetime via ``onStart(_:parentContext:)`` and ``onEnd(_:)`` calls. | ||
/// Usually, log processors will forward logs to a configurable ``OTelLogEntryExporter``. | ||
/// | ||
/// [OpenTelemetry specification: LogRecord processor](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.20.0/specification/logs/sdk.md#logrecordprocessor) | ||
/// | ||
/// ### Implementation Notes | ||
/// | ||
/// On shutdown, processors forwarding logs to an ``OTelLogEntryExporter`` MUST shutdown that exporter. | ||
@_spi(Logging) | ||
public protocol OTelLogEntryProcessor: Service & Sendable { | ||
func onLog(_ log: OTelLogEntry) | ||
|
||
/// Force log processors that batch logs to flush immediately. | ||
func forceFlush() async throws | ||
} |
40 changes: 40 additions & 0 deletions
40
Sources/OTel/Logging/Processing/OTelNoOpLogEntryProcessor.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,40 @@ | ||
//===----------------------------------------------------------------------===// | ||
// | ||
// This source file is part of the Swift OTel open source project | ||
// | ||
// Copyright (c) 2024 Moritz Lang and the Swift OTel project authors | ||
// Licensed under Apache License v2.0 | ||
// | ||
// See LICENSE.txt for license information | ||
// | ||
// SPDX-License-Identifier: Apache-2.0 | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
import ServiceContextModule | ||
|
||
/// A log entry processor that ignores all operations, used when no logs should be processed. | ||
@_spi(Logging) | ||
public struct OTelNoOpLogEntryProcessor: OTelLogEntryProcessor, CustomStringConvertible { | ||
public let description = "OTelNoOpLogEntryProcessor" | ||
|
||
private let stream: AsyncStream<Void> | ||
private let continuation: AsyncStream<Void>.Continuation | ||
|
||
/// Initialize a no-op log entry processor. | ||
public init() { | ||
(stream, continuation) = AsyncStream.makeStream() | ||
} | ||
|
||
public func run() async { | ||
for await _ in stream.cancelOnGracefulShutdown() {} | ||
} | ||
|
||
public func onLog(_ log: OTelLogEntry) { | ||
// no-op | ||
} | ||
|
||
public func forceFlush() async throws { | ||
// no-op | ||
} | ||
} |