From 94992e1144d620c0c8a589dee334b709dfcdd4bc Mon Sep 17 00:00:00 2001 From: Evan Date: Tue, 17 Dec 2024 19:53:17 -0800 Subject: [PATCH] send all logs from client to server and log them --- src/client/GameRunner.ts | 3 ++- src/client/LogSender.ts | 33 +++++++++++++++++++++++++++------ src/client/Main.ts | 1 + src/client/Transport.ts | 4 ++-- src/core/Schemas.ts | 10 +++++++++- src/server/Server.ts | 12 ++++++------ src/server/StructuredLog.ts | 12 +++--------- 7 files changed, 50 insertions(+), 25 deletions(-) diff --git a/src/client/GameRunner.ts b/src/client/GameRunner.ts index af7dde298..52eb54be0 100644 --- a/src/client/GameRunner.ts +++ b/src/client/GameRunner.ts @@ -13,6 +13,7 @@ import { SendAttackIntentEvent, SendSpawnIntentEvent, Transport } from "./Transp import { createCanvas } from "./Utils"; import { DisplayMessageEvent, MessageType } from "./graphics/layers/EventsDisplay"; import { WorkerClient } from "../core/worker/WorkerClient"; +import { initializeLogSender } from "./LogSender"; export interface LobbyConfig { playerName: () => string @@ -27,6 +28,7 @@ export interface LobbyConfig { export function joinLobby(lobbyConfig: LobbyConfig, onjoin: () => void): () => void { const eventBus = new EventBus() + initializeLogSender(eventBus) const config = getConfig() let gameConfig: GameConfig = null @@ -186,7 +188,6 @@ export class GameRunner { } private playerEvent(event: PlayerEvent) { - console.log('received new player event!') if (event.player.clientID() == this.clientID) { console.log('setting name') this.myPlayer = event.player diff --git a/src/client/LogSender.ts b/src/client/LogSender.ts index f2edd4691..3ff203648 100644 --- a/src/client/LogSender.ts +++ b/src/client/LogSender.ts @@ -1,16 +1,37 @@ import { EventBus } from "../core/EventBus" +import { LogSeverity } from "../core/Schemas" import { SendLogEvent } from "./Transport" -export enum LogSeverity { - Info, - Warn, - Error -} +let inited = false export function initializeLogSender(eventBus: EventBus) { + if (inited) { + return + } + inited = true + + // Store original console methods + const originalLog = console.log + const originalWarn = console.warn + const originalError = console.error + const log = (msg: string): void => { eventBus.emit(new SendLogEvent(LogSeverity.Info, msg)) - console.log(msg) + originalLog.call(console, msg) // Use the original method } + + const warn = (msg: string): void => { + eventBus.emit(new SendLogEvent(LogSeverity.Warn, msg)) + originalWarn.call(console, msg) // Use the original method + } + + const error = (msg: string): void => { + eventBus.emit(new SendLogEvent(LogSeverity.Error, msg)) + originalError.call(console, msg) // Use the original method + } + + // Replace console methods console.log = log + console.warn = warn + console.error = error } \ No newline at end of file diff --git a/src/client/Main.ts b/src/client/Main.ts index a40f10933..e1fdb6e7d 100644 --- a/src/client/Main.ts +++ b/src/client/Main.ts @@ -10,6 +10,7 @@ import { SinglePlayerModal } from "./SinglePlayerModal"; import { HostLobbyModal as HostPrivateLobbyModal } from "./HostLobbyModal"; import { JoinPrivateLobbyModal } from "./JoinPrivateLobbyModal"; import { generateID } from "../core/Util"; +import { initializeLogSender } from "./LogSender"; diff --git a/src/client/Transport.ts b/src/client/Transport.ts index d5b932d46..f0a9518d9 100644 --- a/src/client/Transport.ts +++ b/src/client/Transport.ts @@ -1,10 +1,9 @@ import { Config } from "../core/configuration/Config" import { EventBus, GameEvent } from "../core/EventBus" import { AllianceRequest, AllPlayers, Cell, GameType, Player, PlayerID, PlayerType, Tile, UnitType } from "../core/game/Game" -import { ClientID, ClientIntentMessageSchema, ClientJoinMessageSchema, GameID, Intent, ServerMessage, ServerMessageSchema, ClientPingMessageSchema, GameConfig, ClientLogMessageSchema } from "../core/Schemas" +import { ClientID, ClientIntentMessageSchema, ClientJoinMessageSchema, GameID, Intent, ServerMessage, ServerMessageSchema, ClientPingMessageSchema, GameConfig, ClientLogMessageSchema, LogSeverity } from "../core/Schemas" import { LobbyConfig } from "./GameRunner" import { LocalServer } from "./LocalServer" -import { LogSeverity } from "./LogSender" export class SendAllianceRequestIntentEvent implements GameEvent { @@ -206,6 +205,7 @@ export class Transport { clientID: this.lobbyConfig.clientID, persistentID: this.lobbyConfig.persistentID, log: event.log, + severity: event.severity, }) ) ) diff --git a/src/core/Schemas.ts b/src/core/Schemas.ts index c07e266fa..4545a2e1c 100644 --- a/src/core/Schemas.ts +++ b/src/core/Schemas.ts @@ -48,6 +48,14 @@ export type GameRecord = z.infer const PlayerTypeSchema = z.nativeEnum(PlayerType); +export enum LogSeverity { + Debug = 'DEBUG', + Info = 'INFO', + Warn = 'WARN', + Error = 'ERROR', + Fatal = 'FATAL' +} + // TODO: create Cell schema export interface Lobby { @@ -216,7 +224,7 @@ const ClientBaseMessageSchema = z.object({ export const ClientLogMessageSchema = ClientBaseMessageSchema.extend({ type: z.literal('log'), - severity: z.enum(['']) + severity: z.nativeEnum(LogSeverity), log: z.string(), }) diff --git a/src/server/Server.ts b/src/server/Server.ts index 99e6f40b7..a974b6c13 100644 --- a/src/server/Server.ts +++ b/src/server/Server.ts @@ -4,9 +4,9 @@ import { WebSocketServer } from 'ws'; import path from 'path'; import { fileURLToPath } from 'url'; import { GameManager } from './GameManager'; -import { ClientMessage, ClientMessageSchema, GameRecord, GameRecordSchema, Turn, TurnSchema } from '../core/Schemas'; +import { ClientMessage, ClientMessageSchema, GameRecord, GameRecordSchema, LogSeverity } from '../core/Schemas'; import { getConfig } from '../core/configuration/Config'; -import { LogSeverity, slog } from './StructuredLog'; +import { slog } from './StructuredLog'; import { Client } from './Client'; import { GamePhase, GameServer } from './GameServer'; import { archive } from './Archive'; @@ -68,7 +68,7 @@ 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('complete_single_player_game_record', 'Failed to complete game record', { error }, LogSeverity.Error); res.status(400).json({ error: 'Invalid game record format' }); } }) @@ -103,7 +103,7 @@ 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('websocket_msg', 'server received websocket message', clientMsg, LogSeverity.Debug) if (clientMsg.type == "join") { const forwarded = req.headers['x-forwarded-for'] const ip = Array.isArray(forwarded) @@ -122,8 +122,8 @@ wss.on('connection', (ws, req) => { clientMsg.lastTurn ) } - if(clientMsg.type == "log") { - console.log() + if (clientMsg.type == "log") { + console.log(clientMsg.log) } }) }); diff --git a/src/server/StructuredLog.ts b/src/server/StructuredLog.ts index 071e47b23..b253e4254 100644 --- a/src/server/StructuredLog.ts +++ b/src/server/StructuredLog.ts @@ -1,12 +1,6 @@ -export enum LogSeverity { - DEBUG = 'DEBUG', - INFO = 'INFO', - WARN = 'WARN', - ERROR = 'ERROR', - FATAL = 'FATAL' -} +import { LogSeverity } from "../core/Schemas"; -export function slog(eventType: string, description, data: any, severity = LogSeverity.INFO): void { +export function slog(eventType: string, description, data: any, severity = LogSeverity.Info): void { const logEntry = { eventType: eventType, description: description, @@ -14,7 +8,7 @@ export function slog(eventType: string, description, data: any, severity = LogSe data: data }; if (process.env.GAME_ENV == 'dev') { - if (severity != LogSeverity.DEBUG) { + if (severity != LogSeverity.Debug) { console.log(description) } } else {