From 035b9537940778d23f3bce50525d464f3643626e Mon Sep 17 00:00:00 2001 From: Christoph Hagen Date: Thu, 11 Nov 2021 09:43:08 +0100 Subject: [PATCH] Add logging and configuration file --- Resources/paths.conf | 3 +++ Sources/App/Errors.swift | 6 ++++++ Sources/App/Log.swift | 43 +++++++++++++++++++++++++++++++++++++ Sources/App/configure.swift | 41 ++++++++++++++++++++--------------- 4 files changed, 76 insertions(+), 17 deletions(-) create mode 100755 Resources/paths.conf create mode 100644 Sources/App/Errors.swift create mode 100644 Sources/App/Log.swift diff --git a/Resources/paths.conf b/Resources/paths.conf new file mode 100755 index 0000000..fc59537 --- /dev/null +++ b/Resources/paths.conf @@ -0,0 +1,3 @@ +/data/logs/festival/server.log +/data/public/festival/lists + diff --git a/Sources/App/Errors.swift b/Sources/App/Errors.swift new file mode 100644 index 0000000..1ba2196 --- /dev/null +++ b/Sources/App/Errors.swift @@ -0,0 +1,6 @@ +import Foundation + +enum FestivalError: Error { + + case invalidConfiguration +} diff --git a/Sources/App/Log.swift b/Sources/App/Log.swift new file mode 100644 index 0000000..36d252a --- /dev/null +++ b/Sources/App/Log.swift @@ -0,0 +1,43 @@ +import Foundation + +private let df: DateFormatter = { + let df = DateFormatter() + df.dateStyle = .short + df.timeStyle = .short + df.locale = Locale(identifier: "de") + return df +}() + +func log(_ message: String, file: String = #file, line: Int = #line) { + let date = df.string(from: Date()) + let m = "[\(date)][\(file.components(separatedBy: "/").last ?? file):\(line)] \(message)" + print(m) + Log.write(m + "\n") +} + +enum Log { + + static func set(logFile: String) throws { + let url = URL(fileURLWithPath: logFile) + let date = df.string(from: Date()) + if !FileManager.default.fileExists(atPath: logFile) { + try "[\(date)] New log created.\n".write(to: url, atomically: false, encoding: .utf8) + } + guard let f = FileHandle(forWritingAtPath: logFile) else { + try "[\(date)] Failed to start log.\n".write(to: url, atomically: false, encoding: .utf8) + return + } + f.seekToEndOfFile() + f.write("[\(date)] Logging started.\n".data(using: .utf8)!) + file = f + } + + static func write(_ message: String) { + guard let f = file else { + return + } + f.write(message.data(using: .utf8)!) + } + + private static var file: FileHandle? +} diff --git a/Sources/App/configure.swift b/Sources/App/configure.swift index 3d426d5..0a970e7 100755 --- a/Sources/App/configure.swift +++ b/Sources/App/configure.swift @@ -38,14 +38,14 @@ private func saveLists() { private func saveList(_ set: Set, named name: String, to url: URL) { guard let list = set.sorted().joined(separator: "\n").data(using: .utf8) else { - print("Failed to save \(name) list, no data") + log("Failed to save \(name) list, no data") return } do { try list.write(to: url) - print("Saved \(name) list with \(set.count) entries") + log("Saved \(name) list with \(set.count) entries") } catch { - print("Failed to write \(name) list: \(error)") + log("Failed to write \(name) list: \(error)") } } @@ -54,7 +54,7 @@ private func loadList(from url: URL) throws -> Set { .split(separator: "\n") .map { $0.trimmingCharacters(in: .whitespacesAndNewlines) } .filter { !$0.isEmpty } - print("Loaded list \(url.path) (\(users.count) entries)") + log("Loaded list \(url.path) (\(users.count) entries)") return .init(users) } @@ -93,25 +93,32 @@ public func configure(_ app: Application) throws { // uncomment to serve files from /Public folder // app.middleware.use(FileMiddleware(publicDirectory: app.directory.publicDirectory)) app.http.server.configuration.port = 9001 - - // let eventLog = app.directory.publicDirectory + "events.txt" - // let guestList = app.directory.publicDirectory + "registered.txt" - // let declinedList = app.directory.publicDirectory + "declined.txt" - let eventLog = "/blog/site/lists/events.txt" - let guestList = "/blog/site/lists/registered.txt" - let declinedList = "/blog/site/lists/declined.txt" - let eventLogPath = URL(fileURLWithPath: eventLog) - guestListPath = URL(fileURLWithPath: guestList) - declinedListPath = URL(fileURLWithPath: declinedList) + let configFile = URL(fileURLWithPath: app.directory.resourcesDirectory) + .appendingPathComponent("paths.conf") + let configData = try String(contentsOf: configFile) + .components(separatedBy: "\n") + .map { $0.trimmingCharacters(in: .whitespaces) } + .filter { !$0.isEmpty } + guard configData.count == 2 else { + throw FestivalError.invalidConfiguration + } + let logFile = URL(fileURLWithPath: configData[0]) + let listDirectory = URL(fileURLWithPath: configData[1]) + + try Log.set(logFile: logFile.path) + + let eventLog = listDirectory.appendingPathComponent("events.txt") + guestListPath = listDirectory.appendingPathComponent("registered.txt") + declinedListPath = listDirectory.appendingPathComponent("declined.txt") // Create the files - try createFileIfNeeded(at: eventLogPath) + try createFileIfNeeded(at: eventLog) try createFileIfNeeded(at: guestListPath) try createFileIfNeeded(at: declinedListPath) // Create handle to write events - eventLogHandle = FileHandle(forWritingAtPath: eventLog) + eventLogHandle = try FileHandle(forWritingTo: eventLog) if #available(macOS 10.15.4, *) { try eventLogHandle?.seekToEnd() } else { @@ -127,6 +134,6 @@ public func configure(_ app: Application) throws { let date = Date() let dateString = df.string(from: date) - print("[\(dateString)] Server started: \(registeredGuests.count) registered, \(declinedGuests.count) declined, event log open: \(eventLogHandle != nil)") + log("[\(dateString)] Server started: \(registeredGuests.count) registered, \(declinedGuests.count) declined, event log open: \(eventLogHandle != nil)") }