Update to new logging version

This commit is contained in:
Christoph Hagen 2023-02-16 18:31:30 +01:00
parent 77a214d2a2
commit e9a650ddec
5 changed files with 63 additions and 52 deletions

View File

@ -15,7 +15,7 @@ let package = Package(
// https://github.com/Joannis/SMTPKitten <- No updates since 0ct 2020
// 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/christophhagen/clairvoyant.git", from: "0.4.0"),
.package(url: "https://github.com/christophhagen/clairvoyant.git", branch: "main"),
],
targets: [
.target(

View File

@ -51,17 +51,15 @@ final class SQLiteDatabase {
private let registeredPlayerCountMetric: Metric<Int>
init(database: Database, mail: Configuration.EMail?) {
self.registeredPlayerCountMetric = Metric(
init(database: Database, mail: Configuration.EMail?) async throws {
self.registeredPlayerCountMetric = try await Metric(
"schafkopf.players",
name: "Number of users",
description: "The total number of user accounts")
self.tables = TableManagement(database: database)
self.tables = try await TableManagement(database: database)
self.mail = mail?.mailConfig
Task {
await updateRegisteredPlayerCount(from: database)
}
await updateRegisteredPlayerCount(from: database)
}
func registerPlayer(named name: PlayerName, hash: PasswordHash, email: String?, in database: Database) async throws -> SessionToken {
@ -92,7 +90,7 @@ final class SQLiteDatabase {
func updateRegisteredPlayerCount(from database: Database) async {
do {
let count = try await User.query(on: database).count()
registeredPlayerCountMetric.update(count)
try? await registeredPlayerCountMetric.update(count)
} catch {
log("Failed to update player count metric: \(error)")
}

View File

@ -27,26 +27,25 @@ final class TableManagement {
Load the tables from a file in the storage folder
- Throws: Errors when the file could not be read
*/
init(database: Database) {
self.tableCountMetric = .init(
init(database: Database) async throws {
self.tableCountMetric = try await .init(
"schafkopf.tables",
name: "Open tables",
description: "The number of currently available tables")
self.playingPlayerCountMetric = .init(
self.playingPlayerCountMetric = try await .init(
"schafkopf.playing",
name: "Sitting players",
description: "The number of players currently sitting at a table")
self.connectedPlayerCountMetric = .init(
self.connectedPlayerCountMetric = try await .init(
"schafkopf.connected",
name: "Connected players",
description: "The number of players with a websocket connection to the server")
Task {
do {
try await loadTables(from: database)
} catch {
log("Failed to load tables: \(error)")
}
do {
try await loadTables(from: database)
} catch {
log("Failed to load tables: \(error)")
}
}
@ -60,23 +59,23 @@ final class TableManagement {
self.tables[id] = WaitingTable(id: id, name: table.name, isPublic: table.isPublic, players: table.players)
}
log("\(tables.count) tables loaded")
logTableCount()
logPlayingPlayerCount()
logConnectedPlayerCount()
await logTableCount()
await logPlayingPlayerCount()
await logConnectedPlayerCount()
}
private func logTableCount() {
tableCountMetric.update(tables.count)
private func logTableCount() async {
try? await tableCountMetric.update(tables.count)
}
private func logPlayingPlayerCount() {
private func logPlayingPlayerCount() async {
let count = tables.values.sum { $0.playerCount }
playingPlayerCountMetric.update(count)
try? await playingPlayerCountMetric.update(count)
}
private func logConnectedPlayerCount() {
private func logConnectedPlayerCount() async {
let count = tables.values.sum { $0.numberOfConnectedPlayers }
connectedPlayerCountMetric.update(count)
try? await connectedPlayerCountMetric.update(count)
}
/**
@ -93,8 +92,8 @@ final class TableManagement {
try await player.update(on: database)
let waitingTable = WaitingTable(newTable: table, user: player)
self.tables[waitingTable.id] = waitingTable
logTableCount()
logPlayingPlayerCount()
await logTableCount()
await logPlayingPlayerCount()
return waitingTable.tableInfo(forPlayer: player.name)
}
@ -127,7 +126,7 @@ final class TableManagement {
player.$table.id = table.id
try await player.update(on: database)
table.sendUpdateToAllPlayers()
logPlayingPlayerCount()
await logPlayingPlayerCount()
return table.tableInfo(forPlayer: player.name)
}
@ -159,7 +158,7 @@ final class TableManagement {
player.$table.id = nil
guard let table = WaitingTable(oldTable: oldTable, removing: player.name) else {
tables[oldTable.id] = nil
logTableCount()
await logTableCount()
try await player.update(on: database)
try await Table.query(on: database).filter(\.$id == oldTable.id).delete()
return
@ -168,8 +167,8 @@ final class TableManagement {
tables[table.id] = table
#warning("Update points for all players, add penalty if running game")
table.sendUpdateToAllPlayers()
logPlayingPlayerCount()
logConnectedPlayerCount()
await logPlayingPlayerCount()
await logConnectedPlayerCount()
try await player.update(on: database)
}
@ -177,16 +176,21 @@ final class TableManagement {
guard let table = currentTable(for: player) else {
return false
}
defer { logConnectedPlayerCount() }
return table.connect(player: player, using: socket)
let result = table.connect(player: player, using: socket)
Task {
await logConnectedPlayerCount()
}
return result
}
func disconnect(player: PlayerName) {
guard let table = currentTable(for: player) else {
return
}
defer { logConnectedPlayerCount() }
table.disconnect(player: player)
Task {
await logConnectedPlayerCount()
}
}
func performAction(player: PlayerName, action: PlayerAction) -> PlayerActionResult {
@ -255,6 +259,8 @@ final class TableManagement {
func disconnectAllSockets() {
tables.values.forEach { $0.disconnectAllPlayers() }
logConnectedPlayerCount()
Task {
await logConnectedPlayerCount()
}
}
}

View File

@ -5,24 +5,24 @@ import Clairvoyant
var server: SQLiteDatabase!
// configures your application
public func configure(_ app: Application) throws {
public func configure(_ app: Application) async throws {
let storageFolder = URL(fileURLWithPath: app.directory.resourcesDirectory)
let logFolder = storageFolder.appendingPathComponent("logs")
let accessManager = AccessTokenManager([])
let monitor = MetricObserver(
let monitor = await MetricObserver(
logFolder: logFolder,
accessManager: accessManager,
logMetricId: "schafkopf.log")
MetricObserver.standard = monitor
let status = Metric<ServerStatus>(
let status = try! await Metric<ServerStatus>(
"schafkopf.status",
name: "Status",
description: "The main status of the server")
status.update(.initializing)
monitor.registerRoutes(app)
try? await status.update(.initializing)
await monitor.registerRoutes(app)
let configPath = URL(fileURLWithPath: app.directory.resourcesDirectory)
.appendingPathComponent("config.json")
@ -31,8 +31,8 @@ public func configure(_ app: Application) throws {
do {
configuration = try Configuration(loadFromUrl: configPath)
} catch {
status.update(.initializationFailure)
monitor.log("Failed to read configuration: \(error)")
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
@ -60,8 +60,8 @@ public func configure(_ app: Application) throws {
do {
try app.autoMigrate().wait()
} catch {
monitor.log("Failed to migrate database: \(error)")
status.update(.initializationFailure)
await monitor.log("Failed to migrate database: \(error)")
try? await status.update(.initializationFailure)
return
}
@ -69,7 +69,7 @@ public func configure(_ app: Application) throws {
app.middleware.use(FileMiddleware(publicDirectory: app.directory.publicDirectory))
let db = app.databases.database(.sqlite, logger: .init(label: "Init"), on: app.databases.eventLoopGroup.next())!
server = SQLiteDatabase(database: db, mail: configuration.mail)
server = try await SQLiteDatabase(database: db, mail: configuration.mail)
// Gracefully shut down by closing potentially open socket
DispatchQueue.global(qos: .utility).asyncAfter(deadline: .now() + .seconds(5)) {
@ -81,10 +81,15 @@ public func configure(_ app: Application) throws {
// register routes
routes(app)
status.update(.nominal)
try? await status.update(.nominal)
}
func log(_ message: String) {
MetricObserver.standard?.log(message)
print(message)
guard let observer = MetricObserver.standard else {
print(message)
return
}
Task {
await observer.log(message)
}
}

View File

@ -5,5 +5,7 @@ var env = try Environment.detect()
try LoggingSystem.bootstrap(from: &env)
let app = Application(env)
defer { app.shutdown() }
try configure(app)
try app.run()
Task {
try await configure(app)
try app.run()
}