Update to new logging version
This commit is contained in:
parent
77a214d2a2
commit
e9a650ddec
@ -15,7 +15,7 @@ let package = Package(
|
|||||||
// https://github.com/Joannis/SMTPKitten <- No updates since 0ct 2020
|
// https://github.com/Joannis/SMTPKitten <- No updates since 0ct 2020
|
||||||
// https://github.com/Joannis/VaporSMTPKit <- No updates since 0ct. 2020, 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.4.0"),
|
.package(url: "https://github.com/christophhagen/clairvoyant.git", branch: "main"),
|
||||||
],
|
],
|
||||||
targets: [
|
targets: [
|
||||||
.target(
|
.target(
|
||||||
|
@ -51,17 +51,15 @@ final class SQLiteDatabase {
|
|||||||
|
|
||||||
private let registeredPlayerCountMetric: Metric<Int>
|
private let registeredPlayerCountMetric: Metric<Int>
|
||||||
|
|
||||||
init(database: Database, mail: Configuration.EMail?) {
|
init(database: Database, mail: Configuration.EMail?) async throws {
|
||||||
self.registeredPlayerCountMetric = Metric(
|
self.registeredPlayerCountMetric = try await Metric(
|
||||||
"schafkopf.players",
|
"schafkopf.players",
|
||||||
name: "Number of users",
|
name: "Number of users",
|
||||||
description: "The total number of user accounts")
|
description: "The total number of user accounts")
|
||||||
self.tables = TableManagement(database: database)
|
self.tables = try await TableManagement(database: database)
|
||||||
self.mail = mail?.mailConfig
|
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 {
|
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 {
|
func updateRegisteredPlayerCount(from database: Database) async {
|
||||||
do {
|
do {
|
||||||
let count = try await User.query(on: database).count()
|
let count = try await User.query(on: database).count()
|
||||||
registeredPlayerCountMetric.update(count)
|
try? await registeredPlayerCountMetric.update(count)
|
||||||
} catch {
|
} catch {
|
||||||
log("Failed to update player count metric: \(error)")
|
log("Failed to update player count metric: \(error)")
|
||||||
}
|
}
|
||||||
|
@ -27,26 +27,25 @@ final class TableManagement {
|
|||||||
Load the tables from a file in the storage folder
|
Load the tables from a file in the storage folder
|
||||||
- Throws: Errors when the file could not be read
|
- Throws: Errors when the file could not be read
|
||||||
*/
|
*/
|
||||||
init(database: Database) {
|
init(database: Database) async throws {
|
||||||
self.tableCountMetric = .init(
|
self.tableCountMetric = try await .init(
|
||||||
"schafkopf.tables",
|
"schafkopf.tables",
|
||||||
name: "Open tables",
|
name: "Open tables",
|
||||||
description: "The number of currently available tables")
|
description: "The number of currently available tables")
|
||||||
self.playingPlayerCountMetric = .init(
|
self.playingPlayerCountMetric = try await .init(
|
||||||
"schafkopf.playing",
|
"schafkopf.playing",
|
||||||
name: "Sitting players",
|
name: "Sitting players",
|
||||||
description: "The number of players currently sitting at a table")
|
description: "The number of players currently sitting at a table")
|
||||||
self.connectedPlayerCountMetric = .init(
|
self.connectedPlayerCountMetric = try await .init(
|
||||||
"schafkopf.connected",
|
"schafkopf.connected",
|
||||||
name: "Connected players",
|
name: "Connected players",
|
||||||
description: "The number of players with a websocket connection to the server")
|
description: "The number of players with a websocket connection to the server")
|
||||||
|
|
||||||
Task {
|
|
||||||
do {
|
do {
|
||||||
try await loadTables(from: database)
|
try await loadTables(from: database)
|
||||||
} catch {
|
} catch {
|
||||||
log("Failed to load tables: \(error)")
|
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)
|
self.tables[id] = WaitingTable(id: id, name: table.name, isPublic: table.isPublic, players: table.players)
|
||||||
}
|
}
|
||||||
log("\(tables.count) tables loaded")
|
log("\(tables.count) tables loaded")
|
||||||
logTableCount()
|
await logTableCount()
|
||||||
logPlayingPlayerCount()
|
await logPlayingPlayerCount()
|
||||||
logConnectedPlayerCount()
|
await logConnectedPlayerCount()
|
||||||
}
|
}
|
||||||
|
|
||||||
private func logTableCount() {
|
private func logTableCount() async {
|
||||||
tableCountMetric.update(tables.count)
|
try? await tableCountMetric.update(tables.count)
|
||||||
}
|
}
|
||||||
|
|
||||||
private func logPlayingPlayerCount() {
|
private func logPlayingPlayerCount() async {
|
||||||
let count = tables.values.sum { $0.playerCount }
|
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 }
|
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)
|
try await player.update(on: database)
|
||||||
let waitingTable = WaitingTable(newTable: table, user: player)
|
let waitingTable = WaitingTable(newTable: table, user: player)
|
||||||
self.tables[waitingTable.id] = waitingTable
|
self.tables[waitingTable.id] = waitingTable
|
||||||
logTableCount()
|
await logTableCount()
|
||||||
logPlayingPlayerCount()
|
await logPlayingPlayerCount()
|
||||||
return waitingTable.tableInfo(forPlayer: player.name)
|
return waitingTable.tableInfo(forPlayer: player.name)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -127,7 +126,7 @@ final class TableManagement {
|
|||||||
player.$table.id = table.id
|
player.$table.id = table.id
|
||||||
try await player.update(on: database)
|
try await player.update(on: database)
|
||||||
table.sendUpdateToAllPlayers()
|
table.sendUpdateToAllPlayers()
|
||||||
logPlayingPlayerCount()
|
await logPlayingPlayerCount()
|
||||||
return table.tableInfo(forPlayer: player.name)
|
return table.tableInfo(forPlayer: player.name)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -159,7 +158,7 @@ final class TableManagement {
|
|||||||
player.$table.id = nil
|
player.$table.id = nil
|
||||||
guard let table = WaitingTable(oldTable: oldTable, removing: player.name) else {
|
guard let table = WaitingTable(oldTable: oldTable, removing: player.name) else {
|
||||||
tables[oldTable.id] = nil
|
tables[oldTable.id] = nil
|
||||||
logTableCount()
|
await logTableCount()
|
||||||
try await player.update(on: database)
|
try await player.update(on: database)
|
||||||
try await Table.query(on: database).filter(\.$id == oldTable.id).delete()
|
try await Table.query(on: database).filter(\.$id == oldTable.id).delete()
|
||||||
return
|
return
|
||||||
@ -168,8 +167,8 @@ final class TableManagement {
|
|||||||
tables[table.id] = table
|
tables[table.id] = table
|
||||||
#warning("Update points for all players, add penalty if running game")
|
#warning("Update points for all players, add penalty if running game")
|
||||||
table.sendUpdateToAllPlayers()
|
table.sendUpdateToAllPlayers()
|
||||||
logPlayingPlayerCount()
|
await logPlayingPlayerCount()
|
||||||
logConnectedPlayerCount()
|
await logConnectedPlayerCount()
|
||||||
try await player.update(on: database)
|
try await player.update(on: database)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -177,16 +176,21 @@ final class TableManagement {
|
|||||||
guard let table = currentTable(for: player) else {
|
guard let table = currentTable(for: player) else {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
defer { logConnectedPlayerCount() }
|
let result = table.connect(player: player, using: socket)
|
||||||
return table.connect(player: player, using: socket)
|
Task {
|
||||||
|
await logConnectedPlayerCount()
|
||||||
|
}
|
||||||
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
func disconnect(player: PlayerName) {
|
func disconnect(player: PlayerName) {
|
||||||
guard let table = currentTable(for: player) else {
|
guard let table = currentTable(for: player) else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer { logConnectedPlayerCount() }
|
|
||||||
table.disconnect(player: player)
|
table.disconnect(player: player)
|
||||||
|
Task {
|
||||||
|
await logConnectedPlayerCount()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func performAction(player: PlayerName, action: PlayerAction) -> PlayerActionResult {
|
func performAction(player: PlayerName, action: PlayerAction) -> PlayerActionResult {
|
||||||
@ -255,6 +259,8 @@ final class TableManagement {
|
|||||||
|
|
||||||
func disconnectAllSockets() {
|
func disconnectAllSockets() {
|
||||||
tables.values.forEach { $0.disconnectAllPlayers() }
|
tables.values.forEach { $0.disconnectAllPlayers() }
|
||||||
logConnectedPlayerCount()
|
Task {
|
||||||
|
await logConnectedPlayerCount()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,24 +5,24 @@ import Clairvoyant
|
|||||||
var server: SQLiteDatabase!
|
var server: SQLiteDatabase!
|
||||||
|
|
||||||
// configures your application
|
// configures your application
|
||||||
public func configure(_ app: Application) throws {
|
public func configure(_ app: Application) async throws {
|
||||||
let storageFolder = URL(fileURLWithPath: app.directory.resourcesDirectory)
|
let storageFolder = URL(fileURLWithPath: app.directory.resourcesDirectory)
|
||||||
|
|
||||||
let logFolder = storageFolder.appendingPathComponent("logs")
|
let logFolder = storageFolder.appendingPathComponent("logs")
|
||||||
let accessManager = AccessTokenManager([])
|
let accessManager = AccessTokenManager([])
|
||||||
let monitor = MetricObserver(
|
let monitor = await MetricObserver(
|
||||||
logFolder: logFolder,
|
logFolder: logFolder,
|
||||||
accessManager: accessManager,
|
accessManager: accessManager,
|
||||||
logMetricId: "schafkopf.log")
|
logMetricId: "schafkopf.log")
|
||||||
MetricObserver.standard = monitor
|
MetricObserver.standard = monitor
|
||||||
|
|
||||||
let status = Metric<ServerStatus>(
|
let status = try! await Metric<ServerStatus>(
|
||||||
"schafkopf.status",
|
"schafkopf.status",
|
||||||
name: "Status",
|
name: "Status",
|
||||||
description: "The main status of the server")
|
description: "The main status of the server")
|
||||||
|
|
||||||
status.update(.initializing)
|
try? await status.update(.initializing)
|
||||||
monitor.registerRoutes(app)
|
await monitor.registerRoutes(app)
|
||||||
|
|
||||||
let configPath = URL(fileURLWithPath: app.directory.resourcesDirectory)
|
let configPath = URL(fileURLWithPath: app.directory.resourcesDirectory)
|
||||||
.appendingPathComponent("config.json")
|
.appendingPathComponent("config.json")
|
||||||
@ -31,8 +31,8 @@ public func configure(_ app: Application) throws {
|
|||||||
do {
|
do {
|
||||||
configuration = try Configuration(loadFromUrl: configPath)
|
configuration = try Configuration(loadFromUrl: configPath)
|
||||||
} catch {
|
} catch {
|
||||||
status.update(.initializationFailure)
|
try? await status.update(.initializationFailure)
|
||||||
monitor.log("Failed to read configuration: \(error)")
|
await monitor.log("Failed to read configuration: \(error)")
|
||||||
// Note: If configuration can't be loaded, then the server will run on the wrong port
|
// 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
|
// and access to metrics is impossible, since no tokens are loaded
|
||||||
return
|
return
|
||||||
@ -60,8 +60,8 @@ public func configure(_ app: Application) throws {
|
|||||||
do {
|
do {
|
||||||
try app.autoMigrate().wait()
|
try app.autoMigrate().wait()
|
||||||
} catch {
|
} catch {
|
||||||
monitor.log("Failed to migrate database: \(error)")
|
await monitor.log("Failed to migrate database: \(error)")
|
||||||
status.update(.initializationFailure)
|
try? await status.update(.initializationFailure)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,7 +69,7 @@ public func configure(_ app: Application) throws {
|
|||||||
app.middleware.use(FileMiddleware(publicDirectory: app.directory.publicDirectory))
|
app.middleware.use(FileMiddleware(publicDirectory: app.directory.publicDirectory))
|
||||||
|
|
||||||
let db = app.databases.database(.sqlite, logger: .init(label: "Init"), on: app.databases.eventLoopGroup.next())!
|
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
|
// Gracefully shut down by closing potentially open socket
|
||||||
DispatchQueue.global(qos: .utility).asyncAfter(deadline: .now() + .seconds(5)) {
|
DispatchQueue.global(qos: .utility).asyncAfter(deadline: .now() + .seconds(5)) {
|
||||||
@ -81,10 +81,15 @@ public func configure(_ app: Application) throws {
|
|||||||
// register routes
|
// register routes
|
||||||
routes(app)
|
routes(app)
|
||||||
|
|
||||||
status.update(.nominal)
|
try? await status.update(.nominal)
|
||||||
}
|
}
|
||||||
|
|
||||||
func log(_ message: String) {
|
func log(_ message: String) {
|
||||||
MetricObserver.standard?.log(message)
|
guard let observer = MetricObserver.standard else {
|
||||||
print(message)
|
print(message)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
Task {
|
||||||
|
await observer.log(message)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,5 +5,7 @@ var env = try Environment.detect()
|
|||||||
try LoggingSystem.bootstrap(from: &env)
|
try LoggingSystem.bootstrap(from: &env)
|
||||||
let app = Application(env)
|
let app = Application(env)
|
||||||
defer { app.shutdown() }
|
defer { app.shutdown() }
|
||||||
try configure(app)
|
Task {
|
||||||
try app.run()
|
try await configure(app)
|
||||||
|
try app.run()
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user