@brutalist/mcp 1.8.1 → 1.9.1
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/README.md +32 -0
- package/dist/brutalist-server.d.ts +31 -9
- package/dist/brutalist-server.d.ts.map +1 -1
- package/dist/brutalist-server.js +107 -673
- package/dist/brutalist-server.js.map +1 -1
- package/dist/cli-adapters/claude-adapter.d.ts +25 -0
- package/dist/cli-adapters/claude-adapter.d.ts.map +1 -0
- package/dist/cli-adapters/claude-adapter.js +245 -0
- package/dist/cli-adapters/claude-adapter.js.map +1 -0
- package/dist/cli-adapters/codex-adapter.d.ts +23 -0
- package/dist/cli-adapters/codex-adapter.d.ts.map +1 -0
- package/dist/cli-adapters/codex-adapter.js +173 -0
- package/dist/cli-adapters/codex-adapter.js.map +1 -0
- package/dist/cli-adapters/gemini-adapter.d.ts +50 -0
- package/dist/cli-adapters/gemini-adapter.d.ts.map +1 -0
- package/dist/cli-adapters/gemini-adapter.js +196 -0
- package/dist/cli-adapters/gemini-adapter.js.map +1 -0
- package/dist/cli-adapters/index.d.ts +75 -0
- package/dist/cli-adapters/index.d.ts.map +1 -0
- package/dist/cli-adapters/index.js +29 -0
- package/dist/cli-adapters/index.js.map +1 -0
- package/dist/cli-adapters/shared.d.ts +12 -0
- package/dist/cli-adapters/shared.d.ts.map +1 -0
- package/dist/cli-adapters/shared.js +99 -0
- package/dist/cli-adapters/shared.js.map +1 -0
- package/dist/cli-agents.d.ts +69 -2
- package/dist/cli-agents.d.ts.map +1 -1
- package/dist/cli-agents.js +358 -394
- package/dist/cli-agents.js.map +1 -1
- package/dist/debate/constitutional.d.ts +27 -0
- package/dist/debate/constitutional.d.ts.map +1 -0
- package/dist/debate/constitutional.js +74 -0
- package/dist/debate/constitutional.js.map +1 -0
- package/dist/debate/debate-orchestrator.d.ts +154 -0
- package/dist/debate/debate-orchestrator.d.ts.map +1 -0
- package/dist/debate/debate-orchestrator.js +699 -0
- package/dist/debate/debate-orchestrator.js.map +1 -0
- package/dist/debate/index.d.ts +18 -0
- package/dist/debate/index.d.ts.map +1 -0
- package/dist/debate/index.js +18 -0
- package/dist/debate/index.js.map +1 -0
- package/dist/debate/refusal-detection.d.ts +27 -0
- package/dist/debate/refusal-detection.d.ts.map +1 -0
- package/dist/debate/refusal-detection.js +62 -0
- package/dist/debate/refusal-detection.js.map +1 -0
- package/dist/debate/synthesis.d.ts +22 -0
- package/dist/debate/synthesis.d.ts.map +1 -0
- package/dist/debate/synthesis.js +117 -0
- package/dist/debate/synthesis.js.map +1 -0
- package/dist/logger.d.ts +204 -1
- package/dist/logger.d.ts.map +1 -1
- package/dist/logger.js +398 -18
- package/dist/logger.js.map +1 -1
- package/dist/metrics/counter.d.ts +24 -0
- package/dist/metrics/counter.d.ts.map +1 -0
- package/dist/metrics/counter.js +60 -0
- package/dist/metrics/counter.js.map +1 -0
- package/dist/metrics/histogram.d.ts +42 -0
- package/dist/metrics/histogram.d.ts.map +1 -0
- package/dist/metrics/histogram.js +114 -0
- package/dist/metrics/histogram.js.map +1 -0
- package/dist/metrics/index.d.ts +26 -0
- package/dist/metrics/index.d.ts.map +1 -0
- package/dist/metrics/index.js +22 -0
- package/dist/metrics/index.js.map +1 -0
- package/dist/metrics/registry.d.ts +96 -0
- package/dist/metrics/registry.d.ts.map +1 -0
- package/dist/metrics/registry.js +113 -0
- package/dist/metrics/registry.js.map +1 -0
- package/dist/metrics/safe-metric.d.ts +25 -0
- package/dist/metrics/safe-metric.d.ts.map +1 -0
- package/dist/metrics/safe-metric.js +41 -0
- package/dist/metrics/safe-metric.js.map +1 -0
- package/dist/metrics/types.d.ts +82 -0
- package/dist/metrics/types.d.ts.map +1 -0
- package/dist/metrics/types.js +121 -0
- package/dist/metrics/types.js.map +1 -0
- package/dist/registry/argument-spaces.d.ts.map +1 -1
- package/dist/registry/argument-spaces.js +20 -0
- package/dist/registry/argument-spaces.js.map +1 -1
- package/dist/registry/domains.d.ts.map +1 -1
- package/dist/registry/domains.js +17 -1
- package/dist/registry/domains.js.map +1 -1
- package/dist/streaming/circuit-breaker.d.ts +13 -1
- package/dist/streaming/circuit-breaker.d.ts.map +1 -1
- package/dist/streaming/circuit-breaker.js +13 -1
- package/dist/streaming/circuit-breaker.js.map +1 -1
- package/dist/streaming/intelligent-buffer.d.ts +13 -1
- package/dist/streaming/intelligent-buffer.d.ts.map +1 -1
- package/dist/streaming/intelligent-buffer.js +13 -1
- package/dist/streaming/intelligent-buffer.js.map +1 -1
- package/dist/streaming/output-parser.d.ts +16 -2
- package/dist/streaming/output-parser.d.ts.map +1 -1
- package/dist/streaming/output-parser.js +16 -2
- package/dist/streaming/output-parser.js.map +1 -1
- package/dist/streaming/progress-tracker.d.ts +14 -1
- package/dist/streaming/progress-tracker.d.ts.map +1 -1
- package/dist/streaming/progress-tracker.js +14 -1
- package/dist/streaming/progress-tracker.js.map +1 -1
- package/dist/streaming/session-manager.d.ts +14 -1
- package/dist/streaming/session-manager.d.ts.map +1 -1
- package/dist/streaming/session-manager.js +14 -1
- package/dist/streaming/session-manager.js.map +1 -1
- package/dist/streaming/sse-transport.d.ts +12 -1
- package/dist/streaming/sse-transport.d.ts.map +1 -1
- package/dist/streaming/sse-transport.js +12 -1
- package/dist/streaming/sse-transport.js.map +1 -1
- package/dist/streaming/streaming-orchestrator.d.ts +15 -1
- package/dist/streaming/streaming-orchestrator.d.ts.map +1 -1
- package/dist/streaming/streaming-orchestrator.js +15 -1
- package/dist/streaming/streaming-orchestrator.js.map +1 -1
- package/dist/system-prompts.d.ts.map +1 -1
- package/dist/system-prompts.js +490 -4
- package/dist/system-prompts.js.map +1 -1
- package/dist/tool-definitions-generated.d.ts.map +1 -1
- package/dist/tool-definitions-generated.js +3 -1
- package/dist/tool-definitions-generated.js.map +1 -1
- package/package.json +1 -1
package/dist/logger.js
CHANGED
|
@@ -21,9 +21,147 @@ import { homedir } from 'os';
|
|
|
21
21
|
* BRUTALIST_LOG_MAX_SIZE – max MB per file (default 5)
|
|
22
22
|
* BRUTALIST_LOG_MAX_FILES – rotated files to keep (default 3)
|
|
23
23
|
* BRUTALIST_LOG_LEVEL – minimum file log level (default "info")
|
|
24
|
+
*
|
|
25
|
+
* Structured fields (intents.md #3):
|
|
26
|
+
* Every call carries {ts, level, msg, pid}. Callers that use
|
|
27
|
+
* `logger.for({module, operation})` additionally bind `module` and
|
|
28
|
+
* `operation` so records are queryable by subsystem without reading
|
|
29
|
+
* source. Base methods remain source-compatible with pre-migration
|
|
30
|
+
* call sites — module/operation are simply absent on unbound calls.
|
|
24
31
|
*/
|
|
25
32
|
const LOG_LEVELS = { debug: 0, info: 1, warn: 2, error: 3 };
|
|
26
33
|
const LOG_FILENAME = 'brutalist.log';
|
|
34
|
+
/** Max length for sanitized scope fields on the stderr prefix (RL4). */
|
|
35
|
+
const STDERR_SCOPE_MAX_LEN = 64;
|
|
36
|
+
/** Placeholder written when JSON serialization throws (RL3). */
|
|
37
|
+
const UNSERIALIZABLE_PLACEHOLDER = '[unserializable]';
|
|
38
|
+
/**
|
|
39
|
+
* Safely stringify arbitrary user-supplied data. JSON.stringify throws on
|
|
40
|
+
* circular structures and on objects with toJSON methods that throw —
|
|
41
|
+
* callers into the logger must never have their requests killed by a
|
|
42
|
+
* logging call, so on failure we fall back to a stable placeholder.
|
|
43
|
+
*
|
|
44
|
+
* Used for stderr payload rendering (RL3). The NDJSON file path already
|
|
45
|
+
* wraps JSON.stringify in the writeToFile try/catch block.
|
|
46
|
+
*/
|
|
47
|
+
function safeStringify(value) {
|
|
48
|
+
try {
|
|
49
|
+
return JSON.stringify(value);
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
return UNSERIALIZABLE_PLACEHOLDER;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Sanitize a scope field (module/operation) for stderr interpolation (RL4).
|
|
57
|
+
*
|
|
58
|
+
* Callers of the logger can pass attacker-influenced strings into module
|
|
59
|
+
* or operation (tool names, provider IDs, error categories bound at
|
|
60
|
+
* integration time). The stderr layout `[BRUTALIST MCP] LEVEL [m/o]:`
|
|
61
|
+
* is a flat line format, so a `\n` in a scope field forges a second
|
|
62
|
+
* log record, a `\x1b` injects ANSI escapes, and `]` breaks the
|
|
63
|
+
* delimiter. This function strips/escapes those characters and caps
|
|
64
|
+
* length to bound the attack surface.
|
|
65
|
+
*
|
|
66
|
+
* Applied ONLY at the stderr emission path — the NDJSON file record
|
|
67
|
+
* preserves the original unescaped values because JSON.stringify
|
|
68
|
+
* already escapes control characters safely.
|
|
69
|
+
*
|
|
70
|
+
* RL4-extension (Cycle 6): also escape C1 control chars (0x80–0x9f),
|
|
71
|
+
* notably U+009B CSI which some terminals interpret as an ANSI control
|
|
72
|
+
* introducer without a literal ESC byte.
|
|
73
|
+
*
|
|
74
|
+
* RL6 (Cycle 6): also escape `%`. The returned string becomes the first
|
|
75
|
+
* argument to `console.error`, which Node's `util.format` treats as a
|
|
76
|
+
* format string — `%j`/`%s`/`%d`/`%o` would consume subsequent
|
|
77
|
+
* arguments. Doubling `%` as `%%` is the standard `util.format` escape.
|
|
78
|
+
*
|
|
79
|
+
* RL7 (Cycle 6): defense-in-depth — accept null/undefined (returns '')
|
|
80
|
+
* so an upstream merge bug that propagates undefined through scope
|
|
81
|
+
* cannot crash the logger when the caller is in an error handler.
|
|
82
|
+
*/
|
|
83
|
+
function sanitizeScopeForStderr(value) {
|
|
84
|
+
// RL7: defense-in-depth null/undefined guard — never throw from inside
|
|
85
|
+
// the logger because of a bad scope field (loggers run in error handlers).
|
|
86
|
+
if (value == null)
|
|
87
|
+
return '';
|
|
88
|
+
// Replace CR, LF, tab, ESC, and other C0 control chars (0x00-0x1f, 0x7f)
|
|
89
|
+
// and C1 control chars (0x80-0x9f) plus the ']' delimiter and `%`. Using
|
|
90
|
+
// explicit replacements so escapes stay visible rather than silently
|
|
91
|
+
// dropped.
|
|
92
|
+
let sanitized = '';
|
|
93
|
+
for (const ch of value) {
|
|
94
|
+
const code = ch.charCodeAt(0);
|
|
95
|
+
if (ch === ']') {
|
|
96
|
+
sanitized += '\\]';
|
|
97
|
+
}
|
|
98
|
+
else if (ch === '%') {
|
|
99
|
+
// RL6: escape per util.format convention so the prefix string
|
|
100
|
+
// cannot be interpreted as a format spec when used as the first
|
|
101
|
+
// arg to console.error.
|
|
102
|
+
sanitized += '%%';
|
|
103
|
+
}
|
|
104
|
+
else if (code < 0x20 || code === 0x7f || (code >= 0x80 && code <= 0x9f)) {
|
|
105
|
+
// Escape as \xHH so operators can see what was there.
|
|
106
|
+
// C0 (0x00-0x1f), DEL (0x7f), and C1 (0x80-0x9f) all hex-escaped —
|
|
107
|
+
// C1 includes U+009B CSI which several terminals treat as an
|
|
108
|
+
// ANSI control introducer without a literal ESC.
|
|
109
|
+
sanitized += '\\x' + code.toString(16).padStart(2, '0');
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
sanitized += ch;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
if (sanitized.length > STDERR_SCOPE_MAX_LEN) {
|
|
116
|
+
sanitized = sanitized.slice(0, STDERR_SCOPE_MAX_LEN);
|
|
117
|
+
}
|
|
118
|
+
return sanitized;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Sanitize the caller-provided `message` and string error payloads before
|
|
122
|
+
* they hit `console.error` (RL5, Cycle 6).
|
|
123
|
+
*
|
|
124
|
+
* RL4 closed the scope-field injection vector at `stderrPrefix`, but the
|
|
125
|
+
* `message` argument restored by RL1 (and the string-error payload in
|
|
126
|
+
* `emitError`) is a parallel raw channel into stderr. Without
|
|
127
|
+
* sanitization, a `message` containing `\n[BRUTALIST MCP] ERROR ...`
|
|
128
|
+
* forges an additional stderr line that downstream log scrapers will
|
|
129
|
+
* parse as a separate record.
|
|
130
|
+
*
|
|
131
|
+
* Distinct from `sanitizeScopeForStderr`:
|
|
132
|
+
* - No length cap — messages are intentionally free-form text and
|
|
133
|
+
* operators rely on full-message visibility for triage.
|
|
134
|
+
* - No `]` escape — `]` is not a delimiter inside the message body.
|
|
135
|
+
* - No `%` escape — `message` is the SECOND console.error argument and
|
|
136
|
+
* is never treated as a format string (RL6 handles the prefix, which
|
|
137
|
+
* is the only arg position where util.format parses specifiers).
|
|
138
|
+
* - CR/LF replaced with visible `\n` / `\r` rather than `\xHH` because
|
|
139
|
+
* these are by far the most common chars in a message body and the
|
|
140
|
+
* short escape keeps the stderr line readable.
|
|
141
|
+
* - Other C0 controls and DEL hex-escaped; C1 controls hex-escaped
|
|
142
|
+
* (parity with `sanitizeScopeForStderr`).
|
|
143
|
+
*/
|
|
144
|
+
function sanitizeMessageForStderr(value) {
|
|
145
|
+
if (value == null)
|
|
146
|
+
return '';
|
|
147
|
+
let sanitized = '';
|
|
148
|
+
for (const ch of value) {
|
|
149
|
+
const code = ch.charCodeAt(0);
|
|
150
|
+
if (ch === '\n') {
|
|
151
|
+
sanitized += '\\n';
|
|
152
|
+
}
|
|
153
|
+
else if (ch === '\r') {
|
|
154
|
+
sanitized += '\\r';
|
|
155
|
+
}
|
|
156
|
+
else if (code < 0x20 || code === 0x7f || (code >= 0x80 && code <= 0x9f)) {
|
|
157
|
+
sanitized += '\\x' + code.toString(16).padStart(2, '0');
|
|
158
|
+
}
|
|
159
|
+
else {
|
|
160
|
+
sanitized += ch;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
return sanitized;
|
|
164
|
+
}
|
|
27
165
|
export class Logger {
|
|
28
166
|
static instance;
|
|
29
167
|
debugMode;
|
|
@@ -51,35 +189,191 @@ export class Logger {
|
|
|
51
189
|
// Public API — unchanged signatures, all call sites continue to work
|
|
52
190
|
// ---------------------------------------------------------------------------
|
|
53
191
|
info(message, data) {
|
|
54
|
-
|
|
55
|
-
this.writeToFile('info', message, data);
|
|
192
|
+
this.emit('info', message, data);
|
|
56
193
|
}
|
|
57
194
|
warn(message, data) {
|
|
58
|
-
|
|
59
|
-
this.writeToFile('warn', message, data);
|
|
195
|
+
this.emit('warn', message, data);
|
|
60
196
|
}
|
|
61
197
|
error(message, error) {
|
|
62
|
-
|
|
198
|
+
this.emitError(message, error);
|
|
199
|
+
}
|
|
200
|
+
debug(message, data) {
|
|
201
|
+
this.emit('debug', message, data);
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Produce a child logger that binds `module` and `operation` to every
|
|
205
|
+
* record it emits. Child loggers delegate to the same file + stderr
|
|
206
|
+
* pipeline as the root, so `BRUTALIST_LOG_LEVEL`, `DEBUG`, and
|
|
207
|
+
* `shutdown()` behavior are shared.
|
|
208
|
+
*
|
|
209
|
+
* Callers should bind once per subsystem scope (e.g., in a class
|
|
210
|
+
* constructor) and reuse the returned logger, rather than creating a
|
|
211
|
+
* new child per call.
|
|
212
|
+
*
|
|
213
|
+
* RL8 (Cycle 6): signature accepts `Partial<LogScope>` to match the
|
|
214
|
+
* `StructuredLogger` interface, but the root `Logger` has no parent
|
|
215
|
+
* scope to inherit from — both `module` and `operation` must be
|
|
216
|
+
* provided. A missing field throws so that an integration-phase
|
|
217
|
+
* caller cannot silently produce a child with `undefined` fields
|
|
218
|
+
* (which would defeat the structured-logging guarantee).
|
|
219
|
+
*/
|
|
220
|
+
for(scope) {
|
|
221
|
+
if (!scope.module || !scope.operation) {
|
|
222
|
+
throw new Error(`Logger.for() requires both module and operation at the root ` +
|
|
223
|
+
`(no parent scope to inherit from). Got module=${JSON.stringify(scope.module)} ` +
|
|
224
|
+
`operation=${JSON.stringify(scope.operation)}.`);
|
|
225
|
+
}
|
|
226
|
+
return new ScopedLogger(this, { module: scope.module, operation: scope.operation });
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Root-level `forOperation` is intentionally a thrower: there is no
|
|
230
|
+
* parent module to inherit from, so the resulting child would have
|
|
231
|
+
* `module=undefined`. Use `logger.for({ module, operation })` to bind
|
|
232
|
+
* the scope at the root and `child.forOperation(op)` thereafter.
|
|
233
|
+
*
|
|
234
|
+
* This exists on the interface (RL8) so that DI-typed dependencies
|
|
235
|
+
* can call `forOperation` after they have been narrowed once. Calling
|
|
236
|
+
* it on the bare root logger is a programming error.
|
|
237
|
+
*/
|
|
238
|
+
forOperation(_operation) {
|
|
239
|
+
throw new Error(`Logger.forOperation() cannot be called on the root logger — ` +
|
|
240
|
+
`bind a module first via logger.for({ module, operation }).`);
|
|
241
|
+
}
|
|
242
|
+
/** No-op kept for API compatibility. Writes are synchronous, nothing to flush. */
|
|
243
|
+
shutdown() {
|
|
244
|
+
// All writes use appendFileSync — every line is already on disk.
|
|
245
|
+
}
|
|
246
|
+
// ---------------------------------------------------------------------------
|
|
247
|
+
// Internal emit pipeline — shared by root methods and ScopedLogger
|
|
248
|
+
// ---------------------------------------------------------------------------
|
|
249
|
+
/**
|
|
250
|
+
* Emit a non-error record. Private so that the only externally visible
|
|
251
|
+
* methods keep their original signatures.
|
|
252
|
+
*
|
|
253
|
+
* Stderr layout (RL1): `{prefix} {message}` followed by the serialized
|
|
254
|
+
* data when present. The message text must appear on stderr — it is
|
|
255
|
+
* the guaranteed operational sink since file logging is opt-in via
|
|
256
|
+
* BRUTALIST_LOG_FILE=true.
|
|
257
|
+
*
|
|
258
|
+
* RL5/RL6 (Cycle 6): the prefix is sanitized for `%` (RL6) by
|
|
259
|
+
* `sanitizeScopeForStderr` so it cannot drive `util.format` substitution
|
|
260
|
+
* even though it is the first console.error argument. The caller-
|
|
261
|
+
* supplied `message` is sanitized via `sanitizeMessageForStderr`
|
|
262
|
+
* (RL5) so CR/LF in `message` cannot forge a second log line. The
|
|
263
|
+
* NDJSON file path receives the ORIGINAL `message` and `data`
|
|
264
|
+
* because JSON.stringify already escapes control chars safely.
|
|
265
|
+
*/
|
|
266
|
+
/** @internal */
|
|
267
|
+
emit(level, message, data, scope) {
|
|
268
|
+
const prefix = this.stderrPrefix(level, scope);
|
|
269
|
+
const safeMessage = sanitizeMessageForStderr(message);
|
|
270
|
+
// RL3: safeStringify guards against circular structures and toJSON
|
|
271
|
+
// throws. If data is absent we pass through the empty string to
|
|
272
|
+
// preserve the two-argument call shape tests assert against.
|
|
273
|
+
//
|
|
274
|
+
// RL9 (Cycle 8): JSON.stringify escapes C0 (0x00-0x1f) natively but
|
|
275
|
+
// does NOT escape C1 controls (0x80-0x9f) — those emit as raw UTF-8
|
|
276
|
+
// bytes. Several terminals interpret U+009B CSI as an ANSI control
|
|
277
|
+
// introducer without a literal ESC. Pipe the stringified payload
|
|
278
|
+
// through `sanitizeMessageForStderr` so C1 bytes are hex-escaped
|
|
279
|
+
// before they reach `console.error`. The NDJSON file path below
|
|
280
|
+
// still receives the ORIGINAL `data` object (unsanitized) — parity
|
|
281
|
+
// with the RL4/RL5 stderr-vs-file split: operators consume files
|
|
282
|
+
// with jq/grep, raw bytes are tool-safe there; stderr is the
|
|
283
|
+
// channel terminals render.
|
|
284
|
+
const payload = data !== undefined
|
|
285
|
+
? sanitizeMessageForStderr(safeStringify(data))
|
|
286
|
+
: '';
|
|
287
|
+
if (level === 'debug') {
|
|
288
|
+
if (this.debugMode) {
|
|
289
|
+
console.error(prefix, safeMessage, payload);
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
else {
|
|
293
|
+
console.error(prefix, safeMessage, payload);
|
|
294
|
+
}
|
|
295
|
+
this.writeToFile(level, message, data, scope);
|
|
296
|
+
}
|
|
297
|
+
/**
|
|
298
|
+
* Emit an error record. Splits stderr vs file formatting the same way
|
|
299
|
+
* the original `error()` did — Error instances get `.message` on
|
|
300
|
+
* stderr and the full shape in the NDJSON record.
|
|
301
|
+
*
|
|
302
|
+
* Stderr layout (RL1): `{prefix} {message} {error.message|payload}`.
|
|
303
|
+
* The caller-supplied `message` must appear alongside the error detail
|
|
304
|
+
* so the human-readable line is symmetric with emit().
|
|
305
|
+
*
|
|
306
|
+
* RL5 (Cycle 6): both the caller-supplied `message` and the string
|
|
307
|
+
* forms of the error payload (`Error.message` and string error
|
|
308
|
+
* arguments) are passed through `sanitizeMessageForStderr` before
|
|
309
|
+
* `console.error`. CR/LF in either field would otherwise forge a
|
|
310
|
+
* second stderr log line. Non-Error object payloads go through
|
|
311
|
+
* `safeStringify` (RL3) and JSON.stringify already escapes control
|
|
312
|
+
* chars, so they are stderr-safe without further sanitization.
|
|
313
|
+
*
|
|
314
|
+
* The file path (`writeToFile`) receives the ORIGINAL `message` and
|
|
315
|
+
* the structured `fileData` shape so NDJSON consumers see the raw
|
|
316
|
+
* values that were logged (JSON.stringify handles control char
|
|
317
|
+
* escaping safely on the file side).
|
|
318
|
+
*/
|
|
319
|
+
/** @internal */
|
|
320
|
+
emitError(message, error, scope) {
|
|
321
|
+
const prefix = this.stderrPrefix('error', scope);
|
|
322
|
+
// RL3: Error.message is always a string so JSON stringify is not
|
|
323
|
+
// invoked. For non-Error payloads we safeStringify defensively,
|
|
324
|
+
// since error?: any permits arbitrary user-supplied objects.
|
|
325
|
+
let errPayload;
|
|
326
|
+
if (error instanceof Error) {
|
|
327
|
+
// RL5: Error.message can carry user-controlled CR/LF (e.g., a
|
|
328
|
+
// remote API error message echoed back into an exception).
|
|
329
|
+
errPayload = sanitizeMessageForStderr(error.message);
|
|
330
|
+
}
|
|
331
|
+
else if (error === undefined) {
|
|
332
|
+
errPayload = '';
|
|
333
|
+
}
|
|
334
|
+
else if (typeof error === 'string') {
|
|
335
|
+
// RL5: string error payloads are also raw caller input.
|
|
336
|
+
errPayload = sanitizeMessageForStderr(error);
|
|
337
|
+
}
|
|
338
|
+
else {
|
|
339
|
+
// RL9 (Cycle 8): JSON.stringify escapes C0 but NOT C1 controls
|
|
340
|
+
// (0x80-0x9f). Non-Error object payloads reach stderr via
|
|
341
|
+
// safeStringify, so an attacker-controlled object field like
|
|
342
|
+
// { csi: '\u009b2J' } would render raw bytes that some
|
|
343
|
+
// terminals interpret as ANSI control introducers without a
|
|
344
|
+
// literal ESC. Pipe the JSON through `sanitizeMessageForStderr`
|
|
345
|
+
// to hex-escape C1 (and any stray C0/DEL) before the byte
|
|
346
|
+
// hits `console.error`. File-side NDJSON below still receives
|
|
347
|
+
// the ORIGINAL `fileData` object — stderr-vs-file parity.
|
|
348
|
+
errPayload = sanitizeMessageForStderr(safeStringify(error));
|
|
349
|
+
}
|
|
350
|
+
const safeMessage = sanitizeMessageForStderr(message);
|
|
351
|
+
console.error(prefix, safeMessage, errPayload);
|
|
63
352
|
if (this.debugMode && error instanceof Error && error.stack) {
|
|
353
|
+
// Stack traces include filenames and line numbers from the runtime
|
|
354
|
+
// and are intentionally multi-line — sanitizing them would defeat
|
|
355
|
+
// operator triage. The debug-mode gate is acceptable because the
|
|
356
|
+
// stack is only emitted in DEBUG=true, an operator-controlled path.
|
|
64
357
|
console.error(error.stack);
|
|
65
358
|
}
|
|
66
|
-
// File output always gets the full error shape for post-mortem debugging
|
|
67
359
|
const fileData = error instanceof Error
|
|
68
360
|
? { message: error.message, stack: error.stack, name: error.name }
|
|
69
361
|
: error;
|
|
70
|
-
this.writeToFile('error', message, fileData);
|
|
362
|
+
this.writeToFile('error', message, fileData, scope);
|
|
71
363
|
}
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
364
|
+
stderrPrefix(level, scope) {
|
|
365
|
+
const upper = level.toUpperCase();
|
|
366
|
+
if (scope) {
|
|
367
|
+
// Human-readable tag — keeps the original `[BRUTALIST MCP] LEVEL:`
|
|
368
|
+
// prefix so log scrapers still match, but adds `[module/operation]`
|
|
369
|
+
// so the subsystem is visible without parsing NDJSON.
|
|
370
|
+
// RL4: sanitize scope fields against CR/LF/ANSI/tab/control-char
|
|
371
|
+
// injection. The NDJSON file record preserves the originals.
|
|
372
|
+
const mod = sanitizeScopeForStderr(scope.module);
|
|
373
|
+
const op = sanitizeScopeForStderr(scope.operation);
|
|
374
|
+
return `[BRUTALIST MCP] ${upper} [${mod}/${op}]:`;
|
|
75
375
|
}
|
|
76
|
-
|
|
77
|
-
// regardless of the stderr debug gate
|
|
78
|
-
this.writeToFile('debug', message, data);
|
|
79
|
-
}
|
|
80
|
-
/** No-op kept for API compatibility. Writes are synchronous, nothing to flush. */
|
|
81
|
-
shutdown() {
|
|
82
|
-
// All writes use appendFileSync — every line is already on disk.
|
|
376
|
+
return `[BRUTALIST MCP] ${upper}:`;
|
|
83
377
|
}
|
|
84
378
|
// ---------------------------------------------------------------------------
|
|
85
379
|
// File logging internals
|
|
@@ -122,15 +416,21 @@ export class Logger {
|
|
|
122
416
|
this.fileEnabled = false;
|
|
123
417
|
}
|
|
124
418
|
}
|
|
125
|
-
writeToFile(level, message, data) {
|
|
419
|
+
writeToFile(level, message, data, scope) {
|
|
126
420
|
if (!this.fileEnabled)
|
|
127
421
|
return;
|
|
128
422
|
if (LOG_LEVELS[level] < this.fileLogLevel)
|
|
129
423
|
return;
|
|
130
424
|
try {
|
|
425
|
+
// Field order is stable for operators grepping NDJSON:
|
|
426
|
+
// ts → level → module → operation → msg → data → pid.
|
|
427
|
+
// `module`/`operation` are omitted entirely when no scope is bound
|
|
428
|
+
// so pre-migration call sites produce exactly the same record as
|
|
429
|
+
// before.
|
|
131
430
|
const entry = {
|
|
132
431
|
ts: new Date().toISOString(),
|
|
133
432
|
level,
|
|
433
|
+
...(scope && { module: scope.module, operation: scope.operation }),
|
|
134
434
|
msg: message,
|
|
135
435
|
...(data !== undefined && { data }),
|
|
136
436
|
pid: this.pid
|
|
@@ -194,5 +494,85 @@ export class Logger {
|
|
|
194
494
|
console.error(`[BRUTALIST MCP] WARN: File logging disabled (${reason})`);
|
|
195
495
|
}
|
|
196
496
|
}
|
|
497
|
+
/**
|
|
498
|
+
* Scoped child logger returned by `Logger.for(...)`. Binds `module` and
|
|
499
|
+
* `operation` to every record so integration-time call sites only need
|
|
500
|
+
* to create the child once per subsystem, not thread the scope through
|
|
501
|
+
* every call.
|
|
502
|
+
*
|
|
503
|
+
* Delegates to the root Logger for the actual stderr + file write so
|
|
504
|
+
* all env-var behavior (BRUTALIST_LOG_LEVEL, DEBUG, BRUTALIST_LOG_FILE,
|
|
505
|
+
* rotation, shutdown) is shared and there is no duplicated pipeline.
|
|
506
|
+
*/
|
|
507
|
+
export class ScopedLogger {
|
|
508
|
+
root;
|
|
509
|
+
scope;
|
|
510
|
+
constructor(root, scope) {
|
|
511
|
+
this.root = root;
|
|
512
|
+
this.scope = scope;
|
|
513
|
+
}
|
|
514
|
+
info(message, data) {
|
|
515
|
+
this.root.emit('info', message, data, this.scope);
|
|
516
|
+
}
|
|
517
|
+
warn(message, data) {
|
|
518
|
+
this.root.emit('warn', message, data, this.scope);
|
|
519
|
+
}
|
|
520
|
+
error(message, error) {
|
|
521
|
+
this.root.emitError(message, error, this.scope);
|
|
522
|
+
}
|
|
523
|
+
debug(message, data) {
|
|
524
|
+
this.root.emit('debug', message, data, this.scope);
|
|
525
|
+
}
|
|
526
|
+
/**
|
|
527
|
+
* Narrow an existing scoped logger to a new operation while preserving
|
|
528
|
+
* the bound module (RL2). Accepts a partial scope so common usage like
|
|
529
|
+
* `.for({ operation: 'orchestrateRound' })` keeps the class-bound
|
|
530
|
+
* module and only overrides the operation. Passing both fields fully
|
|
531
|
+
* replaces the scope — making renaming the module explicit.
|
|
532
|
+
*
|
|
533
|
+
* Resolution (a): module is preserved by default. This is the shape
|
|
534
|
+
* integrate_observability will consume — bind module at the class
|
|
535
|
+
* level, bind operation per method — so typo'd modules across call
|
|
536
|
+
* sites can't split log streams.
|
|
537
|
+
*
|
|
538
|
+
* Method parameter type is `Partial<LogScope>` which is wider than
|
|
539
|
+
* `LogScope` (every `LogScope` is assignable to `Partial<LogScope>`),
|
|
540
|
+
* so this override still satisfies the `StructuredLogger.for`
|
|
541
|
+
* contract — method parameters are contravariant.
|
|
542
|
+
*
|
|
543
|
+
* RL7 (Cycle 6): explicit `undefined` is filtered so it does not
|
|
544
|
+
* overwrite parent fields. The previous `??` form already handled
|
|
545
|
+
* undefined in the override expression, but a caller writing
|
|
546
|
+
* `.for({ module: undefined, operation: 'x' })` would still produce
|
|
547
|
+
* `module: this.scope.module` (correct) — and the same caller writing
|
|
548
|
+
* `.for({ module: undefined })` correctly preserves the parent. The
|
|
549
|
+
* defense-in-depth here is making the intent explicit so future
|
|
550
|
+
* refactors that switch to `Object.assign`-style merge can't silently
|
|
551
|
+
* regress, and so `null` is also handled (TypeScript allows `null`
|
|
552
|
+
* to satisfy an optional field if `strictNullChecks` is off in some
|
|
553
|
+
* consumer). `sanitizeScopeForStderr` also has a null/undefined
|
|
554
|
+
* guard for paranoid defense.
|
|
555
|
+
*/
|
|
556
|
+
for(scope) {
|
|
557
|
+
const nextModule = scope.module != null ? scope.module : this.scope.module;
|
|
558
|
+
const nextOperation = scope.operation != null ? scope.operation : this.scope.operation;
|
|
559
|
+
return new ScopedLogger(this.root, {
|
|
560
|
+
module: nextModule,
|
|
561
|
+
operation: nextOperation,
|
|
562
|
+
});
|
|
563
|
+
}
|
|
564
|
+
/**
|
|
565
|
+
* Grep-friendly shorthand for the common pattern of binding module
|
|
566
|
+
* at class construction and narrowing by operation per method (RL2).
|
|
567
|
+
* Equivalent to `.for({ operation })` but more discoverable and
|
|
568
|
+
* avoids accidental `.for({ module })` typos stripping the operation.
|
|
569
|
+
*/
|
|
570
|
+
forOperation(operation) {
|
|
571
|
+
return new ScopedLogger(this.root, {
|
|
572
|
+
module: this.scope.module,
|
|
573
|
+
operation,
|
|
574
|
+
});
|
|
575
|
+
}
|
|
576
|
+
}
|
|
197
577
|
export const logger = Logger.getInstance();
|
|
198
578
|
//# sourceMappingURL=logger.js.map
|
package/dist/logger.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Counter — a monotonically increasing cumulative metric.
|
|
3
|
+
*
|
|
4
|
+
* Counters are the simplest Prometheus primitive: a numeric value that only
|
|
5
|
+
* goes up. Each distinct label-value combination gets its own independent
|
|
6
|
+
* value so labeled increments never collide.
|
|
7
|
+
*/
|
|
8
|
+
import type { LabelValues, MetricDescriptor } from './types.js';
|
|
9
|
+
import { type LabelKey } from './types.js';
|
|
10
|
+
/**
|
|
11
|
+
* Opaque handle to a counter metric. Consumers of the module import these
|
|
12
|
+
* via `createMetricsRegistry()` and call `inc()` at instrumentation points.
|
|
13
|
+
*/
|
|
14
|
+
export interface Counter<TLabels extends readonly string[]> {
|
|
15
|
+
readonly descriptor: MetricDescriptor<TLabels>;
|
|
16
|
+
/** Increment by 1 (default) or by an explicit non-negative delta. */
|
|
17
|
+
inc(labels: LabelValues<TLabels>, delta?: number): void;
|
|
18
|
+
/** Test-only: read current values keyed by serialized label string. */
|
|
19
|
+
snapshot(): ReadonlyMap<LabelKey, number>;
|
|
20
|
+
/** Render this counter as a Prometheus text-exposition block (without trailing newline). */
|
|
21
|
+
render(): string;
|
|
22
|
+
}
|
|
23
|
+
export declare function createCounter<TLabels extends readonly string[]>(descriptor: MetricDescriptor<TLabels>): Counter<TLabels>;
|
|
24
|
+
//# sourceMappingURL=counter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"counter.d.ts","sourceRoot":"","sources":["../../src/metrics/counter.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAChE,OAAO,EAA+B,KAAK,QAAQ,EAAE,MAAM,YAAY,CAAC;AAExE;;;GAGG;AACH,MAAM,WAAW,OAAO,CAAC,OAAO,SAAS,SAAS,MAAM,EAAE;IACxD,QAAQ,CAAC,UAAU,EAAE,gBAAgB,CAAC,OAAO,CAAC,CAAC;IAC/C,qEAAqE;IACrE,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxD,uEAAuE;IACvE,QAAQ,IAAI,WAAW,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAC1C,4FAA4F;IAC5F,MAAM,IAAI,MAAM,CAAC;CAClB;AAED,wBAAgB,aAAa,CAAC,OAAO,SAAS,SAAS,MAAM,EAAE,EAC7D,UAAU,EAAE,gBAAgB,CAAC,OAAO,CAAC,GACpC,OAAO,CAAC,OAAO,CAAC,CA2ClB"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Counter — a monotonically increasing cumulative metric.
|
|
3
|
+
*
|
|
4
|
+
* Counters are the simplest Prometheus primitive: a numeric value that only
|
|
5
|
+
* goes up. Each distinct label-value combination gets its own independent
|
|
6
|
+
* value so labeled increments never collide.
|
|
7
|
+
*/
|
|
8
|
+
import { escapeHelp, serializeLabels } from './types.js';
|
|
9
|
+
export function createCounter(descriptor) {
|
|
10
|
+
const values = new Map();
|
|
11
|
+
const labelSets = new Map();
|
|
12
|
+
return {
|
|
13
|
+
descriptor,
|
|
14
|
+
inc(labels, delta = 1) {
|
|
15
|
+
if (!Number.isFinite(delta)) {
|
|
16
|
+
throw new Error(`metrics: counter "${descriptor.name}" delta must be finite`);
|
|
17
|
+
}
|
|
18
|
+
if (delta < 0) {
|
|
19
|
+
throw new Error(`metrics: counter "${descriptor.name}" delta must be >= 0`);
|
|
20
|
+
}
|
|
21
|
+
const key = serializeLabels(descriptor.labelNames, labels);
|
|
22
|
+
values.set(key, (values.get(key) ?? 0) + delta);
|
|
23
|
+
if (!labelSets.has(key)) {
|
|
24
|
+
// Preserve the first-seen label map for rendering (values stringified).
|
|
25
|
+
labelSets.set(key, labels);
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
snapshot() {
|
|
29
|
+
return new Map(values);
|
|
30
|
+
},
|
|
31
|
+
render() {
|
|
32
|
+
const lines = [];
|
|
33
|
+
lines.push(`# HELP ${descriptor.name} ${escapeHelp(descriptor.help)}`);
|
|
34
|
+
lines.push(`# TYPE ${descriptor.name} counter`);
|
|
35
|
+
if (values.size === 0) {
|
|
36
|
+
return lines.join('\n');
|
|
37
|
+
}
|
|
38
|
+
// Sort for deterministic output — test assertions rely on this.
|
|
39
|
+
const keys = Array.from(values.keys()).sort();
|
|
40
|
+
for (const key of keys) {
|
|
41
|
+
const value = values.get(key);
|
|
42
|
+
if (key === '') {
|
|
43
|
+
lines.push(`${descriptor.name} ${formatNumber(value)}`);
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
lines.push(`${descriptor.name}{${key}} ${formatNumber(value)}`);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return lines.join('\n');
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
function formatNumber(value) {
|
|
54
|
+
if (Number.isInteger(value)) {
|
|
55
|
+
return value.toString();
|
|
56
|
+
}
|
|
57
|
+
// Prometheus accepts Go-style float literals; JS number.toString() is compatible.
|
|
58
|
+
return value.toString();
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=counter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"counter.js","sourceRoot":"","sources":["../../src/metrics/counter.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EAAE,UAAU,EAAE,eAAe,EAAiB,MAAM,YAAY,CAAC;AAgBxE,MAAM,UAAU,aAAa,CAC3B,UAAqC;IAErC,MAAM,MAAM,GAAG,IAAI,GAAG,EAAoB,CAAC;IAC3C,MAAM,SAAS,GAAG,IAAI,GAAG,EAAkC,CAAC;IAE5D,OAAO;QACL,UAAU;QACV,GAAG,CAAC,MAA4B,EAAE,QAAgB,CAAC;YACjD,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;gBAC5B,MAAM,IAAI,KAAK,CAAC,qBAAqB,UAAU,CAAC,IAAI,wBAAwB,CAAC,CAAC;YAChF,CAAC;YACD,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;gBACd,MAAM,IAAI,KAAK,CAAC,qBAAqB,UAAU,CAAC,IAAI,sBAAsB,CAAC,CAAC;YAC9E,CAAC;YACD,MAAM,GAAG,GAAG,eAAe,CAAC,UAAU,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;YAC3D,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC;YAChD,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;gBACxB,wEAAwE;gBACxE,SAAS,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;YAC7B,CAAC;QACH,CAAC;QACD,QAAQ;YACN,OAAO,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC;QACzB,CAAC;QACD,MAAM;YACJ,MAAM,KAAK,GAAa,EAAE,CAAC;YAC3B,KAAK,CAAC,IAAI,CAAC,UAAU,UAAU,CAAC,IAAI,IAAI,UAAU,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACvE,KAAK,CAAC,IAAI,CAAC,UAAU,UAAU,CAAC,IAAI,UAAU,CAAC,CAAC;YAChD,IAAI,MAAM,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;gBACtB,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC1B,CAAC;YACD,gEAAgE;YAChE,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;YAC9C,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;gBACvB,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,GAAG,CAAE,CAAC;gBAC/B,IAAI,GAAG,KAAK,EAAE,EAAE,CAAC;oBACf,KAAK,CAAC,IAAI,CAAC,GAAG,UAAU,CAAC,IAAI,IAAI,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;gBAC1D,CAAC;qBAAM,CAAC;oBACN,KAAK,CAAC,IAAI,CAAC,GAAG,UAAU,CAAC,IAAI,IAAI,GAAG,KAAK,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;gBAClE,CAAC;YACH,CAAC;YACD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC1B,CAAC;KACF,CAAC;AACJ,CAAC;AAED,SAAS,YAAY,CAAC,KAAa;IACjC,IAAI,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;QAC5B,OAAO,KAAK,CAAC,QAAQ,EAAE,CAAC;IAC1B,CAAC;IACD,kFAAkF;IAClF,OAAO,KAAK,CAAC,QAAQ,EAAE,CAAC;AAC1B,CAAC"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Histogram — a cumulative histogram of observation values.
|
|
3
|
+
*
|
|
4
|
+
* The Prometheus convention: one `_bucket` series per upper bound plus a
|
|
5
|
+
* mandatory `+Inf` bucket, a `_count` series, and a `_sum` series. Buckets
|
|
6
|
+
* are CUMULATIVE — each bucket includes every lower bucket's observations.
|
|
7
|
+
*
|
|
8
|
+
* Buckets are declared once at construction. Per-label-set state includes:
|
|
9
|
+
* - counts[i] — cumulative count for the i-th bucket (counts[bucketsAscending.length] = +Inf).
|
|
10
|
+
* - sum — cumulative sum of observed values (for quantile approximation).
|
|
11
|
+
* - count — total observations (equals counts[+Inf bucket]).
|
|
12
|
+
*/
|
|
13
|
+
import type { LabelValues, MetricDescriptor } from './types.js';
|
|
14
|
+
import { type LabelKey } from './types.js';
|
|
15
|
+
export interface HistogramDescriptor<TLabels extends readonly string[]> extends MetricDescriptor<TLabels> {
|
|
16
|
+
/** Upper bounds in strictly ascending order; a `+Inf` bucket is added automatically. */
|
|
17
|
+
readonly buckets: readonly number[];
|
|
18
|
+
}
|
|
19
|
+
export interface Histogram<TLabels extends readonly string[]> {
|
|
20
|
+
readonly descriptor: HistogramDescriptor<TLabels>;
|
|
21
|
+
/**
|
|
22
|
+
* Record an observation.
|
|
23
|
+
*
|
|
24
|
+
* The value must be a FINITE, NON-NEGATIVE number. Negative values are
|
|
25
|
+
* rejected symmetrically with `Counter.inc()`'s rejection of negative
|
|
26
|
+
* deltas — callers that mis-compute a duration (e.g., `Date.now() -
|
|
27
|
+
* futureTimestamp`) must not silently poison bucket counts or `_sum`
|
|
28
|
+
* (which would break SLO math downstream). Rejection mode: throw.
|
|
29
|
+
*/
|
|
30
|
+
observe(labels: LabelValues<TLabels>, value: number): void;
|
|
31
|
+
/** Test-only: cumulative counts per bucket, keyed by serialized label string. */
|
|
32
|
+
snapshot(): ReadonlyMap<LabelKey, HistogramSnapshot>;
|
|
33
|
+
render(): string;
|
|
34
|
+
}
|
|
35
|
+
export interface HistogramSnapshot {
|
|
36
|
+
/** cumulative[i] = number of observations <= buckets[i]; last entry is +Inf. */
|
|
37
|
+
readonly cumulative: readonly number[];
|
|
38
|
+
readonly sum: number;
|
|
39
|
+
readonly count: number;
|
|
40
|
+
}
|
|
41
|
+
export declare function createHistogram<TLabels extends readonly string[]>(descriptor: HistogramDescriptor<TLabels>): Histogram<TLabels>;
|
|
42
|
+
//# sourceMappingURL=histogram.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"histogram.d.ts","sourceRoot":"","sources":["../../src/metrics/histogram.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAChE,OAAO,EAAiD,KAAK,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE1F,MAAM,WAAW,mBAAmB,CAAC,OAAO,SAAS,SAAS,MAAM,EAAE,CACpE,SAAQ,gBAAgB,CAAC,OAAO,CAAC;IACjC,wFAAwF;IACxF,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;CACrC;AAED,MAAM,WAAW,SAAS,CAAC,OAAO,SAAS,SAAS,MAAM,EAAE;IAC1D,QAAQ,CAAC,UAAU,EAAE,mBAAmB,CAAC,OAAO,CAAC,CAAC;IAClD;;;;;;;;OAQG;IACH,OAAO,CAAC,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3D,iFAAiF;IACjF,QAAQ,IAAI,WAAW,CAAC,QAAQ,EAAE,iBAAiB,CAAC,CAAC;IACrD,MAAM,IAAI,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,iBAAiB;IAChC,gFAAgF;IAChF,QAAQ,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;IACvC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AASD,wBAAgB,eAAe,CAAC,OAAO,SAAS,SAAS,MAAM,EAAE,EAC/D,UAAU,EAAE,mBAAmB,CAAC,OAAO,CAAC,GACvC,SAAS,CAAC,OAAO,CAAC,CA0FpB"}
|