fix(desktop): timestamp every desktop.log / RECENT LOGS line
rememberLog prepended only '[hermes] ' to each line, so desktop.log and the in-app RECENT LOGS view carried no timestamps while agent.log and gateway.log (Python logging) did. Extract the line format into a small pure helper (desktop-log-line.ts) and prefix each line with an ISO-8601 UTC timestamp shared per chunk, matching the Python-side convention. Regression tests assert the shape contract: timestamp + [hermes] tag + verbatim message. Fixes #84405.
This commit is contained in:
@@ -0,0 +1,22 @@
|
||||
import { describe, expect, it } from 'vitest'
|
||||
|
||||
import { formatDesktopLogLine } from './desktop-log-line'
|
||||
|
||||
describe('formatDesktopLogLine', () => {
|
||||
it('prefixes each line with an ISO-8601 timestamp and the hermes tag', () => {
|
||||
const line = formatDesktopLogLine('[boot] Resolving Hermes backend')
|
||||
|
||||
// Shape contract (not a snapshot): every desktop log line starts with
|
||||
// an ISO timestamp so multi-surface logs are chronologically readable.
|
||||
// See #84405.
|
||||
expect(line).toMatch(
|
||||
/^\[\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z\] \[hermes\] \[boot\] Resolving Hermes backend$/
|
||||
)
|
||||
})
|
||||
|
||||
it('keeps the message verbatim after the prefix', () => {
|
||||
const line = formatDesktopLogLine('Hermes backend exited (0)')
|
||||
|
||||
expect(line).toMatch(/^\[\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z\] \[hermes\] Hermes backend exited \(0\)$/)
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,19 @@
|
||||
/**
|
||||
* Desktop log line formatting shared by every desktop log surface:
|
||||
* `desktop.log`, the in-app "RECENT LOGS" view, and crash forensics.
|
||||
*
|
||||
* Historically each line was prefixed with just `[hermes] `, so lines from
|
||||
* different moments were indistinguishable. Every surface now carries an
|
||||
* ISO-8601 UTC timestamp, matching the Python-side `agent.log` /
|
||||
* `gateway.log` convention (`2026-07-12 16:22:17,540 INFO ...`). See #84405.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Format one desktop log line with an ISO-8601 UTC timestamp.
|
||||
*
|
||||
* `stamp` defaults to now; callers that batch multiple lines (a single
|
||||
* stdout chunk) pass one shared stamp so the group reads as one event.
|
||||
*/
|
||||
export function formatDesktopLogLine(text: string, stamp = new Date().toISOString()): string {
|
||||
return `[${stamp}] [hermes] ${text}`
|
||||
}
|
||||
@@ -31,6 +31,7 @@ import {
|
||||
import nodePty from 'node-pty'
|
||||
|
||||
import { classifyActiveRuntime } from './active-runtime-state'
|
||||
import { formatDesktopLogLine } from './desktop-log-line'
|
||||
import { stopBackendChild as stopBackendChildImpl, stopBackendTreesForUpdate } from './backend-child'
|
||||
import { dashboardFallbackArgs, sourceDeclaresServe } from './backend-command'
|
||||
import { createBackendConnectionState } from './backend-connection-state'
|
||||
@@ -1347,7 +1348,10 @@ function rememberLog(chunk) {
|
||||
return
|
||||
}
|
||||
|
||||
const lines = text.split(/\r?\n/).map(line => `[hermes] ${line}`)
|
||||
// One timestamp per chunk: lines arriving in the same event happened
|
||||
// at the same moment. ISO-8601 UTC, matching agent.log/gateway.log.
|
||||
const stamp = new Date().toISOString()
|
||||
const lines = text.split(/\r?\n/).map(line => formatDesktopLogLine(line, stamp))
|
||||
hermesLog.push(...lines)
|
||||
|
||||
if (hermesLog.length > 300) {
|
||||
|
||||
Reference in New Issue
Block a user