Skip to content

Commit 61b76da

Browse files
authored
Merge pull request #8 from SwiftRex/FixFileLogging
Fix file logging
2 parents 509b9ce + b3993a1 commit 61b76da

File tree

1 file changed

+59
-23
lines changed

1 file changed

+59
-23
lines changed

Sources/LoggerMiddleware/LoggerMiddleware.swift

Lines changed: 59 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -103,26 +103,21 @@ extension LoggerMiddleware {
103103
// MARK: State Logger
104104
extension LoggerMiddleware {
105105
public enum StateLogger {
106+
/// Logs using os_log.
106107
case osLog
107-
case file(URL)
108+
/// Appends the messages to a file. The file must exist!
109+
case file(FileAppender)
110+
/// A custom handler.
108111
case custom((String) -> Void)
109112

110113
func log(state: String) {
111114
switch self {
112-
case .osLog: LoggerMiddleware.osLog(state: state)
113-
case let .file(url): LoggerMiddleware.fileLog(state: state, to: url)
115+
case .osLog: LoggerMiddleware.osLog(state)
116+
case let .file(fileAppender): fileAppender.write(state)
114117
case let .custom(closure): closure(state)
115118
}
116119
}
117120
}
118-
119-
private static func osLog(state: String) {
120-
os_log(.debug, log: .default, "%{PUBLIC}@", state)
121-
}
122-
123-
private static func fileLog(state: String, to fileURL: URL) {
124-
try? state.write(toFile: fileURL.absoluteString, atomically: false, encoding: String.Encoding.utf8)
125-
}
126121
}
127122

128123
// MARK: State Diff Transform
@@ -243,32 +238,27 @@ extension LoggerMiddleware {
243238
// MARK: Action Logger
244239
extension LoggerMiddleware {
245240
public enum ActionLogger {
241+
/// Logs using os_log.
246242
case osLog
247-
case file(URL)
243+
/// Appends the messages to a file. The file must exist!
244+
case file(FileAppender)
245+
/// A custom handler.
248246
case custom((String) -> Void)
249247

250248
func log(action: String) {
251249
switch self {
252-
case .osLog: LoggerMiddleware.osLog(action: action)
253-
case let .file(url): LoggerMiddleware.fileLog(action: action, to: url)
250+
case .osLog: LoggerMiddleware.osLog(action)
251+
case let .file(fileappender): fileappender.write(action)
254252
case let .custom(closure): closure(action)
255253
}
256254
}
257255
}
258-
259-
private static func osLog(action: String) {
260-
os_log(.debug, log: .default, "%{PUBLIC}@", action)
261-
}
262-
263-
private static func fileLog(action: String, to fileURL: URL) -> Void {
264-
try? action.write(toFile: fileURL.absoluteString, atomically: false, encoding: .utf8)
265-
}
266256
}
267257

268258
// MARK: Action Transform
269259
extension LoggerMiddleware {
270260
public enum ActionTransform {
271-
case `default`(actionPrefix: String = "\n🕹 ", sourcePrefix: String = "\n🎪 ")
261+
case `default`(actionPrefix: String = "🕹 ", sourcePrefix: String = " 🎪 ")
272262
case actionNameOnly
273263
case custom((InputActionType, ActionSource) -> String)
274264

@@ -284,3 +274,49 @@ extension LoggerMiddleware {
284274
}
285275
}
286276
}
277+
278+
// MARK: Log output
279+
280+
extension LoggerMiddleware {
281+
282+
fileprivate static func osLog(_ message: String) {
283+
os_log(.debug, log: .default, "%{PUBLIC}@", message)
284+
}
285+
286+
}
287+
288+
public struct FileAppender {
289+
private let url: URL
290+
private let date: () -> Date
291+
private let dateFormatter: DateFormatter
292+
private let writer: (URL, Data) -> Void
293+
294+
public init(url: URL, date: @escaping () -> Date, dateFormatter: DateFormatter, writer: @escaping (URL, Data) -> Void) {
295+
self.url = url
296+
self.date = date
297+
self.dateFormatter = dateFormatter
298+
self.writer = writer
299+
}
300+
301+
public func write(_ message: String) {
302+
guard let data = (dateFormatter.string(from: date()) + " " + message + "\n").data(using: String.Encoding.utf8) else { return }
303+
writer(url, data)
304+
}
305+
}
306+
307+
extension FileAppender {
308+
public static func live(url: URL, dateFormatter: DateFormatter = .init(), date: @escaping () -> Date = Date.init, fileHandle: @escaping (URL) throws -> FileHandle = FileHandle.init(forUpdating:)) -> FileAppender {
309+
FileAppender(
310+
url: url,
311+
date: date,
312+
dateFormatter: dateFormatter,
313+
writer: { url, data in
314+
guard let fileUpdater = try? fileHandle(url) else { return }
315+
fileUpdater.seekToEndOfFile()
316+
fileUpdater.write(data)
317+
fileUpdater.closeFile()
318+
}
319+
)
320+
}
321+
}
322+

0 commit comments

Comments
 (0)