Add logging and configuration file

This commit is contained in:
Christoph Hagen 2021-11-11 09:43:08 +01:00
parent bdb838bf5e
commit 035b953794
4 changed files with 76 additions and 17 deletions

3
Resources/paths.conf Executable file
View File

@ -0,0 +1,3 @@
/data/logs/festival/server.log
/data/public/festival/lists

6
Sources/App/Errors.swift Normal file
View File

@ -0,0 +1,6 @@
import Foundation
enum FestivalError: Error {
case invalidConfiguration
}

43
Sources/App/Log.swift Normal file
View File

@ -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?
}

View File

@ -38,14 +38,14 @@ private func saveLists() {
private func saveList(_ set: Set<String>, named name: String, to url: URL) { private func saveList(_ set: Set<String>, named name: String, to url: URL) {
guard let list = set.sorted().joined(separator: "\n").data(using: .utf8) else { 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 return
} }
do { do {
try list.write(to: url) try list.write(to: url)
print("Saved \(name) list with \(set.count) entries") log("Saved \(name) list with \(set.count) entries")
} catch { } 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<String> {
.split(separator: "\n") .split(separator: "\n")
.map { $0.trimmingCharacters(in: .whitespacesAndNewlines) } .map { $0.trimmingCharacters(in: .whitespacesAndNewlines) }
.filter { !$0.isEmpty } .filter { !$0.isEmpty }
print("Loaded list \(url.path) (\(users.count) entries)") log("Loaded list \(url.path) (\(users.count) entries)")
return .init(users) return .init(users)
} }
@ -93,25 +93,32 @@ public func configure(_ app: Application) throws {
// uncomment to serve files from /Public folder // uncomment to serve files from /Public folder
// app.middleware.use(FileMiddleware(publicDirectory: app.directory.publicDirectory)) // app.middleware.use(FileMiddleware(publicDirectory: app.directory.publicDirectory))
app.http.server.configuration.port = 9001 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) let configFile = URL(fileURLWithPath: app.directory.resourcesDirectory)
guestListPath = URL(fileURLWithPath: guestList) .appendingPathComponent("paths.conf")
declinedListPath = URL(fileURLWithPath: declinedList) 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 // Create the files
try createFileIfNeeded(at: eventLogPath) try createFileIfNeeded(at: eventLog)
try createFileIfNeeded(at: guestListPath) try createFileIfNeeded(at: guestListPath)
try createFileIfNeeded(at: declinedListPath) try createFileIfNeeded(at: declinedListPath)
// Create handle to write events // Create handle to write events
eventLogHandle = FileHandle(forWritingAtPath: eventLog) eventLogHandle = try FileHandle(forWritingTo: eventLog)
if #available(macOS 10.15.4, *) { if #available(macOS 10.15.4, *) {
try eventLogHandle?.seekToEnd() try eventLogHandle?.seekToEnd()
} else { } else {
@ -127,6 +134,6 @@ public func configure(_ app: Application) throws {
let date = Date() let date = Date()
let dateString = df.string(from: 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)")
} }