@spinajs/log-common 2.0.481 → 2.0.484

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.
Files changed (68) hide show
  1. package/README.md +125 -4
  2. package/lib/cjs/BatchQueue.d.ts +127 -0
  3. package/lib/cjs/BatchQueue.d.ts.map +1 -0
  4. package/lib/cjs/BatchQueue.js +126 -0
  5. package/lib/cjs/BatchQueue.js.map +1 -0
  6. package/lib/cjs/filters/filter.d.ts +27 -0
  7. package/lib/cjs/filters/filter.d.ts.map +1 -0
  8. package/lib/cjs/filters/filter.js +20 -0
  9. package/lib/cjs/filters/filter.js.map +1 -0
  10. package/lib/cjs/filters/whenRepeated.d.ts +52 -0
  11. package/lib/cjs/filters/whenRepeated.d.ts.map +1 -0
  12. package/lib/cjs/filters/whenRepeated.js +98 -0
  13. package/lib/cjs/filters/whenRepeated.js.map +1 -0
  14. package/lib/cjs/format.d.ts +20 -0
  15. package/lib/cjs/format.d.ts.map +1 -0
  16. package/lib/cjs/format.js +75 -0
  17. package/lib/cjs/format.js.map +1 -0
  18. package/lib/cjs/index.d.ts +260 -21
  19. package/lib/cjs/index.d.ts.map +1 -1
  20. package/lib/cjs/index.js +211 -34
  21. package/lib/cjs/index.js.map +1 -1
  22. package/lib/cjs/perf.d.ts +109 -0
  23. package/lib/cjs/perf.d.ts.map +1 -0
  24. package/lib/cjs/perf.js +162 -0
  25. package/lib/cjs/perf.js.map +1 -0
  26. package/lib/cjs/persistence.d.ts +19 -0
  27. package/lib/cjs/persistence.d.ts.map +1 -0
  28. package/lib/cjs/persistence.js +137 -0
  29. package/lib/cjs/persistence.js.map +1 -0
  30. package/lib/cjs/serializers.d.ts +77 -0
  31. package/lib/cjs/serializers.d.ts.map +1 -0
  32. package/lib/cjs/serializers.js +215 -0
  33. package/lib/cjs/serializers.js.map +1 -0
  34. package/lib/mjs/BatchQueue.d.ts +127 -0
  35. package/lib/mjs/BatchQueue.d.ts.map +1 -0
  36. package/lib/mjs/BatchQueue.js +122 -0
  37. package/lib/mjs/BatchQueue.js.map +1 -0
  38. package/lib/mjs/filters/filter.d.ts +27 -0
  39. package/lib/mjs/filters/filter.d.ts.map +1 -0
  40. package/lib/mjs/filters/filter.js +16 -0
  41. package/lib/mjs/filters/filter.js.map +1 -0
  42. package/lib/mjs/filters/whenRepeated.d.ts +52 -0
  43. package/lib/mjs/filters/whenRepeated.d.ts.map +1 -0
  44. package/lib/mjs/filters/whenRepeated.js +95 -0
  45. package/lib/mjs/filters/whenRepeated.js.map +1 -0
  46. package/lib/mjs/format.d.ts +20 -0
  47. package/lib/mjs/format.d.ts.map +1 -0
  48. package/lib/mjs/format.js +72 -0
  49. package/lib/mjs/format.js.map +1 -0
  50. package/lib/mjs/index.d.ts +260 -21
  51. package/lib/mjs/index.d.ts.map +1 -1
  52. package/lib/mjs/index.js +205 -11
  53. package/lib/mjs/index.js.map +1 -1
  54. package/lib/mjs/perf.d.ts +109 -0
  55. package/lib/mjs/perf.d.ts.map +1 -0
  56. package/lib/mjs/perf.js +157 -0
  57. package/lib/mjs/perf.js.map +1 -0
  58. package/lib/mjs/persistence.d.ts +19 -0
  59. package/lib/mjs/persistence.d.ts.map +1 -0
  60. package/lib/mjs/persistence.js +132 -0
  61. package/lib/mjs/persistence.js.map +1 -0
  62. package/lib/mjs/serializers.d.ts +77 -0
  63. package/lib/mjs/serializers.d.ts.map +1 -0
  64. package/lib/mjs/serializers.js +208 -0
  65. package/lib/mjs/serializers.js.map +1 -0
  66. package/lib/tsconfig.cjs.tsbuildinfo +1 -1
  67. package/lib/tsconfig.mjs.tsbuildinfo +1 -1
  68. package/package.json +8 -9
package/lib/mjs/index.js CHANGED
@@ -9,7 +9,15 @@ var __metadata = (this && this.__metadata) || function (k, v) {
9
9
  };
10
10
  import { Autoinject, Container, DI, SyncService } from "@spinajs/di";
11
11
  import _ from "lodash";
12
- import * as util from "util";
12
+ import { format } from "./format.js";
13
+ import { applySerializers } from "./serializers.js";
14
+ import { persistLevel, clearPersistedLevel } from "./persistence.js";
15
+ export * from "./serializers.js";
16
+ export * from "./filters/filter.js";
17
+ export * from "./filters/whenRepeated.js";
18
+ export * from "./BatchQueue.js";
19
+ export * from "./persistence.js";
20
+ export * from "./perf.js";
13
21
  export var LogLevel;
14
22
  (function (LogLevel) {
15
23
  LogLevel[LogLevel["Security"] = 999] = "Security";
@@ -31,6 +39,29 @@ export const StrToLogLevel = {
31
39
  fatal: LogLevel.Fatal,
32
40
  security: LogLevel.Security,
33
41
  };
42
+ /**
43
+ * Sentinel level sitting one ABOVE {@link LogLevel.Security} ( SpinaJS's highest
44
+ * real level ). Used by `Log.disableAll()` as the runtime override so even a
45
+ * `security()` call is gated out - `isEnabled` compares numerically, so nothing
46
+ * ever reaches it.
47
+ */
48
+ export const SILENT_LEVEL = LogLevel.Security + 1;
49
+ /**
50
+ * Normalises a level given either as a {@link LogLevel} number or a level name
51
+ * ( "trace" | "debug" | ... ) to its numeric value. Single validation choke
52
+ * point: an unknown name throws a clear error. Numbers pass straight through
53
+ * ( so {@link SILENT_LEVEL } and other synthetic values are accepted ).
54
+ */
55
+ export function normalizeLevel(level) {
56
+ if (typeof level === "number") {
57
+ return level;
58
+ }
59
+ const resolved = StrToLogLevel[level];
60
+ if (resolved === undefined) {
61
+ throw new Error(`Invalid log level: ${level}`);
62
+ }
63
+ return resolved;
64
+ }
34
65
  export const LogLevelStrings = {
35
66
  [LogLevel.Debug]: "debug",
36
67
  [LogLevel.Error]: "error",
@@ -41,11 +72,37 @@ export const LogLevelStrings = {
41
72
  [LogLevel.Trace]: "trace",
42
73
  [LogLevel.Warn]: "warn",
43
74
  };
75
+ /**
76
+ * Maps SpinaJS log levels onto the OpenTelemetry SeverityNumber scale ( 1..24 ),
77
+ * so structured logs can be severity-ranked/filtered by any OTel-aware backend
78
+ * ( Grafana, Datadog, Elastic, OTLP pipelines ). Anchored on the OTel bands:
79
+ * TRACE 1-4, DEBUG 5-8, INFO 9-12, WARN 13-16, ERROR 17-20, FATAL 21-24.
80
+ * Success sits in the INFO band ( above plain info ); Security is mapped to the
81
+ * top of the FATAL band as SpinaJS's highest severity.
82
+ */
83
+ export const LogLevelToSeverityNumber = {
84
+ [LogLevel.Trace]: 1,
85
+ [LogLevel.Debug]: 5,
86
+ [LogLevel.Info]: 9,
87
+ [LogLevel.Success]: 11,
88
+ [LogLevel.Warn]: 13,
89
+ [LogLevel.Error]: 17,
90
+ [LogLevel.Fatal]: 21,
91
+ [LogLevel.Security]: 23,
92
+ };
44
93
  export class LogTarget extends SyncService {
45
94
  constructor(options) {
46
95
  super();
47
96
  this.HasError = false;
48
97
  this.Error = null;
98
+ /**
99
+ * Drop-hook. Set by a wrapper ( eg. {@link FallbackGroupTarget} ) to receive
100
+ * entries this target GAVE UP on ( buffer overflow or a non-retryable delivery
101
+ * failure ), so a durable fallback can catch EXACTLY what was not delivered —
102
+ * no duplicates. `null` ( the default ) means nobody is listening and dropped
103
+ * entries are simply discarded, as before.
104
+ */
105
+ this.OnDropped = null;
49
106
  if (options) {
50
107
  this.Options = _.merge(_.merge(this.Options, {
51
108
  enabled: true,
@@ -59,20 +116,40 @@ export class LogTarget extends SyncService {
59
116
  };
60
117
  }
61
118
  }
119
+ /** Flush any buffered entries to the underlying sink. Default no-op; buffered targets override. */
120
+ forceFlush() {
121
+ return Promise.resolve();
122
+ }
62
123
  }
63
124
  export function createLogMessageObject(err, message, level, logger, variables, ...args) {
64
- const sMsg = err instanceof Error || !err ? message : err;
65
- const tMsg = args.length !== 0 ? util.format(sMsg, ...args) : sMsg;
125
+ // `log.error(err)` ( no message ) is a legal overload, and it used to render
126
+ // an EMPTY `${message}`. Fall back to the error's own message so a bare
127
+ // error-only call still says something.
128
+ const sMsg = err instanceof Error ? (message ?? err.message) : !err ? message : err;
129
+ const tMsg = args.length !== 0 ? format(sMsg, ...args) : sMsg;
66
130
  const lName = logger ?? message;
131
+ // Ambient async-context fields ( lowest precedence, must never throw ). The
132
+ // computed core fields below and any explicit per-call / logger `variables`
133
+ // OVERRIDE these — ambient context only FILLS IN fields nobody else set.
134
+ let ctx = {};
135
+ try {
136
+ ctx = logContextProvider() ?? {};
137
+ }
138
+ catch {
139
+ ctx = {};
140
+ }
141
+ const theVars = {
142
+ ...ctx,
143
+ error: err instanceof Error ? err : undefined,
144
+ level: LogLevelStrings[`${level}`].toUpperCase(),
145
+ logger: lName,
146
+ message: tMsg,
147
+ ...variables,
148
+ };
149
+ applySerializers(theVars);
67
150
  return {
68
151
  Level: level,
69
- Variables: {
70
- error: err instanceof Error ? err : undefined,
71
- level: LogLevelStrings[`${level}`].toUpperCase(),
72
- logger: lName,
73
- message: tMsg,
74
- ...variables,
75
- },
152
+ Variables: theVars,
76
153
  };
77
154
  }
78
155
  export class Log extends SyncService {
@@ -80,9 +157,87 @@ export class Log extends SyncService {
80
157
  super(...arguments);
81
158
  this.Timers = new Map();
82
159
  this.Variables = {};
160
+ /**
161
+ * Lowest level any of this logger's targets accepts ( the MIN across its
162
+ * matched rules ). Set by FrameworkLogger.resolve(); default Trace = allow
163
+ * all. A call below this level would be dropped by every target anyway, so the
164
+ * per-method guard can safely short-circuit on it.
165
+ */
166
+ this.MinLevel = LogLevel.Trace;
167
+ /**
168
+ * Runtime level override ( loglevel-style ). `null` means "no override, use
169
+ * MinLevel". Set via setLevel/enableAll/disableAll, cleared via resetLevel.
170
+ */
171
+ this.LevelOverride = null;
172
+ }
173
+ /** Effective minimum level: the runtime override if set, otherwise MinLevel. */
174
+ getLevel() {
175
+ return this.LevelOverride ?? this.MinLevel;
176
+ }
177
+ /** True when a call at `level` should be emitted given the effective level. */
178
+ isEnabled(level) {
179
+ return level >= this.getLevel();
180
+ }
181
+ /**
182
+ * Set a runtime level override. Accepts a {@link LogLevel} or a level name.
183
+ * When `persist` ( default true ) the choice is stored so it survives a
184
+ * browser reload ( no-op on Node ).
185
+ */
186
+ setLevel(level, persist = true) {
187
+ this.LevelOverride = normalizeLevel(level);
188
+ if (persist) {
189
+ persistLevel(this.Name, this.LevelOverride);
190
+ }
191
+ }
192
+ /**
193
+ * Set the override ONLY if nothing is currently applied ( loglevel semantics:
194
+ * a default must never clobber a user's explicit / persisted choice ). Never
195
+ * persists.
196
+ */
197
+ setDefaultLevel(level) {
198
+ if (this.LevelOverride === null) {
199
+ this.LevelOverride = normalizeLevel(level);
200
+ }
201
+ }
202
+ /** Drop the runtime override ( back to MinLevel ) and clear any persisted value. */
203
+ resetLevel() {
204
+ this.LevelOverride = null;
205
+ clearPersistedLevel(this.Name);
206
+ }
207
+ /** Enable every level ( Trace and up ). */
208
+ enableAll(persist = true) {
209
+ this.setLevel(LogLevel.Trace, persist);
210
+ }
211
+ /**
212
+ * Disable every level - even {@link LogLevel.Security} - by raising the
213
+ * override to {@link SILENT_LEVEL} ( one above Security ).
214
+ */
215
+ disableAll(persist = true) {
216
+ this.setLevel(SILENT_LEVEL, persist);
217
+ }
218
+ /**
219
+ * Force-drain THIS logger's targets' buffers ( eg. File / Loki / OTLP batch
220
+ * queues ) so buffered entries are written out. Does NOT close / dispose the
221
+ * target - handle & timer teardown remains the DI container's job. Calling
222
+ * `forceFlush()` on a non-buffered target is a harmless no-op. Guarded so a
223
+ * logger that failed to resolve ( no `Targets` ) is a safe no-op.
224
+ */
225
+ flush() {
226
+ if (!this.Targets || this.Targets.length === 0) {
227
+ return Promise.resolve();
228
+ }
229
+ return Promise.allSettled(this.Targets.map((t) => t.instance.forceFlush())).then(() => undefined);
230
+ }
231
+ /** Flush every registered logger ( best-effort; never rejects ). */
232
+ static flushAll() {
233
+ return Promise.allSettled([...Log.Loggers.values()].map((l) => l.flush())).then(() => undefined);
83
234
  }
84
235
  static clearLoggers() {
85
- return Promise.all([...Log.Loggers.values()].map((l) => l.dispose()))
236
+ // Flush buffered entries out BEFORE tearing loggers down so File / Loki /
237
+ // OTLP data is not lost when teardown does not go through DI container
238
+ // disposal of the target singletons.
239
+ return Log.flushAll()
240
+ .then(() => Promise.all([...Log.Loggers.values()].map((l) => l.dispose())))
86
241
  .then(() => {
87
242
  Log.Loggers.clear();
88
243
  })
@@ -119,6 +274,28 @@ export class Log extends SyncService {
119
274
  this,
120
275
  ]);
121
276
  }
277
+ /**
278
+ * Attach a sink to THIS logger AT RUNTIME ( bunyan `addStream` style ),
279
+ * without going through config. Returns the resolved target instance, or
280
+ * `undefined` when nothing was attached ( eg. `def.enabled === false` ).
281
+ *
282
+ * Default is a safe no-op ( returns `undefined` ) so `Log`-typed references
283
+ * and bootstrap proxies compile; {@link FrameworkLogger } overrides it with
284
+ * the real target-descriptor build + gate recompute.
285
+ */
286
+ addTarget(_def, _opts) {
287
+ return undefined;
288
+ }
289
+ /**
290
+ * Detach a runtime sink by its target `name`, flushing its buffered entries
291
+ * first ( it is NOT disposed - the instance may be DI-owned / shared ).
292
+ * No-op when no target with that name is attached.
293
+ *
294
+ * Default resolves immediately; {@link FrameworkLogger } overrides it.
295
+ */
296
+ removeTarget(_name) {
297
+ return Promise.resolve();
298
+ }
122
299
  }
123
300
  Log.Loggers = new Map();
124
301
  Log.InternalLoggers = new Map();
@@ -157,4 +334,21 @@ export function Logger(name, variables) {
157
334
  });
158
335
  };
159
336
  }
337
+ /**
338
+ * Ambient log-context provider seam. A Node-side consumer ( @spinajs/log's
339
+ * LogContext ) registers a function returning the current async-context store;
340
+ * `createLogMessageObject` merges its result at LOWEST precedence so every log
341
+ * entry inherits ambient fields ( eg. requestId ) without threading them by hand.
342
+ *
343
+ * Kept here ( not in @spinajs/log ) so the seam is browser-safe: log-common must
344
+ * stay free of `node:async_hooks`. The default provider returns an empty object;
345
+ * the browser build wires a synchronous fallback instead.
346
+ */
347
+ let logContextProvider = () => ({});
348
+ /**
349
+ * Registers the ambient log-context provider. See {@link logContextProvider}.
350
+ */
351
+ export function setLogContextProvider(fn) {
352
+ logContextProvider = fn;
353
+ }
160
354
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,109 @@
1
+ import { SyncService } from "@spinajs/di";
2
+ /** Kind of a single measurement. */
3
+ export type PerfKind = "span" | "counter" | "value";
4
+ /** One unit of instrumentation, emitted to every registered {@link PerfSink}. */
5
+ export interface IPerfMetric {
6
+ name: string;
7
+ kind: PerfKind;
8
+ /** span duration in ms ( monotonic ). */
9
+ durationMs?: number;
10
+ /** counter delta / recorded value. */
11
+ value?: number;
12
+ /** LOW-cardinality dimensions ( safe as prom labels ). */
13
+ labels?: Record<string, string | number | boolean>;
14
+ /** rich payload for logs only ( sql text, bindings, rows ). Never a prom label. */
15
+ fields?: Record<string, unknown>;
16
+ /** epoch ms when the measurement started. */
17
+ startedAt?: number;
18
+ /** correlation id from the active request scope, when any. */
19
+ requestId?: string;
20
+ /** set when the measured block threw. */
21
+ error?: unknown;
22
+ }
23
+ /** Per-name aggregate inside a {@link IPerfRollup}. */
24
+ export interface IPerfRollupEntry {
25
+ count: number;
26
+ totalMs: number;
27
+ maxMs: number;
28
+ }
29
+ /** One per-request summary, handed to {@link PerfSink.onScopeEnd}. */
30
+ export interface IPerfRollup {
31
+ requestId?: string;
32
+ labels?: Record<string, string | number | boolean>;
33
+ totalMs: number;
34
+ byName: Record<string, IPerfRollupEntry>;
35
+ }
36
+ /** The mutable accumulator kept on the async request store. */
37
+ export interface IPerfScope {
38
+ requestId?: string;
39
+ byName: Record<string, IPerfRollupEntry>;
40
+ }
41
+ /**
42
+ * A receiver of perf measurements. Register a concrete subclass with
43
+ * `@Injectable(PerfSink)` and it is discovered via `Array.ofType(PerfSink)`.
44
+ * `SyncService` ( same base as LogTarget ) so resolution stays synchronous.
45
+ */
46
+ export declare abstract class PerfSink extends SyncService {
47
+ /** Receive one measurement. MUST NOT throw ( the facade guards it ). */
48
+ abstract collect(metric: IPerfMetric): void;
49
+ /** Optional: receive the per-request rollup at scope end. */
50
+ onScopeEnd?(rollup: IPerfRollup): void;
51
+ }
52
+ /** Options accepted by {@link Perf.measure} / {@link Perf.start}. */
53
+ export interface IMeasureOpts {
54
+ labels?: Record<string, string | number | boolean>;
55
+ fields?: Record<string, unknown>;
56
+ }
57
+ /** Handle returned by {@link Perf.start}. */
58
+ export interface IPerfSpan {
59
+ end(fields?: Record<string, unknown>): void;
60
+ }
61
+ /**
62
+ * Seam for the per-request scope. The node `@spinajs/log` package wires this to
63
+ * its AsyncLocalStorage-backed LogContext; the default returns `null` so the
64
+ * facade works ( sans rollups ) with no host — eg. on the browser.
65
+ */
66
+ export interface IPerfScopeBackend {
67
+ get(): IPerfScope | null;
68
+ }
69
+ /** Install the per-request scope backend. See {@link IPerfScopeBackend}. */
70
+ export declare function setPerfScopeBackend(backend: IPerfScopeBackend): void;
71
+ declare class PerfImpl {
72
+ /** Global kill-switch; when false measure/start/count/value are pass-throughs. */
73
+ Enabled: boolean;
74
+ private sinks;
75
+ /** Drop the memoized sink list so the next emit re-resolves ( tests / late registration ). */
76
+ refreshSinks(): void;
77
+ private resolveSinks;
78
+ private emit;
79
+ private accumulate;
80
+ private record;
81
+ /**
82
+ * Time `fn` ( sync or async ), emit a span, and return `fn`'s result. On a
83
+ * thrown error the span is still emitted ( with `error` set ) and the error is
84
+ * rethrown.
85
+ */
86
+ measure<T>(name: string, fn: () => Promise<T> | T, opts?: IMeasureOpts): Promise<T> | T;
87
+ /** Open a manual span; call `end()` where timing stops ( start/end may be far apart ). */
88
+ start(name: string, opts?: IMeasureOpts): IPerfSpan;
89
+ /** Increment a per-request counter ( eg. query count ) and emit a counter metric. */
90
+ count(name: string, delta?: number, labels?: Record<string, string | number | boolean>): void;
91
+ /** Record an absolute value ( gauge-like ) and emit a value metric. */
92
+ value(name: string, n: number, labels?: Record<string, string | number | boolean>): void;
93
+ /**
94
+ * Emit the per-request rollup for `scope` to every sink's `onScopeEnd`. The
95
+ * caller ( http ) passes the scope it read off `req.storage`; `extra` carries
96
+ * request labels and total wall time. No-op when `scope` is null.
97
+ */
98
+ flushScope(scope: IPerfScope | null | undefined, extra?: {
99
+ labels?: Record<string, string | number | boolean>;
100
+ totalMs?: number;
101
+ }): void;
102
+ }
103
+ /**
104
+ * Shared perf-instrumentation facade. Emits measurements to every registered
105
+ * {@link PerfSink}. See the plan / design doc for usage.
106
+ */
107
+ export declare const Perf: PerfImpl;
108
+ export {};
109
+ //# sourceMappingURL=perf.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"perf.d.ts","sourceRoot":"","sources":["../../src/perf.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,157 @@
1
+ import { DI, SyncService } from "@spinajs/di";
2
+ /**
3
+ * A receiver of perf measurements. Register a concrete subclass with
4
+ * `@Injectable(PerfSink)` and it is discovered via `Array.ofType(PerfSink)`.
5
+ * `SyncService` ( same base as LogTarget ) so resolution stays synchronous.
6
+ */
7
+ export class PerfSink extends SyncService {
8
+ }
9
+ const NOOP_BACKEND = { get: () => null };
10
+ let perfScopeBackend = NOOP_BACKEND;
11
+ /** Install the per-request scope backend. See {@link IPerfScopeBackend}. */
12
+ export function setPerfScopeBackend(backend) {
13
+ perfScopeBackend = backend ?? NOOP_BACKEND;
14
+ }
15
+ class PerfImpl {
16
+ constructor() {
17
+ /** Global kill-switch; when false measure/start/count/value are pass-throughs. */
18
+ this.Enabled = true;
19
+ this.sinks = null;
20
+ }
21
+ /** Drop the memoized sink list so the next emit re-resolves ( tests / late registration ). */
22
+ refreshSinks() {
23
+ this.sinks = null;
24
+ }
25
+ resolveSinks() {
26
+ if (this.sinks === null) {
27
+ // PerfSink extends SyncService => resolve returns synchronously.
28
+ this.sinks = DI.resolve(Array.ofType(PerfSink)) ?? [];
29
+ }
30
+ return this.sinks;
31
+ }
32
+ emit(metric) {
33
+ for (const s of this.resolveSinks()) {
34
+ try {
35
+ s.collect(metric);
36
+ }
37
+ catch {
38
+ /* a sink must never break the measured code or sibling sinks */
39
+ }
40
+ }
41
+ }
42
+ accumulate(name, durationMs, scope) {
43
+ if (!scope)
44
+ return;
45
+ const e = scope.byName[name] ?? (scope.byName[name] = { count: 0, totalMs: 0, maxMs: 0 });
46
+ e.count += 1;
47
+ e.totalMs += durationMs;
48
+ if (durationMs > e.maxMs)
49
+ e.maxMs = durationMs;
50
+ }
51
+ record(name, startedAt, durationMs, opts, error) {
52
+ const scope = perfScopeBackend.get();
53
+ this.accumulate(name, durationMs, scope);
54
+ this.emit({
55
+ name,
56
+ kind: "span",
57
+ durationMs,
58
+ labels: opts?.labels,
59
+ fields: error !== undefined ? { ...(opts?.fields ?? {}), error } : opts?.fields,
60
+ startedAt,
61
+ requestId: scope?.requestId,
62
+ error,
63
+ });
64
+ }
65
+ /**
66
+ * Time `fn` ( sync or async ), emit a span, and return `fn`'s result. On a
67
+ * thrown error the span is still emitted ( with `error` set ) and the error is
68
+ * rethrown.
69
+ */
70
+ measure(name, fn, opts) {
71
+ if (!this.Enabled)
72
+ return fn();
73
+ const startedAt = Date.now();
74
+ const t0 = performance.now();
75
+ let out;
76
+ try {
77
+ out = fn();
78
+ }
79
+ catch (err) {
80
+ this.record(name, startedAt, performance.now() - t0, opts, err);
81
+ throw err;
82
+ }
83
+ if (out !== null && typeof out?.then === "function") {
84
+ return out.then((v) => {
85
+ this.record(name, startedAt, performance.now() - t0, opts, undefined);
86
+ return v;
87
+ }, (err) => {
88
+ this.record(name, startedAt, performance.now() - t0, opts, err);
89
+ throw err;
90
+ });
91
+ }
92
+ this.record(name, startedAt, performance.now() - t0, opts, undefined);
93
+ return out;
94
+ }
95
+ /** Open a manual span; call `end()` where timing stops ( start/end may be far apart ). */
96
+ start(name, opts) {
97
+ const startedAt = Date.now();
98
+ const t0 = performance.now();
99
+ let ended = false;
100
+ return {
101
+ end: (fields) => {
102
+ if (ended)
103
+ return;
104
+ ended = true;
105
+ const merged = fields ? { labels: opts?.labels, fields: { ...(opts?.fields ?? {}), ...fields } } : opts ?? {};
106
+ this.record(name, startedAt, performance.now() - t0, merged, undefined);
107
+ },
108
+ };
109
+ }
110
+ /** Increment a per-request counter ( eg. query count ) and emit a counter metric. */
111
+ count(name, delta = 1, labels) {
112
+ if (!this.Enabled)
113
+ return;
114
+ const scope = perfScopeBackend.get();
115
+ if (scope) {
116
+ const e = scope.byName[name] ?? (scope.byName[name] = { count: 0, totalMs: 0, maxMs: 0 });
117
+ e.count += delta;
118
+ }
119
+ this.emit({ name, kind: "counter", value: delta, labels, requestId: scope?.requestId });
120
+ }
121
+ /** Record an absolute value ( gauge-like ) and emit a value metric. */
122
+ value(name, n, labels) {
123
+ if (!this.Enabled)
124
+ return;
125
+ const scope = perfScopeBackend.get();
126
+ this.emit({ name, kind: "value", value: n, labels, requestId: scope?.requestId });
127
+ }
128
+ /**
129
+ * Emit the per-request rollup for `scope` to every sink's `onScopeEnd`. The
130
+ * caller ( http ) passes the scope it read off `req.storage`; `extra` carries
131
+ * request labels and total wall time. No-op when `scope` is null.
132
+ */
133
+ flushScope(scope, extra) {
134
+ if (!scope)
135
+ return;
136
+ const rollup = {
137
+ requestId: scope.requestId,
138
+ labels: extra?.labels,
139
+ totalMs: extra?.totalMs ?? 0,
140
+ byName: scope.byName,
141
+ };
142
+ for (const sink of this.resolveSinks()) {
143
+ try {
144
+ sink.onScopeEnd?.(rollup);
145
+ }
146
+ catch {
147
+ /* isolate */
148
+ }
149
+ }
150
+ }
151
+ }
152
+ /**
153
+ * Shared perf-instrumentation facade. Emits measurements to every registered
154
+ * {@link PerfSink}. See the plan / design doc for usage.
155
+ */
156
+ export const Perf = new PerfImpl();
157
+ //# sourceMappingURL=perf.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"perf.js","sourceRoot":"","sources":["../../src/perf.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import type { LogLevel } from "./index.js";
2
+ /**
3
+ * Persist `level` for `loggerName`. Browser only - writes `String(level)` to
4
+ * localStorage under `spinajs:log:level:<loggerName>`, falling back to a cookie
5
+ * when storage throws. No-op on Node.
6
+ */
7
+ export declare function persistLevel(loggerName: string, level: LogLevel): void;
8
+ /**
9
+ * Read back the persisted level for `loggerName` ( localStorage then cookie ).
10
+ * Returns a finite {@link LogLevel} number, or `undefined` when nothing valid is
11
+ * stored. Always `undefined` on Node.
12
+ */
13
+ export declare function readPersistedLevel(loggerName: string): LogLevel | undefined;
14
+ /**
15
+ * Remove any persisted level for `loggerName` ( localStorage + cookie ). No-op
16
+ * on Node.
17
+ */
18
+ export declare function clearPersistedLevel(loggerName: string): void;
19
+ //# sourceMappingURL=persistence.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"persistence.d.ts","sourceRoot":"","sources":["../../src/persistence.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAmE3C;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,GAAG,IAAI,CAmBtE;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,QAAQ,GAAG,SAAS,CA0B3E;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAgB5D"}