diff --git a/src/core/Schemas.ts b/src/core/Schemas.ts index 4545a2e1c..811fbf44b 100644 --- a/src/core/Schemas.ts +++ b/src/core/Schemas.ts @@ -226,6 +226,7 @@ export const ClientLogMessageSchema = ClientBaseMessageSchema.extend({ type: z.literal('log'), severity: z.nativeEnum(LogSeverity), log: z.string(), + persistentID: z.string(), }) export const ClientPingMessageSchema = ClientBaseMessageSchema.extend({ diff --git a/src/server/GameServer.ts b/src/server/GameServer.ts index 778bf18b9..6dbed548f 100644 --- a/src/server/GameServer.ts +++ b/src/server/GameServer.ts @@ -51,11 +51,18 @@ export class GameServer { public addClient(client: Client, lastTurn: number) { console.log(`${this.id}: adding client ${client.clientID}`) - slog('client_joined_game', `client ${client.clientID} (re)joining game ${this.id}`, { + slog({ + logKey: 'client_joined_game', + msg: `client ${client.clientID} (re)joining game ${this.id}`, + data: { + clientID: client.clientID, + clientIP: client.ip, + gameID: this.id, + isRejoin: lastTurn > 0 + }, clientID: client.clientID, - clientIP: client.ip, + persistentID: client.persistentID, gameID: this.id, - isRejoin: lastTurn > 0 }) // Remove stale client if this is a reconnect const existing = this.activeClients.find(c => c.clientID == client.clientID) diff --git a/src/server/Server.ts b/src/server/Server.ts index a974b6c13..e591b783f 100644 --- a/src/server/Server.ts +++ b/src/server/Server.ts @@ -68,7 +68,11 @@ app.post('/archive_singleplayer_game', (req, res) => { success: true, }); } catch (error) { - slog('complete_single_player_game_record', 'Failed to complete game record', { error }, LogSeverity.Error); + slog({ + logKey: 'complete_single_player_game_record', + msg: `Failed to complete game record: ${error}`, + severity: LogSeverity.Error, + }); res.status(400).json({ error: 'Invalid game record format' }); } }) @@ -103,7 +107,12 @@ app.get('/private_lobby/:id', (req, res) => { wss.on('connection', (ws, req) => { ws.on('message', (message: string) => { const clientMsg: ClientMessage = ClientMessageSchema.parse(JSON.parse(message)) - slog('websocket_msg', 'server received websocket message', clientMsg, LogSeverity.Debug) + slog({ + logKey: 'websocket_msg', + msg: 'server received websocket message', + data: clientMsg, + severity: LogSeverity.Debug + }) if (clientMsg.type == "join") { const forwarded = req.headers['x-forwarded-for'] const ip = Array.isArray(forwarded) @@ -123,7 +132,14 @@ wss.on('connection', (ws, req) => { ) } if (clientMsg.type == "log") { - console.log(clientMsg.log) + slog({ + logKey: "client_console_log", + msg: clientMsg.log, + severity: clientMsg.severity, + clientID: clientMsg.clientID, + gameID: clientMsg.gameID, + persistentID: clientMsg.persistentID, + }) } }) }); diff --git a/src/server/StructuredLog.ts b/src/server/StructuredLog.ts index b253e4254..0099c2cc5 100644 --- a/src/server/StructuredLog.ts +++ b/src/server/StructuredLog.ts @@ -1,17 +1,33 @@ -import { LogSeverity } from "../core/Schemas"; +import { ClientID, GameID, LogSeverity } from "../core/Schemas"; + +export interface slogMsg { + logKey: string, + msg: string, + data?: any + severity?: LogSeverity + gameID?: GameID + clientID?: ClientID + persistentID?: string +} + +export function slog(msg: slogMsg): void { + msg.severity = msg.severity ?? LogSeverity.Info; -export function slog(eventType: string, description, data: any, severity = LogSeverity.Info): void { - const logEntry = { - eventType: eventType, - description: description, - severity: severity, - data: data - }; if (process.env.GAME_ENV == 'dev') { - if (severity != LogSeverity.Debug) { - console.log(description) + // Avoid blowing up the log during development. + if (msg.logKey == 'client_console_log') { + return + } + if (msg.severity != LogSeverity.Debug) { + console.log(msg.msg) } } else { - console.log(JSON.stringify(logEntry)); + try { + console.log(JSON.stringify(msg)); + } catch (error) { + console.error('Failed to stringify log message:', error); + // Fallback to basic logging + console.log(`${msg.severity}: ${msg.msg}`); + } } } \ No newline at end of file