diff options
author | Ilion Beyst <ilion.beyst@gmail.com> | 2022-09-17 11:55:17 +0200 |
---|---|---|
committer | Ilion Beyst <ilion.beyst@gmail.com> | 2022-09-17 11:55:17 +0200 |
commit | f5fe1c4f2918561d70a56d196aaf1b13c97a2bf1 (patch) | |
tree | 6700d2139eda39d87223b991fb4e9adeb89d1e02 | |
parent | 518ad1d811e87872fcd6d769435f485d0ed31768 (diff) | |
download | planetwars.dev-f5fe1c4f2918561d70a56d196aaf1b13c97a2bf1.tar.xz planetwars.dev-f5fe1c4f2918561d70a56d196aaf1b13c97a2bf1.zip |
initial version of structured log display
-rw-r--r-- | web/pw-server/src/lib/components/OutputPane.svelte | 80 | ||||
-rw-r--r-- | web/pw-server/src/lib/log_parser.ts | 55 |
2 files changed, 134 insertions, 1 deletions
diff --git a/web/pw-server/src/lib/components/OutputPane.svelte b/web/pw-server/src/lib/components/OutputPane.svelte index 759fd4c..efd0d2c 100644 --- a/web/pw-server/src/lib/components/OutputPane.svelte +++ b/web/pw-server/src/lib/components/OutputPane.svelte @@ -4,6 +4,8 @@ export let matchLog: string; let playerLog: PlayerLog; + let showRawStderr = false; + $: if (matchLog) { playerLog = parsePlayerLog(1, matchLog); } else { @@ -13,9 +15,38 @@ <div class="output"> <h3 class="output-header">Player log</h3> + {#if showRawStderr} <div class="output-text stderr-text"> {playerLog.flatMap((turn) => turn.stderr).join("\n")} </div> + {:else} + <div class="output-text"> + {#each playerLog as logTurn, i} + <div class="turn"> + <div class="turn-header"> + <span class="turn-header-text">Turn {i}</span> + {#if logTurn.action?.type === "bad_command"} + <span class="turn-error">invalid command</span> + {/if} + </div> + {#if logTurn.action?.type === "bad_command"} + <div class="bad-command-container"> + <div class="bad-command-text">{logTurn.action.command}</div> + <div class="bad-command-error">Parse error: {logTurn.action.error}</div> + </div> + {/if} + {#if logTurn.stderr.length > 0} + <div class="stderr-header">stderr</div> + <div class="stderr-text-box"> + {#each logTurn.stderr as stdErrMsg} + <div class="stderr-text">{stdErrMsg}</div> + {/each} + </div> + {/if} + </div> + {/each} + </div> + {/if} </div> <style lang="scss"> @@ -26,15 +57,62 @@ padding: 15px; } + .turn { + margin: 16px 4px; + } + .output-text { color: #ccc; } + .turn-header { + display: flex; + justify-content: space-between; + } + + .turn-header-text { + color: #eee; + font-size: 14px; + font-weight: 600; + text-transform: uppercase; + } + + .turn-error { + color: red; + } + + .bad-command-container { + border-left: 1px solid red; + margin-left: 4px; + padding-left: 8px; + } + + .bad-command-text { + font-family: "Consolas", "Bitstream Vera Sans Mono", "Courier New", Courier, monospace; + padding-bottom: 4px; + } + + .bad-command-error { + color: whitesmoke; + } + .stderr-text { - font-family: monospace; + // font-family: monospace; + font-family: "Consolas", "Bitstream Vera Sans Mono", "Courier New", Courier, monospace; white-space: pre-wrap; } + .stderr-header { + color: #eee; + padding-top: 4px; + } + + .stderr-text-box { + border-left: 1px solid #ccc; + margin-left: 4px; + padding-left: 8px; + } + .output-header { color: #eee; padding-bottom: 20px; diff --git a/web/pw-server/src/lib/log_parser.ts b/web/pw-server/src/lib/log_parser.ts new file mode 100644 index 0000000..77c459f --- /dev/null +++ b/web/pw-server/src/lib/log_parser.ts @@ -0,0 +1,55 @@ +export type PlayerLog = PlayerLogTurn[]; + +export type PlayerLogTurn = { + action?: PlayerAction; + stderr: string[]; +}; + +type PlayerAction = BadCommand; + +type BadCommand = { + type: "bad_command"; + command: string; + error: string; +}; + +function createEmptyLogTurn(): PlayerLogTurn { + return { + stderr: [], + }; +} + +export function parsePlayerLog(playerId: number, logText: string): PlayerLog { + const logLines = logText.split("\n").slice(0, -1); + + const playerLog: PlayerLog = []; + + let turn = null; + + logLines.forEach((logLine) => { + const logMessage = JSON.parse(logLine); + + if (logMessage["type"] === "gamestate") { + if (turn) { + playerLog.push(turn); + turn = createEmptyLogTurn(); + } + } else if (logMessage["player_id"] === playerId) { + if (!turn) { + // older match logs don't have an initial game state due to a bug. + turn = createEmptyLogTurn(); + } + switch (logMessage["type"]) { + case "stderr": { + let msg = logMessage["message"]; + turn.stderr.push(msg); + } + case "bad_command": { + turn.action = logMessage; + } + } + } + }); + + return playerLog; +} |