Last active
September 16, 2025 13:14
-
-
Save elland/b45430c8daa5e8a85b1b4643f2f51ecc to your computer and use it in GitHub Desktop.
This file contains hidden or 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
| import Foundation | |
| import Logging | |
| final public class NushuLogger { | |
| private static let shared = NushuLogger() | |
| private let loggingURL = FileManager.default | |
| .urls(for: .documentDirectory, in: .userDomainMask).first! | |
| .appendingPathComponent("default.log") | |
| private let logger: Logger | |
| private init() { | |
| self.logger = try! FileLogging.logger(label: "com.NushuiOS", localFile: self.loggingURL) | |
| } | |
| // MARK: - Interface | |
| static func debug(_ msg: Logger.Message) { | |
| self.shared.logger.debug(msg) | |
| } | |
| static func error(_ msg: Logger.Message) { | |
| self.shared.logger.error(msg) | |
| } | |
| } | |
| public struct FileLogging { | |
| let stream: TextOutputStream | |
| public init(to localFile: URL) throws { | |
| self.stream = try FileHandlerOutputStream(localFile: localFile) | |
| } | |
| public static func logger(label: String, localFile url: URL) throws -> Logger { | |
| let logging = try Self(to: url) | |
| return Logger(label: label, factory: { label in | |
| FileLogHandler(label: label, stream: logging.stream) | |
| }) | |
| } | |
| } | |
| public struct FileLogHandler: LogHandler { | |
| public var metadata: Logging.Logger.Metadata = Logger.Metadata() | |
| public var logLevel: Logging.Logger.Level = .info | |
| private let stream: TextOutputStream | |
| private var label: String | |
| public subscript(metadataKey metadataKey: String) -> Logger.Metadata.Value? { | |
| get { | |
| return self.metadata[metadataKey] | |
| } | |
| set { | |
| self.metadata[metadataKey] = newValue | |
| } | |
| } | |
| public func timestamp() -> String { | |
| ISO8601DateFormatter().string(from: Date()) | |
| } | |
| public init(label: String, stream: TextOutputStream) { | |
| self.label = label | |
| self.stream = stream | |
| } | |
| public func log( | |
| level: Logger.Level, | |
| message: Logger.Message, | |
| metadata: Logger.Metadata?, | |
| source: String, | |
| file: String, | |
| function: String, | |
| line: UInt | |
| ) { | |
| let meta = metadata?.map { "\($0)=\($1)" }.joined(separator: " ") ?? "" | |
| var stream = self.stream | |
| stream.write("\(self.timestamp()) \(level) \(self.label) :\(meta) \(message)\n") | |
| } | |
| } | |
| struct FileHandlerOutputStream: TextOutputStream { | |
| enum Error: Swift.Error { | |
| case couldNotCreateFile | |
| } | |
| private let fileHandle: FileHandle | |
| init(localFile url: URL) throws { | |
| if !FileManager.default.fileExists(atPath: url.path) { | |
| guard FileManager.default.createFile(atPath: url.path, contents: nil, attributes: nil) else { | |
| throw Error.couldNotCreateFile | |
| } | |
| } | |
| let fileHandle = try FileHandle(forWritingTo: url) | |
| fileHandle.seekToEndOfFile() | |
| self.fileHandle = fileHandle | |
| } | |
| mutating func write(_ string: String) { | |
| if let data = string.data(using: .utf8) { | |
| self.fileHandle.write(data) | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment