use better structured logging

This commit is contained in:
Evan
2024-12-17 20:34:15 -08:00
parent 94992e1144
commit 113518a96e
4 changed files with 57 additions and 17 deletions
+1
View File
@@ -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({
+10 -3
View File
@@ -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)
+19 -3
View File
@@ -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,
})
}
})
});
+27 -11
View File
@@ -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}`);
}
}
}