diff --git a/Sources/App/Management/Configuration.swift b/Sources/App/Management/Configuration.swift index a568acb..abf4330 100644 --- a/Sources/App/Management/Configuration.swift +++ b/Sources/App/Management/Configuration.swift @@ -33,6 +33,22 @@ struct Configuration { /// The authentication tokens to access the metrics let monitoringTokens: Set + + /// The path to the folder where the metric logs are stored + /// + /// If no path is provided, then a folder `logs` in the resources directory is created + /// If the path is relative, then it is assumed relative to the resources directory + let logPath: String? + + func logURL(possiblyRelativeTo resourcesDirectory: URL) -> URL { + guard let logPath else { + return resourcesDirectory.appendingPathComponent("logs") + } + guard !logPath.hasPrefix("/") else { + return .init(fileURLWithPath: logPath) + } + return resourcesDirectory.appendingPathComponent(logPath) + } } extension Configuration { diff --git a/Sources/App/configure.swift b/Sources/App/configure.swift index 80a867a..8cc3462 100644 --- a/Sources/App/configure.swift +++ b/Sources/App/configure.swift @@ -29,8 +29,12 @@ public func configure(_ app: Application) throws { private func configureAsync(_ app: Application) async throws { let storageFolder = URL(fileURLWithPath: app.directory.resourcesDirectory) + + let configPath = URL(fileURLWithPath: app.directory.resourcesDirectory) + .appendingPathComponent("config.json") + let configuration = try Configuration(loadFromUrl: configPath) - let logFolder = storageFolder.appendingPathComponent("logs") + let logFolder = configuration.logURL(possiblyRelativeTo: storageFolder) let monitor = MetricObserver( logFileFolder: logFolder, logMetricId: "schafkopf.log") @@ -43,20 +47,6 @@ private func configureAsync(_ app: Application) async throws { _ = try? await status.update(.initializing) - let configPath = URL(fileURLWithPath: app.directory.resourcesDirectory) - .appendingPathComponent("config.json") - let configuration: Configuration - - do { - configuration = try Configuration(loadFromUrl: configPath) - } catch { - _ = try? await status.update(.initializationFailure) - await monitor.log("Failed to read configuration: \(error)") - // Note: If configuration can't be loaded, then the server will run on the wrong port - // and access to metrics is impossible, since no tokens are loaded - return - } - app.http.server.configuration.port = configuration.serverPort // Set target environment