From 1144d6a90fbad06e9da0fa545e5e6f5a9186282e Mon Sep 17 00:00:00 2001 From: Wojciech Nagrodzki <278594+wnagrodzki@users.noreply.github.com> Date: Sun, 26 Aug 2018 13:30:53 +0200 Subject: [PATCH] Uncoupled DiskLogger from FileRotate --- Logger/Loggers/DiskLogger/DiskLogger.swift | 40 ++++++++++++++++++++-- Logger/Loggers/DiskLogger/Filerotate.swift | 12 ++----- 2 files changed, 41 insertions(+), 11 deletions(-) diff --git a/Logger/Loggers/DiskLogger/DiskLogger.swift b/Logger/Loggers/DiskLogger/DiskLogger.swift index 89e46b8..4088a62 100644 --- a/Logger/Loggers/DiskLogger/DiskLogger.swift +++ b/Logger/Loggers/DiskLogger/DiskLogger.swift @@ -24,6 +24,30 @@ import Foundation +/// Allows log files rotation. +protocol Logrotate { + + /// Rotates log files `rotations` number of times. + /// + /// First deletes file at `.`. + /// Next moves files located at: + /// + /// `, .1, .2 ... .` + /// + /// to `.1, .2 ... .` + func rotate() throws +} + +protocol LogrotateFactory { + + /// Returns newly initialized Logrotate instance. + /// + /// - Parameters: + /// - fileURL: URL of the log file. + /// - rotations: Number of times log files are rotated before being removed. + func makeInstance(fileURL: URL, rotations: Int) -> Logrotate +} + /// Logger that writes messages into the file at specified URL with log rotation support. public final class DiskLogger: Logger { @@ -31,6 +55,7 @@ public final class DiskLogger: Logger { private let fileSizeLimit: UInt64 private let rotations: Int private let fileSystem: FileSystem + private let logrotateFactory: LogrotateFactory private let formatter: DateFormatter private let queue = DispatchQueue(label: "com.wnagrodzki.DiskLogger", qos: .background, attributes: [], autoreleaseFrequency: .workItem, target: nil) private var buffer = Data() @@ -42,11 +67,16 @@ public final class DiskLogger: Logger { /// - fileURL: URL of the log file. /// - fileSizeLimit: Maximum size log file can reach in bytes. Attempt to exceeding that limit triggers log files rotation. /// - rotations: Number of times log files are rotated before being removed. - public init(fileURL: URL, fileSizeLimit: UInt64, rotations: Int, fileSystem: FileSystem) { + public convenience init(fileURL: URL, fileSizeLimit: UInt64, rotations: Int) { + self.init(fileURL: fileURL, fileSizeLimit: fileSizeLimit, rotations: rotations, fileSystem: FileManager.default, logrotateFactory: FileRotateFactory()) + } + + init(fileURL: URL, fileSizeLimit: UInt64, rotations: Int, fileSystem: FileSystem, logrotateFactory: LogrotateFactory) { self.fileURL = fileURL self.fileSizeLimit = fileSizeLimit self.rotations = rotations self.fileSystem = fileSystem + self.logrotateFactory = logrotateFactory formatter = DateFormatter() formatter.dateFormat = "yyyy-MM-dd HH:mm:ss.SSS" formatter.timeZone = TimeZone(secondsFromGMT: 0) @@ -99,7 +129,13 @@ public final class DiskLogger: Logger { } private func rotateLogFiles() throws { - let logrotate = FileRotate(fileURL: fileURL, rotations: rotations, fileSystem: fileSystem) + let logrotate = logrotateFactory.makeInstance(fileURL: fileURL, rotations: rotations) try logrotate.rotate() } } + +private class FileRotateFactory: LogrotateFactory { + func makeInstance(fileURL: URL, rotations: Int) -> Logrotate { + return FileRotate(fileURL: fileURL, rotations: rotations, fileSystem: FileManager.default) + } +} diff --git a/Logger/Loggers/DiskLogger/Filerotate.swift b/Logger/Loggers/DiskLogger/Filerotate.swift index bda34b9..0963cfa 100644 --- a/Logger/Loggers/DiskLogger/Filerotate.swift +++ b/Logger/Loggers/DiskLogger/Filerotate.swift @@ -24,7 +24,6 @@ import Foundation -/// Allows log files rotation. final class FileRotate { private let fileURL: URL @@ -42,15 +41,10 @@ final class FileRotate { self.rotations = rotations self.fileSystem = fileSystem } +} + +extension FileRotate: Logrotate { - /// Rotates log files `rotations` number of times. - /// - /// First deletes file at `.`. - /// Next moves files located at: - /// - /// `, .1, .2 ... .` - /// - /// to `.1, .2 ... .` func rotate() throws { let range = 1...rotations let pathExtensions = range.map { "\($0)" }