@senpi/runtime 3.0.124 → 3.0.125
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/actions/action-events.d.ts +21 -7
- package/dist/actions/action-events.d.ts.map +1 -1
- package/dist/actions/action-events.js +54 -26
- package/dist/actions/action-events.js.map +1 -1
- package/dist/actions/action-runtime-module.d.ts.map +1 -1
- package/dist/actions/action-runtime-module.js +38 -7
- package/dist/actions/action-runtime-module.js.map +1 -1
- package/dist/actions/close-position/close-position.action.d.ts.map +1 -1
- package/dist/actions/close-position/close-position.action.js +122 -15
- package/dist/actions/close-position/close-position.action.js.map +1 -1
- package/dist/actions/decision-engine.d.ts.map +1 -1
- package/dist/actions/decision-engine.js +15 -2
- package/dist/actions/decision-engine.js.map +1 -1
- package/dist/actions/event-derivation.d.ts +71 -2
- package/dist/actions/event-derivation.d.ts.map +1 -1
- package/dist/actions/event-derivation.js +251 -8
- package/dist/actions/event-derivation.js.map +1 -1
- package/dist/actions/open-position/open-position.action.d.ts +17 -2
- package/dist/actions/open-position/open-position.action.d.ts.map +1 -1
- package/dist/actions/open-position/open-position.action.js +162 -47
- package/dist/actions/open-position/open-position.action.js.map +1 -1
- package/dist/actions/position-tracker/position-tracker.action.d.ts +2 -1
- package/dist/actions/position-tracker/position-tracker.action.d.ts.map +1 -1
- package/dist/actions/position-tracker/position-tracker.action.js +62 -17
- package/dist/actions/position-tracker/position-tracker.action.js.map +1 -1
- package/dist/actions/skipped-signal-results.d.ts +25 -0
- package/dist/actions/skipped-signal-results.d.ts.map +1 -0
- package/dist/actions/skipped-signal-results.js +71 -0
- package/dist/actions/skipped-signal-results.js.map +1 -0
- package/dist/actions/store/types.d.ts +9 -2
- package/dist/actions/store/types.d.ts.map +1 -1
- package/dist/actions/store/types.js.map +1 -1
- package/dist/actions/types.d.ts +13 -0
- package/dist/actions/types.d.ts.map +1 -1
- package/dist/actions/types.js +13 -0
- package/dist/actions/types.js.map +1 -1
- package/dist/cli/guide-commands.d.ts.map +1 -1
- package/dist/cli/guide-commands.js +3 -0
- package/dist/cli/guide-commands.js.map +1 -1
- package/dist/dsl/engine-client/event-mapping.d.ts.map +1 -1
- package/dist/dsl/engine-client/event-mapping.js +14 -0
- package/dist/dsl/engine-client/event-mapping.js.map +1 -1
- package/dist/dsl/events/build-closed-event.d.ts +16 -1
- package/dist/dsl/events/build-closed-event.d.ts.map +1 -1
- package/dist/dsl/events/build-closed-event.js +6 -0
- package/dist/dsl/events/build-closed-event.js.map +1 -1
- package/dist/dsl/events/handlers.d.ts +7 -0
- package/dist/dsl/events/handlers.d.ts.map +1 -1
- package/dist/dsl/events/handlers.js +37 -7
- package/dist/dsl/events/handlers.js.map +1 -1
- package/dist/dsl/monitor/create-monitor.d.ts +6 -2
- package/dist/dsl/monitor/create-monitor.d.ts.map +1 -1
- package/dist/dsl/monitor/create-monitor.js +15 -9
- package/dist/dsl/monitor/create-monitor.js.map +1 -1
- package/dist/dsl/monitor/dsl-failure-events.d.ts +2 -0
- package/dist/dsl/monitor/dsl-failure-events.d.ts.map +1 -1
- package/dist/dsl/monitor/dsl-failure-events.js +2 -1
- package/dist/dsl/monitor/dsl-failure-events.js.map +1 -1
- package/dist/dsl/monitor/process-one-position.d.ts +1 -0
- package/dist/dsl/monitor/process-one-position.d.ts.map +1 -1
- package/dist/dsl/monitor/process-one-position.js +59 -25
- package/dist/dsl/monitor/process-one-position.js.map +1 -1
- package/dist/dsl/plugin/index.d.ts +8 -2
- package/dist/dsl/plugin/index.d.ts.map +1 -1
- package/dist/dsl/plugin/index.js +8 -6
- package/dist/dsl/plugin/index.js.map +1 -1
- package/dist/health/types.d.ts +13 -0
- package/dist/health/types.d.ts.map +1 -1
- package/dist/health/types.js +12 -0
- package/dist/health/types.js.map +1 -1
- package/dist/index.d.ts +27 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +254 -42
- package/dist/index.js.map +1 -1
- package/dist/runtime/action-registry.d.ts.map +1 -1
- package/dist/runtime/action-registry.js +4 -3
- package/dist/runtime/action-registry.js.map +1 -1
- package/dist/runtime/domain-events.d.ts.map +1 -1
- package/dist/runtime/domain-events.js +7 -0
- package/dist/runtime/domain-events.js.map +1 -1
- package/dist/runtime/lifecycle-events.d.ts +9 -1
- package/dist/runtime/lifecycle-events.d.ts.map +1 -1
- package/dist/runtime/lifecycle-events.js +11 -2
- package/dist/runtime/lifecycle-events.js.map +1 -1
- package/dist/runtime/reconcile-run.d.ts +13 -3
- package/dist/runtime/reconcile-run.d.ts.map +1 -1
- package/dist/runtime/reconcile-run.js +4 -3
- package/dist/runtime/reconcile-run.js.map +1 -1
- package/dist/runtime/reconcile-state.d.ts +8 -0
- package/dist/runtime/reconcile-state.d.ts.map +1 -1
- package/dist/runtime/reconcile-state.js +4 -1
- package/dist/runtime/reconcile-state.js.map +1 -1
- package/dist/runtime/run.d.ts +1 -0
- package/dist/runtime/run.d.ts.map +1 -1
- package/dist/runtime/run.js.map +1 -1
- package/dist/runtime/runtime-schema.js +3 -3
- package/dist/runtime/runtime-schema.js.map +1 -1
- package/dist/runtime/runtime.d.ts +1 -0
- package/dist/runtime/runtime.d.ts.map +1 -1
- package/dist/runtime/runtime.js +27 -3
- package/dist/runtime/runtime.js.map +1 -1
- package/dist/runtime/supervisor/long-running-supervisor.d.ts +13 -0
- package/dist/runtime/supervisor/long-running-supervisor.d.ts.map +1 -1
- package/dist/runtime/supervisor/long-running-supervisor.js +1 -0
- package/dist/runtime/supervisor/long-running-supervisor.js.map +1 -1
- package/dist/runtime/validate-dsl-position-tracking.d.ts.map +1 -1
- package/dist/runtime/validate-dsl-position-tracking.js +2 -1
- package/dist/runtime/validate-dsl-position-tracking.js.map +1 -1
- package/dist/runtime-api/handlers/ingest-signals.d.ts.map +1 -1
- package/dist/runtime-api/handlers/ingest-signals.js +1 -0
- package/dist/runtime-api/handlers/ingest-signals.js.map +1 -1
- package/dist/runtime-api/handlers/types.d.ts +5 -0
- package/dist/runtime-api/handlers/types.d.ts.map +1 -1
- package/dist/runtime-api/intake/ingest-request.d.ts +17 -0
- package/dist/runtime-api/intake/ingest-request.d.ts.map +1 -0
- package/dist/runtime-api/intake/ingest-request.js +34 -0
- package/dist/runtime-api/intake/ingest-request.js.map +1 -0
- package/dist/runtime-api/intake/intake-events.d.ts +1 -1
- package/dist/runtime-api/intake/intake-events.d.ts.map +1 -1
- package/dist/runtime-api/intake/intake-events.js +9 -3
- package/dist/runtime-api/intake/intake-events.js.map +1 -1
- package/dist/runtime-api/intake/intake-mount.d.ts.map +1 -1
- package/dist/runtime-api/intake/intake-mount.js +4 -19
- package/dist/runtime-api/intake/intake-mount.js.map +1 -1
- package/dist/runtime-api/intake/process-error-post.d.ts +6 -1
- package/dist/runtime-api/intake/process-error-post.d.ts.map +1 -1
- package/dist/runtime-api/intake/process-error-post.js +5 -1
- package/dist/runtime-api/intake/process-error-post.js.map +1 -1
- package/dist/runtime-api/intake/process-signal-post.d.ts +7 -1
- package/dist/runtime-api/intake/process-signal-post.d.ts.map +1 -1
- package/dist/runtime-api/intake/process-signal-post.js +5 -0
- package/dist/runtime-api/intake/process-signal-post.js.map +1 -1
- package/dist/runtime-api/intake/scaffold-error-router.js.map +1 -1
- package/dist/runtime-api/intake/scaffold-tick-router.d.ts +39 -0
- package/dist/runtime-api/intake/scaffold-tick-router.d.ts.map +1 -0
- package/dist/runtime-api/intake/scaffold-tick-router.js +122 -0
- package/dist/runtime-api/intake/scaffold-tick-router.js.map +1 -0
- package/dist/runtime-api/intake/scanner-launcher.d.ts.map +1 -1
- package/dist/runtime-api/intake/scanner-launcher.js +15 -0
- package/dist/runtime-api/intake/scanner-launcher.js.map +1 -1
- package/dist/runtime-api/intake/types.d.ts +55 -0
- package/dist/runtime-api/intake/types.d.ts.map +1 -1
- package/dist/runtime-api/routes/signals.d.ts +2 -0
- package/dist/runtime-api/routes/signals.d.ts.map +1 -1
- package/dist/runtime-api/routes/signals.js +5 -1
- package/dist/runtime-api/routes/signals.js.map +1 -1
- package/dist/runtime-api/routes/signals.schema.d.ts +43 -0
- package/dist/runtime-api/routes/signals.schema.d.ts.map +1 -1
- package/dist/runtime-api/routes/signals.schema.js +43 -0
- package/dist/runtime-api/routes/signals.schema.js.map +1 -1
- package/dist/runtime-api/server.d.ts +7 -1
- package/dist/runtime-api/server.d.ts.map +1 -1
- package/dist/runtime-api/server.js +1 -0
- package/dist/runtime-api/server.js.map +1 -1
- package/dist/scanners/engine/engine.d.ts +22 -1
- package/dist/scanners/engine/engine.d.ts.map +1 -1
- package/dist/scanners/engine/engine.js +78 -11
- package/dist/scanners/engine/engine.js.map +1 -1
- package/dist/scanners/engine/lifecycle.d.ts +7 -1
- package/dist/scanners/engine/lifecycle.d.ts.map +1 -1
- package/dist/scanners/events.d.ts +4 -0
- package/dist/scanners/events.d.ts.map +1 -1
- package/dist/scanners/events.js +2 -0
- package/dist/scanners/events.js.map +1 -1
- package/dist/scanners/external/scaffold/delivery.py +194 -25
- package/dist/scanners/external/scaffold/scaffold.py +172 -31
- package/dist/scanners/external/scaffold/senpi_mcp.py +150 -8
- package/dist/scanners/external/scaffold/tick_facts.py +130 -0
- package/dist/scanners/external/scaffold/ulid.py +58 -0
- package/dist/scanners/external-scanner-receiver.d.ts +17 -0
- package/dist/scanners/external-scanner-receiver.d.ts.map +1 -1
- package/dist/scanners/external-scanner-receiver.js +8 -0
- package/dist/scanners/external-scanner-receiver.js.map +1 -1
- package/dist/scanners/runtime-module.d.ts +1 -0
- package/dist/scanners/runtime-module.d.ts.map +1 -1
- package/dist/scanners/runtime-module.js +66 -9
- package/dist/scanners/runtime-module.js.map +1 -1
- package/dist/telemetry/attributes.d.ts +20 -0
- package/dist/telemetry/attributes.d.ts.map +1 -1
- package/dist/telemetry/attributes.js +24 -0
- package/dist/telemetry/attributes.js.map +1 -1
- package/dist/telemetry/event-builders.d.ts +81 -6
- package/dist/telemetry/event-builders.d.ts.map +1 -1
- package/dist/telemetry/event-builders.js +141 -17
- package/dist/telemetry/event-builders.js.map +1 -1
- package/dist/telemetry/event-store.d.ts +6 -0
- package/dist/telemetry/event-store.d.ts.map +1 -1
- package/dist/telemetry/event-store.js +12 -8
- package/dist/telemetry/event-store.js.map +1 -1
- package/dist/telemetry/live-telemetry.d.ts +238 -0
- package/dist/telemetry/live-telemetry.d.ts.map +1 -0
- package/dist/telemetry/live-telemetry.js +853 -0
- package/dist/telemetry/live-telemetry.js.map +1 -0
- package/dist/telemetry/metrics.d.ts +14 -2
- package/dist/telemetry/metrics.d.ts.map +1 -1
- package/dist/telemetry/metrics.js +19 -4
- package/dist/telemetry/metrics.js.map +1 -1
- package/dist/telemetry/scanner-stats.d.ts +143 -0
- package/dist/telemetry/scanner-stats.d.ts.map +1 -0
- package/dist/telemetry/scanner-stats.js +426 -0
- package/dist/telemetry/scanner-stats.js.map +1 -0
- package/dist/telemetry/scanner-tick-feed.d.ts +87 -0
- package/dist/telemetry/scanner-tick-feed.d.ts.map +1 -0
- package/dist/telemetry/scanner-tick-feed.js +48 -0
- package/dist/telemetry/scanner-tick-feed.js.map +1 -0
- package/dist/telemetry/spans/redact-pii.d.ts.map +1 -1
- package/dist/telemetry/spans/redact-pii.js +18 -2
- package/dist/telemetry/spans/redact-pii.js.map +1 -1
- package/dist/telemetry/strategy-topology.d.ts +99 -0
- package/dist/telemetry/strategy-topology.d.ts.map +1 -0
- package/dist/telemetry/strategy-topology.js +93 -0
- package/dist/telemetry/strategy-topology.js.map +1 -0
- package/dist/telemetry/telemetry-publisher.d.ts +63 -0
- package/dist/telemetry/telemetry-publisher.d.ts.map +1 -0
- package/dist/telemetry/telemetry-publisher.js +229 -0
- package/dist/telemetry/telemetry-publisher.js.map +1 -0
- package/dist/telemetry/tick-frame.d.ts +212 -0
- package/dist/telemetry/tick-frame.d.ts.map +1 -0
- package/dist/telemetry/tick-frame.js +421 -0
- package/dist/telemetry/tick-frame.js.map +1 -0
- package/dist/telemetry/timeline-buffer.d.ts +95 -0
- package/dist/telemetry/timeline-buffer.d.ts.map +1 -0
- package/dist/telemetry/timeline-buffer.js +237 -0
- package/dist/telemetry/timeline-buffer.js.map +1 -0
- package/dist/telemetry/tracing.d.ts +9 -0
- package/dist/telemetry/tracing.d.ts.map +1 -1
- package/dist/telemetry/tracing.js +36 -0
- package/dist/telemetry/tracing.js.map +1 -1
- package/dist/types/dsl/index.d.ts +11 -0
- package/dist/types/dsl/index.d.ts.map +1 -1
- package/dist/types/scanner.d.ts +15 -0
- package/dist/types/scanner.d.ts.map +1 -1
- package/dist/utils/event-catalog.d.ts +166 -0
- package/dist/utils/event-catalog.d.ts.map +1 -1
- package/dist/utils/event-catalog.js +18 -0
- package/dist/utils/event-catalog.js.map +1 -1
- package/dist/utils/logger.d.ts +4 -1
- package/dist/utils/logger.d.ts.map +1 -1
- package/dist/utils/logger.js.map +1 -1
- package/dist/utils/telemetry-required-log.d.ts +60 -0
- package/dist/utils/telemetry-required-log.d.ts.map +1 -0
- package/dist/utils/telemetry-required-log.js +105 -0
- package/dist/utils/telemetry-required-log.js.map +1 -0
- package/dist/utils/ulid.d.ts +9 -0
- package/dist/utils/ulid.d.ts.map +1 -0
- package/dist/utils/ulid.js +43 -0
- package/dist/utils/ulid.js.map +1 -0
- package/dist/validate/recipe-checks.d.ts.map +1 -1
- package/dist/validate/recipe-checks.js +2 -2
- package/dist/validate/recipe-checks.js.map +1 -1
- package/openclaw.plugin.json +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"redact-pii.js","sourceRoot":"","sources":["../../../src/telemetry/spans/redact-pii.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"redact-pii.js","sourceRoot":"","sources":["../../../src/telemetry/spans/redact-pii.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Builder for the `plugin.senpi.strategies` payload — the topology view of the live telemetry
|
|
3
|
+
* stream: which strategies exist, whether each is up, how healthy it is, and which scanners it
|
|
4
|
+
* declares.
|
|
5
|
+
*
|
|
6
|
+
* Pure. Every fact arrives as an input, nothing is read from the registry or a runtime handle here,
|
|
7
|
+
* so the shape on the wire is testable without booting a runtime.
|
|
8
|
+
*
|
|
9
|
+
* Two properties this module exists to hold:
|
|
10
|
+
* - `status` distinguishes a runtime that is down from one that is up but has no live entry
|
|
11
|
+
* scanners. The second reads as healthy unless it is named, and it is not.
|
|
12
|
+
* - The raw scanner `config` never reaches the wire. It is an unbounded passthrough record and it
|
|
13
|
+
* has been through `resolveEnvInObject`, so it may hold resolved secrets. Only the declared,
|
|
14
|
+
* typed fields below are copied, each by name.
|
|
15
|
+
*/
|
|
16
|
+
import type { ComponentHealth } from "../health/types.js";
|
|
17
|
+
import type { RuntimeScanner } from "../runtime/runtime-schema.js";
|
|
18
|
+
/** Payload schema version. Bump when a field changes meaning, not when one is added. */
|
|
19
|
+
export declare const STRATEGY_TOPOLOGY_VERSION = 1;
|
|
20
|
+
/**
|
|
21
|
+
* `stopped` — no runtime handle.
|
|
22
|
+
* `running_no_entry_scanners` — up, but its declared external scanners never wired, so it produces
|
|
23
|
+
* no entry signals.
|
|
24
|
+
* `running` — up and wired.
|
|
25
|
+
*/
|
|
26
|
+
export type StrategyStatus = "running" | "stopped" | "running_no_entry_scanners";
|
|
27
|
+
/** Membership test satisfied by both a `Map` and a `Set` — the two shapes the plugin holds. */
|
|
28
|
+
export interface IdMembership {
|
|
29
|
+
has(id: string): boolean;
|
|
30
|
+
}
|
|
31
|
+
/** Engine registration facts for one scanner. Absent when the runtime has no live handle. */
|
|
32
|
+
export interface TopologyScannerRegistration {
|
|
33
|
+
enabled: boolean;
|
|
34
|
+
scheduleMode: "interval" | "external";
|
|
35
|
+
intervalSeconds: number | null;
|
|
36
|
+
configVersion: number | null;
|
|
37
|
+
}
|
|
38
|
+
export interface TopologyScannerSource {
|
|
39
|
+
/**
|
|
40
|
+
* The parsed YAML scanner entry. Only `name`, `type`, `interval_seconds` and
|
|
41
|
+
* `signal_data_schema` are ever read from it — `config`, `advanced`, `inputs` and any
|
|
42
|
+
* passthrough key stay off the wire.
|
|
43
|
+
*/
|
|
44
|
+
entry: RuntimeScanner;
|
|
45
|
+
registration?: TopologyScannerRegistration;
|
|
46
|
+
}
|
|
47
|
+
export interface TopologyStrategySource {
|
|
48
|
+
runtimeId: string;
|
|
49
|
+
/** The config wallet as written. Normalized to the wire form by the builder — see below. */
|
|
50
|
+
address: string;
|
|
51
|
+
name: string;
|
|
52
|
+
scanners: TopologyScannerSource[];
|
|
53
|
+
}
|
|
54
|
+
/** The slice of `RuntimeHealthStatus` the topology reads. `startedAt` is ISO, as health emits it. */
|
|
55
|
+
export interface RuntimeHealthLike {
|
|
56
|
+
health: ComponentHealth;
|
|
57
|
+
startedAt?: string;
|
|
58
|
+
}
|
|
59
|
+
export interface BuildStrategyTopologyInput {
|
|
60
|
+
/** The buffer's epoch ULID. A change means the plugin restarted. */
|
|
61
|
+
epoch: string;
|
|
62
|
+
strategies: TopologyStrategySource[];
|
|
63
|
+
/** Runtimes holding a live handle. Everything else is stopped. */
|
|
64
|
+
runningRuntimeIds: IdMembership;
|
|
65
|
+
/** Runtimes that are up but whose entry scanners never wired. */
|
|
66
|
+
unwiredRuntimeIds: IdMembership;
|
|
67
|
+
/** Per-runtime health lookup, keyed on `runtimeId` the way `senpi.getHealthStatus` keys. */
|
|
68
|
+
readHealth?: (runtimeId: string) => RuntimeHealthLike | undefined;
|
|
69
|
+
/** Injectable clock for deterministic tests. */
|
|
70
|
+
now?: () => number;
|
|
71
|
+
}
|
|
72
|
+
export interface StrategyTopologyScanner {
|
|
73
|
+
/** The engine id — the YAML `name:` field. Unique within a runtime, not across runtimes. */
|
|
74
|
+
scannerId: string;
|
|
75
|
+
scheduleMode: "interval" | "external";
|
|
76
|
+
enabled: boolean;
|
|
77
|
+
intervalSeconds: number | null;
|
|
78
|
+
configVersion: number | null;
|
|
79
|
+
signalDataSchema: Record<string, unknown> | null;
|
|
80
|
+
}
|
|
81
|
+
export interface StrategyTopologyEntry {
|
|
82
|
+
runtimeId: string;
|
|
83
|
+
address: string;
|
|
84
|
+
name: string;
|
|
85
|
+
status: StrategyStatus;
|
|
86
|
+
health: ComponentHealth;
|
|
87
|
+
/** Epoch ms, converted from health's ISO stamp; null when health is unavailable. */
|
|
88
|
+
startedAt: number | null;
|
|
89
|
+
scanners: StrategyTopologyScanner[];
|
|
90
|
+
}
|
|
91
|
+
export interface StrategyTopologyPayload {
|
|
92
|
+
v: number;
|
|
93
|
+
epoch: string;
|
|
94
|
+
generatedAt: number;
|
|
95
|
+
strategies: StrategyTopologyEntry[];
|
|
96
|
+
}
|
|
97
|
+
/** Builds one `plugin.senpi.strategies` payload from an already-gathered set of facts. */
|
|
98
|
+
export declare function buildStrategyTopology(input: BuildStrategyTopologyInput): StrategyTopologyPayload;
|
|
99
|
+
//# sourceMappingURL=strategy-topology.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"strategy-topology.d.ts","sourceRoot":"","sources":["../../src/telemetry/strategy-topology.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAIH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAInE,wFAAwF;AACxF,eAAO,MAAM,yBAAyB,IAAI,CAAC;AAE3C;;;;;GAKG;AACH,MAAM,MAAM,cAAc,GAAG,SAAS,GAAG,SAAS,GAAG,2BAA2B,CAAC;AAEjF,+FAA+F;AAC/F,MAAM,WAAW,YAAY;IAC3B,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC;CAC1B;AAED,6FAA6F;AAC7F,MAAM,WAAW,2BAA2B;IAC1C,OAAO,EAAE,OAAO,CAAC;IACjB,YAAY,EAAE,UAAU,GAAG,UAAU,CAAC;IACtC,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B;AAED,MAAM,WAAW,qBAAqB;IACpC;;;;OAIG;IACH,KAAK,EAAE,cAAc,CAAC;IACtB,YAAY,CAAC,EAAE,2BAA2B,CAAC;CAC5C;AAED,MAAM,WAAW,sBAAsB;IACrC,SAAS,EAAE,MAAM,CAAC;IAClB,4FAA4F;IAC5F,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,qBAAqB,EAAE,CAAC;CACnC;AAED,qGAAqG;AACrG,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,eAAe,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,0BAA0B;IACzC,oEAAoE;IACpE,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,sBAAsB,EAAE,CAAC;IACrC,kEAAkE;IAClE,iBAAiB,EAAE,YAAY,CAAC;IAChC,iEAAiE;IACjE,iBAAiB,EAAE,YAAY,CAAC;IAChC,4FAA4F;IAC5F,UAAU,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,iBAAiB,GAAG,SAAS,CAAC;IAClE,gDAAgD;IAChD,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,uBAAuB;IACtC,4FAA4F;IAC5F,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,UAAU,GAAG,UAAU,CAAC;IACtC,OAAO,EAAE,OAAO,CAAC;IACjB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;CAClD;AAED,MAAM,WAAW,qBAAqB;IACpC,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,cAAc,CAAC;IACvB,MAAM,EAAE,eAAe,CAAC;IACxB,oFAAoF;IACpF,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,QAAQ,EAAE,uBAAuB,EAAE,CAAC;CACrC;AAED,MAAM,WAAW,uBAAuB;IACtC,CAAC,EAAE,MAAM,CAAC;IACV,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,qBAAqB,EAAE,CAAC;CACrC;AAwDD,0FAA0F;AAC1F,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,0BAA0B,GAChC,uBAAuB,CAwBzB"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Builder for the `plugin.senpi.strategies` payload — the topology view of the live telemetry
|
|
3
|
+
* stream: which strategies exist, whether each is up, how healthy it is, and which scanners it
|
|
4
|
+
* declares.
|
|
5
|
+
*
|
|
6
|
+
* Pure. Every fact arrives as an input, nothing is read from the registry or a runtime handle here,
|
|
7
|
+
* so the shape on the wire is testable without booting a runtime.
|
|
8
|
+
*
|
|
9
|
+
* Two properties this module exists to hold:
|
|
10
|
+
* - `status` distinguishes a runtime that is down from one that is up but has no live entry
|
|
11
|
+
* scanners. The second reads as healthy unless it is named, and it is not.
|
|
12
|
+
* - The raw scanner `config` never reaches the wire. It is an unbounded passthrough record and it
|
|
13
|
+
* has been through `resolveEnvInObject`, so it may hold resolved secrets. Only the declared,
|
|
14
|
+
* typed fields below are copied, each by name.
|
|
15
|
+
*/
|
|
16
|
+
import { createLogger } from "../utils/logger.js";
|
|
17
|
+
import { normalizeStrategyAddress } from "./event-store.js";
|
|
18
|
+
const logger = createLogger("[senpi-core][strategy-topology]");
|
|
19
|
+
/** Payload schema version. Bump when a field changes meaning, not when one is added. */
|
|
20
|
+
export const STRATEGY_TOPOLOGY_VERSION = 1;
|
|
21
|
+
/**
|
|
22
|
+
* Mirrors the three-way distinction `senpi.listRuntimes` draws: no handle is stopped, a handle in
|
|
23
|
+
* the unwired set is running blind, anything else is running. The wire carries the machine token —
|
|
24
|
+
* the operator-facing string is the frontend's to choose.
|
|
25
|
+
*/
|
|
26
|
+
function resolveStatus(runtimeId, running, unwired) {
|
|
27
|
+
if (!running.has(runtimeId))
|
|
28
|
+
return "stopped";
|
|
29
|
+
return unwired.has(runtimeId) ? "running_no_entry_scanners" : "running";
|
|
30
|
+
}
|
|
31
|
+
/** Health is advisory here: a lookup that fails must degrade the row, never the payload. */
|
|
32
|
+
function resolveHealth(runtimeId, readHealth) {
|
|
33
|
+
let status;
|
|
34
|
+
try {
|
|
35
|
+
status = readHealth?.(runtimeId);
|
|
36
|
+
}
|
|
37
|
+
catch (err) {
|
|
38
|
+
logger.warn("strategy topology could not read runtime health; reporting unknown", err, {
|
|
39
|
+
runtimeId,
|
|
40
|
+
});
|
|
41
|
+
return { health: "unknown", startedAt: null };
|
|
42
|
+
}
|
|
43
|
+
if (!status)
|
|
44
|
+
return { health: "unknown", startedAt: null };
|
|
45
|
+
const parsed = status.startedAt === undefined ? NaN : Date.parse(status.startedAt);
|
|
46
|
+
return {
|
|
47
|
+
health: status.health,
|
|
48
|
+
startedAt: Number.isFinite(parsed) ? parsed : null,
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Copies the declared scanner fields one by one. Never spread `entry` and never copy `config` —
|
|
53
|
+
* see the module note.
|
|
54
|
+
*/
|
|
55
|
+
function buildScanner(source) {
|
|
56
|
+
const { entry, registration } = source;
|
|
57
|
+
const declaredSchema = entry.signal_data_schema;
|
|
58
|
+
return {
|
|
59
|
+
scannerId: entry.name,
|
|
60
|
+
scheduleMode: registration?.scheduleMode ?? (entry.type === "external_scanner" ? "external" : "interval"),
|
|
61
|
+
enabled: registration?.enabled ?? true,
|
|
62
|
+
intervalSeconds: registration?.intervalSeconds ?? entry.interval_seconds ?? null,
|
|
63
|
+
configVersion: registration?.configVersion ?? null,
|
|
64
|
+
signalDataSchema: declaredSchema ?? null,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
/** Builds one `plugin.senpi.strategies` payload from an already-gathered set of facts. */
|
|
68
|
+
export function buildStrategyTopology(input) {
|
|
69
|
+
const now = input.now ?? Date.now;
|
|
70
|
+
const strategies = input.strategies.map((source) => {
|
|
71
|
+
const { health, startedAt } = resolveHealth(source.runtimeId, input.readHealth);
|
|
72
|
+
return {
|
|
73
|
+
runtimeId: source.runtimeId,
|
|
74
|
+
// `(address, scannerId)` is the join key across all four payloads, and the other three
|
|
75
|
+
// normalize their own address input. A checksummed EIP-55 wallet reaching the wire raw would
|
|
76
|
+
// spell this strategy differently from its own scanner rows and timeline rows, and nothing
|
|
77
|
+
// downstream rejects that — the join just returns nothing.
|
|
78
|
+
address: normalizeStrategyAddress(source.address),
|
|
79
|
+
name: source.name,
|
|
80
|
+
status: resolveStatus(source.runtimeId, input.runningRuntimeIds, input.unwiredRuntimeIds),
|
|
81
|
+
health,
|
|
82
|
+
startedAt,
|
|
83
|
+
scanners: source.scanners.map(buildScanner),
|
|
84
|
+
};
|
|
85
|
+
});
|
|
86
|
+
return {
|
|
87
|
+
v: STRATEGY_TOPOLOGY_VERSION,
|
|
88
|
+
epoch: input.epoch,
|
|
89
|
+
generatedAt: now(),
|
|
90
|
+
strategies,
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=strategy-topology.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"strategy-topology.js","sourceRoot":"","sources":["../../src/telemetry/strategy-topology.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The producer tap for the live telemetry stream: a second {@link EventSink} that copies selected
|
|
3
|
+
* `logger.event` records into the in-memory {@link TimelineBuffer} while the on-disk ring keeps
|
|
4
|
+
* receiving every one of them. It sits on the serial trading path, so it resolves the scanner id,
|
|
5
|
+
* picks a fixed set of fields, appends, and returns — no I/O, no await, no counting, no serialization.
|
|
6
|
+
*
|
|
7
|
+
* Two lists govern the stream, and this module owns only the first:
|
|
8
|
+
* - ADMISSION ({@link ADMITTED_EVENT_NAMES}) — what enters the buffer. Every name the timeline
|
|
9
|
+
* displays PLUS every name a counter is derived from, because a counting source that never enters
|
|
10
|
+
* the buffer makes the stats read zero with nothing logged anywhere.
|
|
11
|
+
* - PUBLICATION — what leaves on the timeline event. Applied at flush time, not here. Admission is
|
|
12
|
+
* deliberately the wider of the two: filtering for display at append time is unrecoverable.
|
|
13
|
+
*/
|
|
14
|
+
import { type EventName } from "../utils/event-catalog.js";
|
|
15
|
+
import { type EventSink } from "./event-store.js";
|
|
16
|
+
import { type TimelineBuffer } from "./timeline-buffer.js";
|
|
17
|
+
/**
|
|
18
|
+
* The names that may enter the buffer. Volume control for a bounded ring, so it is an allow-list of
|
|
19
|
+
* the strategy's own narrative: what its scanners did, what each signal became, what was traded, and
|
|
20
|
+
* why the strategy's status changed. It excludes the box-operations and agent-plane families —
|
|
21
|
+
* `auto_update.*`, `tool.*`, `tool_approval.*`, the installer and state/mcp faults — and the
|
|
22
|
+
* mechanical, poll-frequency records (`dsl.sl_updated`, `dsl.close_pending`, `dsl.close_attempt`,
|
|
23
|
+
* `dsl.price_fetch_stale`), which would evict a strategy's recent window without adding a line
|
|
24
|
+
* anyone reads.
|
|
25
|
+
*
|
|
26
|
+
* Typed as `EventName`, so renaming a catalog entry out from under this list is a compile error
|
|
27
|
+
* rather than a silently empty counter.
|
|
28
|
+
*/
|
|
29
|
+
export declare const ADMITTED_EVENT_NAMES: ReadonlySet<EventName>;
|
|
30
|
+
/**
|
|
31
|
+
* What the tap cost, in nanoseconds, since the last read. Two plain numbers and a maximum — no span,
|
|
32
|
+
* no histogram, no allocation: a span per event is exactly the blocking cost the buffer exists to
|
|
33
|
+
* avoid, and this sits on the same serial trading path the records describe.
|
|
34
|
+
*/
|
|
35
|
+
export interface TapCounters {
|
|
36
|
+
/** Tap invocations, admitted or not: the admission check is cost the trading path already paid. */
|
|
37
|
+
calls: number;
|
|
38
|
+
nsTotal: number;
|
|
39
|
+
/** The longest single call. An average hides the one append that had to evict. */
|
|
40
|
+
nsMax: number;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Take the window and zero it. The reader owns the window: a counter that is never reset reports a
|
|
44
|
+
* lifetime total forever, which sizes nothing. Process-wide, like the buffer the tap feeds.
|
|
45
|
+
*/
|
|
46
|
+
export declare function readAndResetTapCounters(): TapCounters;
|
|
47
|
+
export interface TelemetryPublisherOptions {
|
|
48
|
+
/** Buffer to feed. Defaults to the process buffer — one per process, shared by every address. */
|
|
49
|
+
buffer?: TimelineBuffer;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* A sink that copies admitted records into the timeline buffer under `address`. One instance per
|
|
53
|
+
* registered address; every instance writes into the same process buffer, which is what makes the
|
|
54
|
+
* publisher process-wide and address-partitioned rather than per-runtime.
|
|
55
|
+
*/
|
|
56
|
+
export declare function createTelemetryPublisherSink(address: string, options?: TelemetryPublisherOptions): EventSink;
|
|
57
|
+
/**
|
|
58
|
+
* One sink that feeds several. `registerEventSink` keys a single sink per address, so this is how
|
|
59
|
+
* the publisher rides alongside the on-disk ring instead of replacing it. Each branch already
|
|
60
|
+
* swallows its own failures; the loop keeps one branch's throw from starving the rest regardless.
|
|
61
|
+
*/
|
|
62
|
+
export declare function createFanOutEventSink(sinks: readonly EventSink[]): EventSink;
|
|
63
|
+
//# sourceMappingURL=telemetry-publisher.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"telemetry-publisher.d.ts","sourceRoot":"","sources":["../../src/telemetry/telemetry-publisher.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAA8B,KAAK,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAEvF,OAAO,EAA4B,KAAK,SAAS,EAAoB,MAAM,kBAAkB,CAAC;AAC9F,OAAO,EAAqB,KAAK,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAS9E;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,oBAAoB,EAAE,WAAW,CAAC,SAAS,CAqDtD,CAAC;AAEH;;;;GAIG;AACH,MAAM,WAAW,WAAW;IAC1B,mGAAmG;IACnG,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,kFAAkF;IAClF,KAAK,EAAE,MAAM,CAAC;CACf;AAMD;;;GAGG;AACH,wBAAgB,uBAAuB,IAAI,WAAW,CAMrD;AASD,MAAM,WAAW,yBAAyB;IACxC,iGAAiG;IACjG,MAAM,CAAC,EAAE,cAAc,CAAC;CACzB;AAqCD;;;;GAIG;AACH,wBAAgB,4BAA4B,CAC1C,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,yBAA8B,GACtC,SAAS,CAkDX;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,SAAS,SAAS,EAAE,GAAG,SAAS,CAuB5E"}
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The producer tap for the live telemetry stream: a second {@link EventSink} that copies selected
|
|
3
|
+
* `logger.event` records into the in-memory {@link TimelineBuffer} while the on-disk ring keeps
|
|
4
|
+
* receiving every one of them. It sits on the serial trading path, so it resolves the scanner id,
|
|
5
|
+
* picks a fixed set of fields, appends, and returns — no I/O, no await, no counting, no serialization.
|
|
6
|
+
*
|
|
7
|
+
* Two lists govern the stream, and this module owns only the first:
|
|
8
|
+
* - ADMISSION ({@link ADMITTED_EVENT_NAMES}) — what enters the buffer. Every name the timeline
|
|
9
|
+
* displays PLUS every name a counter is derived from, because a counting source that never enters
|
|
10
|
+
* the buffer makes the stats read zero with nothing logged anywhere.
|
|
11
|
+
* - PUBLICATION — what leaves on the timeline event. Applied at flush time, not here. Admission is
|
|
12
|
+
* deliberately the wider of the two: filtering for display at append time is unrecoverable.
|
|
13
|
+
*/
|
|
14
|
+
import { EVENT_NAME } from "../utils/event-catalog.js";
|
|
15
|
+
import { createLogger } from "../utils/logger.js";
|
|
16
|
+
import { normalizeStrategyAddress } from "./event-store.js";
|
|
17
|
+
import { getTimelineBuffer } from "./timeline-buffer.js";
|
|
18
|
+
const logger = createLogger("[senpi-core][telemetry-publisher]");
|
|
19
|
+
/** The scanner's STABLE id. Carried by every event whose `senpi.scanner.id` is ephemeral. */
|
|
20
|
+
const SCANNER_NAME_ATTR = "senpi.scanner.name";
|
|
21
|
+
/** Stable on `signal.outcome` and `scanner.summary`; the ephemeral per-launch id everywhere else. */
|
|
22
|
+
const SCANNER_ID_ATTR = "senpi.scanner.id";
|
|
23
|
+
/**
|
|
24
|
+
* The names that may enter the buffer. Volume control for a bounded ring, so it is an allow-list of
|
|
25
|
+
* the strategy's own narrative: what its scanners did, what each signal became, what was traded, and
|
|
26
|
+
* why the strategy's status changed. It excludes the box-operations and agent-plane families —
|
|
27
|
+
* `auto_update.*`, `tool.*`, `tool_approval.*`, the installer and state/mcp faults — and the
|
|
28
|
+
* mechanical, poll-frequency records (`dsl.sl_updated`, `dsl.close_pending`, `dsl.close_attempt`,
|
|
29
|
+
* `dsl.price_fetch_stale`), which would evict a strategy's recent window without adding a line
|
|
30
|
+
* anyone reads.
|
|
31
|
+
*
|
|
32
|
+
* Typed as `EventName`, so renaming a catalog entry out from under this list is a compile error
|
|
33
|
+
* rather than a silently empty counter.
|
|
34
|
+
*/
|
|
35
|
+
export const ADMITTED_EVENT_NAMES = new Set([
|
|
36
|
+
// Counting sources. `opens` and `skips` come from `signal.outcome`, `errors` from the two
|
|
37
|
+
// `scaffold.tick_*` names. These four are load-bearing, not display-driven.
|
|
38
|
+
EVENT_NAME.signalOutcome,
|
|
39
|
+
EVENT_NAME.decisionMade,
|
|
40
|
+
EVENT_NAME.scaffoldTickError,
|
|
41
|
+
EVENT_NAME.scaffoldTickTimeout,
|
|
42
|
+
// Scanner run and health: the per-run heartbeat plus every supervisor transition behind a
|
|
43
|
+
// scanner's health, degraded reason and restart count.
|
|
44
|
+
EVENT_NAME.scannerSummary,
|
|
45
|
+
EVENT_NAME.scannerSpawned,
|
|
46
|
+
EVENT_NAME.scannerExited,
|
|
47
|
+
EVENT_NAME.scannerRestarted,
|
|
48
|
+
EVENT_NAME.scannerDegraded,
|
|
49
|
+
EVENT_NAME.scannerRecovered,
|
|
50
|
+
EVENT_NAME.scannerSilenceKilled,
|
|
51
|
+
EVENT_NAME.scannerLaunchFailed,
|
|
52
|
+
// Signal intake: what arrived and what was dropped before an action ever evaluated it.
|
|
53
|
+
EVENT_NAME.signalAccepted,
|
|
54
|
+
EVENT_NAME.signalRejected,
|
|
55
|
+
EVENT_NAME.signalExpired,
|
|
56
|
+
EVENT_NAME.signalSuperseded,
|
|
57
|
+
// Execution: the order and position story behind an accepted signal.
|
|
58
|
+
EVENT_NAME.orderPlaced,
|
|
59
|
+
EVENT_NAME.orderFilled,
|
|
60
|
+
EVENT_NAME.orderFailed,
|
|
61
|
+
EVENT_NAME.positionOpened,
|
|
62
|
+
EVENT_NAME.positionClosed,
|
|
63
|
+
EVENT_NAME.positionIncreased,
|
|
64
|
+
EVENT_NAME.positionDecreased,
|
|
65
|
+
EVENT_NAME.positionFlipped,
|
|
66
|
+
EVENT_NAME.positionReconciled,
|
|
67
|
+
// Exit engine: the state changes of an armed exit, not its per-tick floor arithmetic.
|
|
68
|
+
EVENT_NAME.dslCreated,
|
|
69
|
+
EVENT_NAME.dslPhaseChanged,
|
|
70
|
+
EVENT_NAME.dslTierAdvanced,
|
|
71
|
+
EVENT_NAME.dslClosed,
|
|
72
|
+
EVENT_NAME.dslDeleted,
|
|
73
|
+
EVENT_NAME.dslSlSyncFailed,
|
|
74
|
+
EVENT_NAME.dslHandoffFailed,
|
|
75
|
+
// Strategy status, and the two faults that explain a strategy that is up but not trading.
|
|
76
|
+
EVENT_NAME.runtimeStarted,
|
|
77
|
+
EVENT_NAME.runtimeStopped,
|
|
78
|
+
EVENT_NAME.runtimePaused,
|
|
79
|
+
EVENT_NAME.runtimeResumed,
|
|
80
|
+
EVENT_NAME.runtimeError,
|
|
81
|
+
EVENT_NAME.runtimeQueueBackpressure,
|
|
82
|
+
EVENT_NAME.runtimeScannersUnwired,
|
|
83
|
+
]);
|
|
84
|
+
let tapCalls = 0;
|
|
85
|
+
let tapNsTotal = 0;
|
|
86
|
+
let tapNsMax = 0;
|
|
87
|
+
/**
|
|
88
|
+
* Take the window and zero it. The reader owns the window: a counter that is never reset reports a
|
|
89
|
+
* lifetime total forever, which sizes nothing. Process-wide, like the buffer the tap feeds.
|
|
90
|
+
*/
|
|
91
|
+
export function readAndResetTapCounters() {
|
|
92
|
+
const window = { calls: tapCalls, nsTotal: tapNsTotal, nsMax: tapNsMax };
|
|
93
|
+
tapCalls = 0;
|
|
94
|
+
tapNsTotal = 0;
|
|
95
|
+
tapNsMax = 0;
|
|
96
|
+
return window;
|
|
97
|
+
}
|
|
98
|
+
function noteTapCall(startedAt) {
|
|
99
|
+
const ns = Number(process.hrtime.bigint() - startedAt);
|
|
100
|
+
tapCalls += 1;
|
|
101
|
+
tapNsTotal += ns;
|
|
102
|
+
if (ns > tapNsMax)
|
|
103
|
+
tapNsMax = ns;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* The scanner this record belongs to. The name attribute wins: `senpi.scanner.id` carries a
|
|
107
|
+
* per-launch id on the intake, scaffold and supervisor events, so reading it unqualified files one
|
|
108
|
+
* scanner under a new key on every external-scanner restart. Absent — never empty — when the record
|
|
109
|
+
* has no scanner at all; the record is still buffered and the client buckets it as unattributed.
|
|
110
|
+
*/
|
|
111
|
+
function resolveScannerId(attrs) {
|
|
112
|
+
const name = attrs[SCANNER_NAME_ATTR];
|
|
113
|
+
if (typeof name === "string" && name !== "")
|
|
114
|
+
return name;
|
|
115
|
+
const id = attrs[SCANNER_ID_ATTR];
|
|
116
|
+
return typeof id === "string" && id !== "" ? id : undefined;
|
|
117
|
+
}
|
|
118
|
+
function isScalar(value) {
|
|
119
|
+
const t = typeof value;
|
|
120
|
+
return t === "string" || t === "number" || t === "boolean";
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* The bag minus any non-scalar value. Unlike the disk ring — which serializes and forgets — the
|
|
124
|
+
* buffer holds this reference for the whole retention window and then puts it on the wire, so a
|
|
125
|
+
* nested object would pin an arbitrary graph in memory and break the payload's scalar contract.
|
|
126
|
+
* The common case allocates nothing: a copy is made only once a bad value is actually seen.
|
|
127
|
+
*/
|
|
128
|
+
function scalarAttrs(attrs, onDropped) {
|
|
129
|
+
let clean = attrs;
|
|
130
|
+
for (const key of Object.keys(attrs)) {
|
|
131
|
+
if (isScalar(attrs[key]))
|
|
132
|
+
continue;
|
|
133
|
+
if (clean === attrs)
|
|
134
|
+
clean = { ...attrs };
|
|
135
|
+
delete clean[key];
|
|
136
|
+
onDropped();
|
|
137
|
+
}
|
|
138
|
+
return clean;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* A sink that copies admitted records into the timeline buffer under `address`. One instance per
|
|
142
|
+
* registered address; every instance writes into the same process buffer, which is what makes the
|
|
143
|
+
* publisher process-wide and address-partitioned rather than per-runtime.
|
|
144
|
+
*/
|
|
145
|
+
export function createTelemetryPublisherSink(address, options = {}) {
|
|
146
|
+
const bufferAddress = normalizeStrategyAddress(address);
|
|
147
|
+
// Reset on a later success so a transient failure can warn again if it recurs, but a persistently
|
|
148
|
+
// wedged buffer cannot spam a per-event warn on the trading path.
|
|
149
|
+
let warnedAppendFailure = false;
|
|
150
|
+
let warnedNonScalarAttr = false;
|
|
151
|
+
function noteNonScalarAttr(name) {
|
|
152
|
+
if (warnedNonScalarAttr)
|
|
153
|
+
return;
|
|
154
|
+
warnedNonScalarAttr = true;
|
|
155
|
+
logger.warn("telemetry publisher dropped a non-scalar event attribute", {
|
|
156
|
+
"senpi.event.name": name,
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
return {
|
|
160
|
+
append(event) {
|
|
161
|
+
// Measured in a `finally` so the rejected and the failed paths count too: they are the cheapest
|
|
162
|
+
// and the most expensive calls the trading path makes, and an average of neither is honest.
|
|
163
|
+
const startedAt = process.hrtime.bigint();
|
|
164
|
+
try {
|
|
165
|
+
if (!ADMITTED_EVENT_NAMES.has(event.name))
|
|
166
|
+
return;
|
|
167
|
+
const attrs = event.attrs ?? {};
|
|
168
|
+
// Named fields only: whatever else rides the record — a redact slot, resource attributes —
|
|
169
|
+
// is not copied because it is never read.
|
|
170
|
+
(options.buffer ?? getTimelineBuffer()).append({
|
|
171
|
+
ts: event.ts,
|
|
172
|
+
name: event.name,
|
|
173
|
+
level: event.level,
|
|
174
|
+
address: bufferAddress,
|
|
175
|
+
scannerId: resolveScannerId(attrs),
|
|
176
|
+
body: event.body,
|
|
177
|
+
attrs: scalarAttrs(attrs, () => noteNonScalarAttr(event.name)),
|
|
178
|
+
});
|
|
179
|
+
warnedAppendFailure = false;
|
|
180
|
+
}
|
|
181
|
+
catch (err) {
|
|
182
|
+
// The tap must never disturb the logging caller, and a wedged tap must not be silent.
|
|
183
|
+
if (!warnedAppendFailure) {
|
|
184
|
+
warnedAppendFailure = true;
|
|
185
|
+
logger.warn("telemetry publisher append failed; the live stream may be incomplete", {
|
|
186
|
+
address: bufferAddress,
|
|
187
|
+
err: err instanceof Error ? err.message : String(err),
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
finally {
|
|
192
|
+
noteTapCall(startedAt);
|
|
193
|
+
}
|
|
194
|
+
},
|
|
195
|
+
flush: () => Promise.resolve(),
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* One sink that feeds several. `registerEventSink` keys a single sink per address, so this is how
|
|
200
|
+
* the publisher rides alongside the on-disk ring instead of replacing it. Each branch already
|
|
201
|
+
* swallows its own failures; the loop keeps one branch's throw from starving the rest regardless.
|
|
202
|
+
*/
|
|
203
|
+
export function createFanOutEventSink(sinks) {
|
|
204
|
+
return {
|
|
205
|
+
append(event) {
|
|
206
|
+
for (const sink of sinks) {
|
|
207
|
+
try {
|
|
208
|
+
sink.append(event);
|
|
209
|
+
}
|
|
210
|
+
catch {
|
|
211
|
+
// A branch that breaks its own no-throw contract must not cost the others their record.
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
},
|
|
215
|
+
async flush() {
|
|
216
|
+
// Sequential and individually guarded: a graceful stop awaits this, so one branch's rejection
|
|
217
|
+
// must not skip another's drain or surface as a failed stop.
|
|
218
|
+
for (const sink of sinks) {
|
|
219
|
+
try {
|
|
220
|
+
await sink.flush();
|
|
221
|
+
}
|
|
222
|
+
catch {
|
|
223
|
+
// A branch that cannot drain has already reported it; the stop path carries on.
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
},
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
//# sourceMappingURL=telemetry-publisher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"telemetry-publisher.js","sourceRoot":"","sources":["../../src/telemetry/telemetry-publisher.ts"],"names":[],"mappings":"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"}
|