Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions Package.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// swift-tools-version:5.5
// swift-tools-version:6.0
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription
Expand All @@ -25,5 +25,6 @@ let package = Package(
name: "LoggerTests",
dependencies: ["Logger"]
),
]
],
swiftLanguageModes: [.v6]
)
4 changes: 2 additions & 2 deletions Sources/Logger/LogEntry/Level.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@ import Foundation
import OSLog

/// Enum representing different possible levels for log messages. Basically mapped object from the native OSLogEntryLog.Level
public enum Level: CaseIterable {
public enum Level: CaseIterable, Sendable {
case debug // trace
case info
case `default`
case warning // error
case critical // fault
case custom(CustomStringConvertible)
case custom(String)

public static var allCases: [Level] {
[
Expand Down
6 changes: 3 additions & 3 deletions Sources/Logger/LogEntry/LogEntry.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@

import Foundation

public struct LogEntry {
public struct LogEntry: Sendable {
public let header: LogHeader
public let location: LogLocation
public let message: CustomStringConvertible
public let message: String

public init(header: LogHeader, location: LogLocation, message: CustomStringConvertible) {
self.header = header
self.location = location
self.message = message
self.message = message.description
}
}
9 changes: 4 additions & 5 deletions Sources/Logger/LogEntry/LogEntryCoding/LogEntryDecoder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public struct LogEntryDecoder: LogEntryDecoding {
private let logEntryConfig: LogEntryConfig

public init(
logEntryConfig: LogEntryConfig = .init()
logEntryConfig: LogEntryConfig = LogEntryConfig()
) {
self.logEntryConfig = logEntryConfig
}
Expand Down Expand Up @@ -57,12 +57,11 @@ public struct LogEntryDecoder: LogEntryDecoding {
}

return LogEntry(
header: .init(
header: LogHeader(
date: date,
level: Level(rawValue: levelRawValue),
dateFormatter: logEntryConfig.dateFormatter
level: Level(rawValue: levelRawValue)
),
location: .init(
location: LogLocation(
fileName: fileName,
function: functionName,
line: line
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public struct LogEntryEncoder: LogEntryEncoding {
private let logEntryConfig: LogEntryConfig

public init(
logEntryConfig: LogEntryConfig = .init()
logEntryConfig: LogEntryConfig = LogEntryConfig()
) {
self.logEntryConfig = logEntryConfig
}
Expand Down
6 changes: 2 additions & 4 deletions Sources/Logger/LogEntry/LogHeader.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,13 @@

import Foundation

public struct LogHeader {
public struct LogHeader: Sendable {
public let date: Date
public let level: Level
public let dateFormatter: DateFormatter

public init(date: Date, level: Level, dateFormatter: DateFormatter) {
public init(date: Date, level: Level) {
self.date = date
self.level = level
self.dateFormatter = dateFormatter
}
}

Expand Down
2 changes: 1 addition & 1 deletion Sources/Logger/LogEntry/LogLocation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

import Foundation

public struct LogLocation {
public struct LogLocation: Sendable {
public let fileName: String
public let function: String
public let line: Int
Expand Down
19 changes: 8 additions & 11 deletions Sources/Logger/LoggerManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
// Created by Martin Troup on 24.09.2021.
//

import Combine
import Foundation

public typealias ApplicationCallbackBundle = (callbacks: [ApplicationCallbackType], level: Level)
Expand All @@ -23,7 +22,7 @@ public class LoggerManager {
private let metaInformationBundle: MetaInformationBundle?
private var dateOfLastLog: Date?

private var subscriptions = Set<AnyCancellable>()
private var applicationCallbackLogger: ApplicationCallbackLogger?

/// `LoggerManager` initialization
/// - Parameters:
Expand All @@ -42,14 +41,12 @@ public class LoggerManager {
if let applicationCallbackLoggerBundle = applicationCallbackLoggerBundle {
let applicationCallbackLogger = ApplicationCallbackLogger(
callbacks: applicationCallbackLoggerBundle.callbacks,
level: applicationCallbackLoggerBundle.level
)

applicationCallbackLogger.messagePublisher
.sink { [weak self] level, message in
level: applicationCallbackLoggerBundle.level,
logMessage: { [weak self] level, message in
self?.log(message, onLevel: level)
}
.store(in: &subscriptions)
)
self.applicationCallbackLogger = applicationCallbackLogger
}
}

Expand All @@ -67,7 +64,7 @@ public class LoggerManager {
onLine line: Int = #line
) {
let currentDate = Date()
let logHeader = LogHeader(date: currentDate, level: level, dateFormatter: DateFormatter.monthsDaysTimeFormatter)
let logHeader = LogHeader(date: currentDate, level: level)
let logLocation = LogLocation(fileName: (file as NSString).lastPathComponent, function: function, line: line)
let log = LogEntry(header: logHeader, location: logLocation, message: message)
let availableLoggers = loggers.availableLoggers(forLevel: log.header.level)
Expand All @@ -83,9 +80,9 @@ public class LoggerManager {
let asynchronousLoggers = availableLoggers.filter(\.isAsynchronous)
guard !asynchronousLoggers.isEmpty else { return }

serialQueue.async {
serialQueue.async(execute: DispatchWorkItem {
asynchronousLoggers.forEach { $0.log(log) }
}
})
}

public func logMetaInformation() {
Expand Down
22 changes: 10 additions & 12 deletions Sources/Logger/Loggers/ApplicationCallbackLogger.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
// Created by Martin Troup on 24.09.2021.
//

import Combine
import Foundation
#if canImport(WatchKit)
import WatchKit
Expand Down Expand Up @@ -135,23 +134,22 @@ public enum ApplicationCallbackType: String, CaseIterable {
}
#endif

protocol ApplicationCallbackLoggerDelegate: AnyObject {
func logApplicationCallback(_ message: String, onLevel level: Level)
}

public class ApplicationCallbackLogger {
private let messageSubject = PassthroughSubject<(level: Level, message: String), Never>()
var messagePublisher: AnyPublisher<(level: Level, message: String), Never> { messageSubject.eraseToAnyPublisher() }

private let level: Level
private let logMessage: (Level, String) -> Void

init(callbacks: [ApplicationCallbackType] = ApplicationCallbackType.allCases, level: Level = .debug) {
init(
callbacks: [ApplicationCallbackType] = ApplicationCallbackType.allCases,
level: Level = .debug,
logMessage: @escaping (Level, String) -> Void
) {
self.level = level
self.logMessage = logMessage

callbacks.forEach { callback in
#if canImport(UIKit) || canImport(WatchKit)
let selector = Selector(callback.rawValue)
#elseif os(OSX)
#elseif os(macOS)
let selector = #selector(logNotification(_:))
#endif
NotificationCenter.default.addObserver(self, selector: selector, name: callback.notificationName, object: nil)
Expand All @@ -163,7 +161,7 @@ public class ApplicationCallbackLogger {

extension ApplicationCallbackLogger {
private func log(_ message: String, onLevel level: Level) {
messageSubject.send((level: level, message: message))
logMessage(level, message)
}

#if canImport(UIKit) || canImport(WatchKit)
Expand Down Expand Up @@ -247,7 +245,7 @@ extension ApplicationCallbackLogger {
log("\(#function)", onLevel: level)
}

#elseif os(OSX)
#elseif os(macOS)
@objc
fileprivate func logNotification(_ notification: NSNotification) {

Expand Down
2 changes: 1 addition & 1 deletion Sources/Logger/Loggers/FileLogger/FileAccessExecutor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@ struct FileAccessExecutor {

extension FileAccessExecutor {
static func live(queue: DispatchQueue) -> Self {
.init(execute: { queue.async(execute: $0) })
FileAccessExecutor(execute: { queue.async(execute: DispatchWorkItem(block: $0)) })
}
}
24 changes: 9 additions & 15 deletions Sources/Logger/Loggers/FileLogger/FileLogger.swift
Original file line number Diff line number Diff line change
Expand Up @@ -251,27 +251,21 @@ public class FileLogger: Logging {
/// - Parameters:
/// - log: `LogEntry` instance with header, location and log message
public func log(_ logEntry: LogEntry) {
let unwrapped: (FileHandle?) throws -> FileHandle = { fileHandle in
guard let fileHandle = fileHandle else { throw FileLoggerError.missingWritableFileHandle }

return fileHandle
}

let utf8Data: (String) throws -> Data = { string in
guard let data = string.data(using: .utf8) else { throw FileLoggerError.stringToDataConversionFailure }

return data
}

fileAccessExecutor {
do {
try self.refreshCurrentLogFileStatus()

let contentToAppend = self.logEntryEncoder.encode(logEntry, verbose: true) + self.lineSeparator
let fileHandle = try unwrapped(self.currentWritableFileHandle)

guard let fileHandle = self.currentWritableFileHandle else {
throw FileLoggerError.missingWritableFileHandle
}

guard let data = contentToAppend.data(using: .utf8) else {
throw FileLoggerError.stringToDataConversionFailure
}

fileHandle.seekToEndOfFile()
fileHandle.write(try utf8Data(contentToAppend))
fileHandle.write(data)
} catch let error {
self.externalLogger("Failed to write to a log file with error: \(error)!")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,14 @@ extension OSLogStore {
}

func getEntries(bundleIdentifier: String, position: OSLogPosition) async throws -> [OSEntryLog] {
try await withCheckedThrowingContinuation { continuation in
do {
let logs = try self
.getEntries(at: position)
.compactMap { $0 as? OSLogEntryLog }
.map(OSEntryLog.init)
.filter { $0.subsystem == bundleIdentifier }
continuation.resume(with: .success(logs))
} catch {
continuation.resume(throwing: NativeLoggerError.gettingEntriesFailed(error))
}
do {
return try self
.getEntries(at: position)
.compactMap { $0 as? OSLogEntryLog }
.map(OSEntryLog.init)
.filter { $0.subsystem == bundleIdentifier }
} catch {
throw NativeLoggerError.gettingEntriesFailed(error)
}
}
}
18 changes: 18 additions & 0 deletions Tests/LoggerTests/Counter.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import Foundation

final class Counter {
private let lock = NSLock()
private var count = 0

func increment() {
lock.lock()
defer { lock.unlock() }
count += 1
}

func value() -> Int {
lock.lock()
defer { lock.unlock() }
return count
}
}
6 changes: 3 additions & 3 deletions Tests/LoggerTests/LogEntry+mock.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ import Foundation

extension LogEntry {
static func mock(_ message: String) -> LogEntry {
.init(
header: .init(date: Date(), level: .info, dateFormatter: DateFormatter.monthsDaysTimeFormatter),
location: .init(fileName: "file", function: "function", line: 1),
LogEntry(
header: LogHeader(date: Date(), level: .info),
location: LogLocation(fileName: "file", function: "function", line: 1),
message: message
)
}
Expand Down
Loading
Loading