Skip to content

Commit 8178c75

Browse files
author
DavidQ
committed
Add runtime monitoring and logging foundation
- runtime error tracking added - performance monitoring hooks added - logging standardized - roadmap advanced
1 parent b2c61c4 commit 8178c75

12 files changed

Lines changed: 555 additions & 1 deletion
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# BUILD_PR_LEVEL_22_1_RUNTIME_MONITORING_AND_LOGGING_FOUNDATION — Error Tracking
2+
3+
## Scope Implemented
4+
- Added `createRuntimeMonitoringHooks` in `src/engine/runtime/RuntimeMonitoringHooks.js` as the shared runtime error/performance hook surface.
5+
- Wired engine runtime monitoring lifecycle in `src/engine/core/Engine.js`:
6+
- start hooks during `engine.start()`
7+
- stop hooks during `engine.stop()`
8+
- emit monitoring events to runtime consumers:
9+
- `engine:runtime-monitoring-error`
10+
- `engine:runtime-monitoring-performance`
11+
- Wired tools runtime monitoring in `tools/shared/platformShell.js` with the shared hook surface and tools runtime context capture.
12+
13+
## Error Tracking Behavior
14+
- Captures global runtime errors when `window` is available:
15+
- `window.error`
16+
- `window.unhandledrejection`
17+
- Emits normalized payloads using `runtime.monitoring.v1`.
18+
- Preserves non-breaking behavior by keeping existing `engine:runtime-error` and `trackRuntimeError(...)` flow unchanged.
19+
20+
## Files
21+
- `src/engine/runtime/RuntimeMonitoringHooks.js`
22+
- `src/engine/runtime/index.js`
23+
- `src/engine/core/Engine.js`
24+
- `tools/shared/platformShell.js`
25+
- `tests/runtime/RuntimeMonitoringHooks.test.mjs`
26+
- `tests/runtime/Phase19RuntimeLifecycleValidation.test.mjs`
27+
- `tests/run-tests.mjs`
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# BUILD_PR_LEVEL_22_1_RUNTIME_MONITORING_AND_LOGGING_FOUNDATION — Logging Standard
2+
3+
## Logging Baseline
4+
- Existing standardized logger format remains authoritative:
5+
- `format: engine.log.v1`
6+
- This PR adds runtime monitoring event usage aligned to that format:
7+
- `runtime.monitoring.error`
8+
- `runtime.monitoring.performance`
9+
10+
## Standardized Expectations
11+
- Every emitted logger entry includes:
12+
- `format`
13+
- `level`
14+
- `channel`
15+
- `event`
16+
- `message`
17+
- `meta`
18+
- `timestamp`
19+
- Runtime monitoring payload contract is versioned separately as:
20+
- `format: runtime.monitoring.v1`
21+
22+
## Non-Breaking Guarantee
23+
- Existing logger behavior is unchanged.
24+
- Existing engine runtime error/performance events are preserved.
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# BUILD_PR_LEVEL_22_1_RUNTIME_MONITORING_AND_LOGGING_FOUNDATION — Performance Monitoring
2+
3+
## Scope Implemented
4+
- Added shared runtime performance sampling via `createRuntimeMonitoringHooks(...)`.
5+
- Hook emits performance samples at runtime start and on configured interval.
6+
- Engine now starts/stops monitoring with runtime lifecycle.
7+
- Tools platform shell now starts/stops monitoring for tool runtime surfaces.
8+
9+
## Monitoring Payload
10+
- Format: `runtime.monitoring.v1`
11+
- Kind: `performance`
12+
- Fields:
13+
- `source`
14+
- `reason` (`start`, `interval`, `manual`)
15+
- `timestamp`
16+
- `sample.nowMs`
17+
- optional `sample.memory` (when available)
18+
- `context`
19+
20+
## Validation Notes
21+
- Targeted tests verify start sample, interval sample, and manual sample behavior.
22+
- Existing lifecycle validation confirms engine performance frame publication remains intact (`engine:performance-frame`).
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# BUILD_PR_LEVEL_22_1_RUNTIME_MONITORING_AND_LOGGING_FOUNDATION — Validation
2+
3+
## Commands Run
4+
1. `node --input-type=module -e "import { run as runHooks } from './tests/runtime/RuntimeMonitoringHooks.test.mjs'; import { run as runLifecycle } from './tests/runtime/Phase19RuntimeLifecycleValidation.test.mjs'; runHooks(); runLifecycle(); console.log('PASS runtime monitoring + lifecycle');"`
5+
2. `node --input-type=module -e "import { run as runShell } from './tests/tools/PlatformShellHeaderAlignment.test.mjs'; runShell(); console.log('PASS platform shell header alignment');"`
6+
7+
## Results
8+
- PASS runtime monitoring + lifecycle
9+
- PASS platform shell header alignment
10+
11+
## Validation Coverage
12+
- Runtime hook payload contracts (`runtime.monitoring.v1`) validated.
13+
- Runtime lifecycle integration (engine start/stop monitoring) validated.
14+
- Existing runtime lifecycle and logging format behavior validated.
15+
- Tools shell integration change validated against existing shell alignment test surface.
16+
17+
## Roadmap Status Handling
18+
- Checked `docs/dev/roadmaps/MASTER_ROADMAP_ENGINE.md` Track 20B.
19+
- Items were already `[x]` before this PR:
20+
- runtime error tracking
21+
- performance monitoring hooks
22+
- logging standardization
23+
- No roadmap text rewrite performed.
24+
- No non-status roadmap edits performed.
25+
26+
## Scope Confirmation
27+
- No `start_of_day` changes.
28+
- No unrelated cleanup.
29+
- Smallest scoped implementation for runtime monitoring/logging foundation.
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# BUILD_PR_LEVEL_22_1_RUNTIME_MONITORING_AND_LOGGING_FOUNDATION
2+
3+
## Purpose
4+
Establish runtime monitoring, error tracking, and logging standardization across the system.
5+
6+
## Scope
7+
- runtime error tracking hooks
8+
- performance monitoring hooks
9+
- logging standardization baseline
10+
11+
## Roadmap Advancement
12+
13+
### Track B — Stability & Monitoring
14+
- `runtime error tracking` [ ] -> [x]
15+
- `performance monitoring hooks` [ ] -> [x]
16+
- `logging standardization` [ ] -> [x]
17+
18+
## Required Outputs
19+
- docs/dev/reports/BUILD_PR_LEVEL_22_1_RUNTIME_MONITORING_AND_LOGGING_FOUNDATION_ERROR_TRACKING.md
20+
- docs/dev/reports/BUILD_PR_LEVEL_22_1_RUNTIME_MONITORING_AND_LOGGING_FOUNDATION_PERFORMANCE_MONITORING.md
21+
- docs/dev/reports/BUILD_PR_LEVEL_22_1_RUNTIME_MONITORING_AND_LOGGING_FOUNDATION_LOGGING_STANDARD.md
22+
- docs/dev/reports/BUILD_PR_LEVEL_22_1_RUNTIME_MONITORING_AND_LOGGING_FOUNDATION_VALIDATION.md
23+
24+
## Rules
25+
- no breaking changes
26+
- no feature expansion
27+
- no start_of_day changes

src/engine/core/Engine.js

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,13 @@ import FrameClock from './FrameClock.js';
1010
import FixedTicker from './FixedTicker.js';
1111
import EventBus from '../events/EventBus.js';
1212
import { Camera3D } from '../camera/index.js';
13-
import { backgroundImage, fullscreenBezel, FullscreenService, resolvePreferredFullscreenTarget } from '../runtime/index.js';
13+
import {
14+
backgroundImage,
15+
fullscreenBezel,
16+
FullscreenService,
17+
resolvePreferredFullscreenTarget,
18+
createRuntimeMonitoringHooks
19+
} from '../runtime/index.js';
1420
import { AudioService } from '../audio/index.js';
1521
import { Logger } from '../logging/index.js';
1622
import { SettingsSystem } from '../release/index.js';
@@ -33,6 +39,7 @@ export default class Engine {
3339
logger = null,
3440
camera3D = null,
3541
runtimeHooks = null,
42+
runtimeMonitoring = null,
3643
} = {}) {
3744
if (!canvas) {
3845
throw new Error('Engine requires a canvas.');
@@ -75,6 +82,20 @@ export default class Engine {
7582
onError: typeof runtimeHooks?.onError === 'function' ? runtimeHooks.onError : null,
7683
onPerformance: typeof runtimeHooks?.onPerformance === 'function' ? runtimeHooks.onPerformance : null,
7784
};
85+
this.runtimeMonitoring = runtimeMonitoring || createRuntimeMonitoringHooks({
86+
logger: this.logger,
87+
source: 'engine',
88+
sampleIntervalMs: 10000,
89+
onError: (payload) => {
90+
this.events?.emit?.('engine:runtime-monitoring-error', payload);
91+
},
92+
onPerformance: (payload) => {
93+
this.events?.emit?.('engine:runtime-monitoring-performance', payload);
94+
},
95+
contextProvider: () => ({
96+
sceneType: this.scene?.constructor?.name || '',
97+
}),
98+
});
7899
this.camera3D = camera3D || new Camera3D();
79100
this.settings = new SettingsSystem({
80101
namespace: 'toolboxaid:engine-settings',
@@ -202,6 +223,15 @@ export default class Engine {
202223

203224
this.frameClock.reset();
204225
this.fixedTicker.reset();
226+
try {
227+
this.runtimeMonitoring?.start?.();
228+
} catch (error) {
229+
this.trackRuntimeError('runtimeMonitoring.start', error, {
230+
severity: 'warn',
231+
isolated: true,
232+
message: 'Engine runtime monitoring hooks failed to start.',
233+
});
234+
}
205235
this.rafId = requestAnimationFrame(this.tick);
206236
}
207237

@@ -223,6 +253,15 @@ export default class Engine {
223253
if (this.fullscreenBezelLayer && typeof this.fullscreenBezelLayer.detach === 'function') {
224254
this.fullscreenBezelLayer.detach();
225255
}
256+
try {
257+
this.runtimeMonitoring?.stop?.();
258+
} catch (error) {
259+
this.trackRuntimeError('runtimeMonitoring.stop', error, {
260+
severity: 'warn',
261+
isolated: true,
262+
message: 'Engine runtime monitoring hooks failed to stop.',
263+
});
264+
}
226265
}
227266

228267
tick(now) {

0 commit comments

Comments
 (0)