Add monitoring

This commit is contained in:
Christoph Hagen 2023-01-31 22:16:44 +01:00
parent 2d683e34c4
commit 5381b28386
4 changed files with 33 additions and 5 deletions

View File

@ -11,10 +11,11 @@ let package = Package(
.package(url: "https://github.com/vapor/fluent.git", from: "4.0.0"), .package(url: "https://github.com/vapor/fluent.git", from: "4.0.0"),
.package(url: "https://github.com/vapor/fluent-sqlite.git", from: "4.0.0"), .package(url: "https://github.com/vapor/fluent-sqlite.git", from: "4.0.0"),
// Alternatives: // Alternatives:
// https://github.com/onevcat/Hedwig // https://github.com/onevcat/Hedwig <- No updates since Jun 2017
// https://github.com/Joannis/SMTPKitten // https://github.com/Joannis/SMTPKitten <- No updates since 0ct 2020
// https://github.com/Joannis/VaporSMTPKit <- Uses SMTPKitten // https://github.com/Joannis/VaporSMTPKit <- No updates since 0ct. 2020, uses SMTPKitten
.package(url: "https://github.com/Kitura/Swift-SMTP", from: "6.0.0"), .package(url: "https://github.com/Kitura/Swift-SMTP", from: "6.0.0"),
.package(url: "https://github.com/christophhagen/clairvoyant.git", from: "0.3.0"),
], ],
targets: [ targets: [
.target( .target(
@ -24,6 +25,7 @@ let package = Package(
.product(name: "FluentSQLiteDriver", package: "fluent-sqlite"), .product(name: "FluentSQLiteDriver", package: "fluent-sqlite"),
.product(name: "Vapor", package: "vapor"), .product(name: "Vapor", package: "vapor"),
.product(name: "SwiftSMTP", package: "Swift-SMTP"), .product(name: "SwiftSMTP", package: "Swift-SMTP"),
.product(name: "Clairvoyant", package: "Clairvoyant"),
], ],
swiftSettings: [ swiftSettings: [
// Enable better optimizations when building in Release configuration. Despite the use of // Enable better optimizations when building in Release configuration. Despite the use of

View File

@ -7,5 +7,6 @@
"email": "schafkopf@example.com", "email": "schafkopf@example.com",
"password": "some-secret-string", "password": "some-secret-string",
"tokenExpiryDuration": 15, "tokenExpiryDuration": 15,
} },
"monitoringTokens": [],
} }

View File

@ -30,6 +30,9 @@ struct Configuration {
/// The number of minutes until a password reset token is no longer valid /// The number of minutes until a password reset token is no longer valid
let tokenExpiryDuration: Int let tokenExpiryDuration: Int
} }
/// The authentication tokens to access the metrics
let monitoringTokens: Set<String>
} }
extension Configuration { extension Configuration {

View File

@ -1,5 +1,6 @@
import Vapor import Vapor
import Fluent import Fluent
import Clairvoyant
var server: SQLiteDatabase! var server: SQLiteDatabase!
@ -7,9 +8,22 @@ var server: SQLiteDatabase!
public func configure(_ app: Application) throws { public func configure(_ app: Application) throws {
let storageFolder = URL(fileURLWithPath: app.directory.resourcesDirectory) let storageFolder = URL(fileURLWithPath: app.directory.resourcesDirectory)
let logFolder = storageFolder.appendingPathComponent("logs")
let accessManager = AccessTokenManager([])
let monitor = MetricObserver(
logFolder: logFolder,
accessManager: accessManager,
logMetricId: "schafkopf.log")
MetricObserver.standard = monitor
let status = Metric<ServerStatus>("schafkopf.status")
status.update(.initializing)
monitor.registerRoutes(app)
let configPath = URL(fileURLWithPath: app.directory.resourcesDirectory) let configPath = URL(fileURLWithPath: app.directory.resourcesDirectory)
.appendingPathComponent("config.json") .appendingPathComponent("config.json")
let configuration = try Configuration(loadFromUrl: configPath) let configuration = try Configuration(loadFromUrl: configPath)
configuration.monitoringTokens.map { $0.data(using: .utf8)! }.forEach(accessManager.add)
app.http.server.configuration.port = configuration.serverPort app.http.server.configuration.port = configuration.serverPort
@ -29,7 +43,13 @@ public func configure(_ app: Application) throws {
app.migrations.add(UserTableMigration()) app.migrations.add(UserTableMigration())
app.migrations.add(PasswordResetMigration()) app.migrations.add(PasswordResetMigration())
try app.autoMigrate().wait() do {
try app.autoMigrate().wait()
} catch {
monitor.log("Failed to migrate database: \(error)")
status.update(.initializationFailure)
return
}
// serve files from /Public folder // serve files from /Public folder
app.middleware.use(FileMiddleware(publicDirectory: app.directory.publicDirectory)) app.middleware.use(FileMiddleware(publicDirectory: app.directory.publicDirectory))
@ -46,4 +66,6 @@ public func configure(_ app: Application) throws {
// register routes // register routes
try routes(app) try routes(app)
status.update(.nominal)
} }