diff --git a/Sources/LoggingLoki/LokiLogProcessor.swift b/Sources/LoggingLoki/LokiLogProcessor.swift index f11072e..5f92bd8 100644 --- a/Sources/LoggingLoki/LokiLogProcessor.swift +++ b/Sources/LoggingLoki/LokiLogProcessor.swift @@ -193,25 +193,28 @@ public struct LokiLogProcessor: Sendable, Service whe } func addEntryToBatch(_ log: LokiLog, with labels: [String: String]) { - let _log: LokiLog.Transport + let log = makeLog(log) + continuation.yield((log, labels)) + } + + func makeLog(_ log: LokiLog) -> LokiLog.Transport { switch configuration.metadataFormat.code { case .logfmt: var line = "[\(log.level.rawValue.uppercased())] message=\"\(log.message)\"" if let metadata = prettify(log.metadata) { line += " \(metadata)" } - _log = .init(timestamp: .init(), line: line) + return .init(timestamp: .init(), line: line) case .structured: - _log = .init( + return .init( timestamp: .init(), line: "[\(log.level.rawValue.uppercased())] \(log.message)", metadata: log.metadata.mapValues(\.description) ) case .custom(let customFormatter): let line = customFormatter(log.level, log.message, log.metadata) - _log = .init(timestamp: .init(), line: line) + return .init(timestamp: .init(), line: line) } - continuation.yield((_log, labels)) } private func sendBatch(_ batch: Batch) async throws { diff --git a/Tests/LoggingLokiTests/LokiLogProcessorTests.swift b/Tests/LoggingLokiTests/LokiLogProcessorTests.swift new file mode 100644 index 0000000..d927696 --- /dev/null +++ b/Tests/LoggingLokiTests/LokiLogProcessorTests.swift @@ -0,0 +1,43 @@ +import XCTest +@testable import LoggingLoki + +final class LokiLogProcessorTests: XCTestCase { + func testLogFmtFormat() { + let configuration = LokiLogProcessorConfiguration( + lokiURL: "http://localhost:3100", + metadataFormat: .logfmt + ) + let processor = LokiLogProcessor(configuration: configuration) + let raw = LokiLog( + timestamp: .init(), + level: .info, + message: "My log message", + metadata: ["basic_key": "basic_value", "additional_key": "value with whitespace"] + ) + let formatted = processor.makeLog(raw) + XCTAssertNil(formatted.metadata) + XCTAssertTrue(formatted.line.starts(with: "[INFO] ")) + XCTAssertTrue(formatted.line.contains("basic_key=basic_value")) + XCTAssertTrue(formatted.line.contains(#"additional_key="value with whitespace""#)) + XCTAssertTrue(formatted.line.contains(#"message="My log message""#)) + } + + func testCustomFormat() { + let configuration = LokiLogProcessorConfiguration( + lokiURL: "http://localhost:3100", + metadataFormat: .custom({ level, message, metadata in + "\(level.rawValue.uppercased()): \(message) \(metadata)" + }) + ) + let processor = LokiLogProcessor(configuration: configuration) + let raw = LokiLog( + timestamp: .init(), + level: .info, + message: "My log message", + metadata: ["basic_key": "basic_value", "additional_key": "value with whitespace"] + ) + let formatted = processor.makeLog(raw) + XCTAssertNil(formatted.metadata) + XCTAssertEqual(formatted.line, #"INFO: My log message ["basic_key": basic_value, "additional_key": value with whitespace]"#) + } +}