From 8da55d33c43b65f9306a6f8672b61fd7121aec63 Mon Sep 17 00:00:00 2001 From: Dariusz Rybicki <dariusz@elixxir.io> Date: Wed, 5 Oct 2022 02:34:29 +0200 Subject: [PATCH] Add MessengerLogger --- .../Utils/MessengerLogger.swift | 90 +++++++++++++++++++ .../Utils/MessengerLoggerTests.swift | 71 +++++++++++++++ 2 files changed, 161 insertions(+) create mode 100644 Sources/XXMessengerClient/Utils/MessengerLogger.swift create mode 100644 Tests/XXMessengerClientTests/Utils/MessengerLoggerTests.swift diff --git a/Sources/XXMessengerClient/Utils/MessengerLogger.swift b/Sources/XXMessengerClient/Utils/MessengerLogger.swift new file mode 100644 index 00000000..0dcf0bc5 --- /dev/null +++ b/Sources/XXMessengerClient/Utils/MessengerLogger.swift @@ -0,0 +1,90 @@ +import Foundation +import Logging +import XCTestDynamicOverlay + +public struct MessengerLogger { + public struct Log: Equatable { + public init(level: Logger.Level, message: String) { + self.level = level + self.message = message + } + + public var level: Logger.Level + public var message: String + } + + public var run: (Log, String, String, UInt) -> Void + + public func callAsFunction( + _ item: Log, + file: String = #fileID, + function: String = #function, + line: UInt = #line + ) { + run(item, file, function, line) + } +} + +extension MessengerLogger { + public static func live( + logger: Logger = Logger(label: "xx.network.MessengerClient") + ) -> MessengerLogger { + MessengerLogger { item, file, function, line in + logger.log( + level: item.level, + .init(stringLiteral: item.message), + file: file, + function: function, + line: line + ) + } + } +} + +extension MessengerLogger { + public static let unimplemented = MessengerLogger( + run: XCTUnimplemented("\(Self.self)") + ) +} + +extension MessengerLogger.Log { + static func parse(_ string: String) -> MessengerLogger.Log { + let level: Logger.Level + let message: String + let pattern = #"^([A-Z]+)( \d{4}/\d{2}/\d{2})?( \d{1,2}:\d{2}:\d{2}\.\d+)? (.*)"# + let regex = try! NSRegularExpression( + pattern: pattern, + options: .dotMatchesLineSeparators + ) + let stringRange = NSRange(location: 0, length: string.utf16.count) + if let match = regex.firstMatch(in: string, range: stringRange) { + var groups: [Int: String] = [:] + for rangeIndex in 1..<match.numberOfRanges { + let nsRange = match.range(at: rangeIndex) + if !NSEqualRanges(nsRange, NSMakeRange(NSNotFound, 0)) { + let group = (string as NSString).substring(with: nsRange) + groups[rangeIndex] = group + } + } + level = MessengerLogger.Log.level(form: groups[1]) + message = groups[4] ?? string + } else { + level = .notice + message = string + } + return MessengerLogger.Log(level: level, message: message) + } + + static func level(form string: String?) -> Logger.Level { + switch string { + case "TRACE": return .trace + case "DEBUG": return .debug + case "INFO": return .info + case "WARN": return .warning + case "ERROR": return .error + case "CRITICAL": return .critical + case "FATAL": return .critical + default: return .notice + } + } +} diff --git a/Tests/XXMessengerClientTests/Utils/MessengerLoggerTests.swift b/Tests/XXMessengerClientTests/Utils/MessengerLoggerTests.swift new file mode 100644 index 00000000..755863d9 --- /dev/null +++ b/Tests/XXMessengerClientTests/Utils/MessengerLoggerTests.swift @@ -0,0 +1,71 @@ +import CustomDump +import XCTest +@testable import XXMessengerClient + +final class MessengerLoggerTests: XCTestCase { + func testParsingLog() { + XCTAssertNoDifference( + MessengerLogger.Log.parse("TRACE Tracing..."), + MessengerLogger.Log(level: .trace, message: "Tracing...") + ) + XCTAssertNoDifference( + MessengerLogger.Log.parse("DEBUG Debugging..."), + MessengerLogger.Log(level: .debug, message: "Debugging...") + ) + XCTAssertNoDifference( + MessengerLogger.Log.parse("INFO Informing..."), + MessengerLogger.Log(level: .info, message: "Informing...") + ) + XCTAssertNoDifference( + MessengerLogger.Log.parse("WARN Warning!"), + MessengerLogger.Log(level: .warning, message: "Warning!") + ) + XCTAssertNoDifference( + MessengerLogger.Log.parse("ERROR Failure!"), + MessengerLogger.Log(level: .error, message: "Failure!") + ) + XCTAssertNoDifference( + MessengerLogger.Log.parse("CRITICAL Critical failure!"), + MessengerLogger.Log(level: .critical, message: "Critical failure!") + ) + XCTAssertNoDifference( + MessengerLogger.Log.parse("FATAL Fatal failure!"), + MessengerLogger.Log(level: .critical, message: "Fatal failure!") + ) + } + + func testParsingFallbacks() { + XCTAssertNoDifference( + MessengerLogger.Log.parse("1234 Wrongly formatted"), + MessengerLogger.Log(level: .notice, message: "1234 Wrongly formatted") + ) + } + + func testParsingStripsDateTime() { + XCTAssertNoDifference( + MessengerLogger.Log.parse("INFO 2022/10/04 Informing..."), + MessengerLogger.Log(level: .info, message: "Informing...") + ) + XCTAssertNoDifference( + MessengerLogger.Log.parse("INFO 23:36:55.755390 Informing..."), + MessengerLogger.Log(level: .info, message: "Informing...") + ) + XCTAssertNoDifference( + MessengerLogger.Log.parse("INFO 2022/10/04 23:36:55.755390 Informing..."), + MessengerLogger.Log(level: .info, message: "Informing...") + ) + } + + func testParsingMultilineMessage() { + XCTAssertNoDifference( + MessengerLogger.Log.parse(""" + ERROR 2022/10/04 23:51:15.021658 First line + Second line + """), + MessengerLogger.Log(level: .error, message: """ + First line + Second line + """) + ) + } +} -- GitLab