@spinajs/log-common 2.0.480 → 2.0.482

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 +207 -33
  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 +201 -10
  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,37 @@ 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
125
  const sMsg = err instanceof Error || !err ? message : err;
65
- const tMsg = args.length !== 0 ? util.format(sMsg, ...args) : sMsg;
126
+ const tMsg = args.length !== 0 ? format(sMsg, ...args) : sMsg;
66
127
  const lName = logger ?? message;
128
+ // Ambient async-context fields ( lowest precedence, must never throw ). The
129
+ // computed core fields below and any explicit per-call / logger `variables`
130
+ // OVERRIDE these — ambient context only FILLS IN fields nobody else set.
131
+ let ctx = {};
132
+ try {
133
+ ctx = logContextProvider() ?? {};
134
+ }
135
+ catch {
136
+ ctx = {};
137
+ }
138
+ const theVars = {
139
+ ...ctx,
140
+ error: err instanceof Error ? err : undefined,
141
+ level: LogLevelStrings[`${level}`].toUpperCase(),
142
+ logger: lName,
143
+ message: tMsg,
144
+ ...variables,
145
+ };
146
+ applySerializers(theVars);
67
147
  return {
68
148
  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
- },
149
+ Variables: theVars,
76
150
  };
77
151
  }
78
152
  export class Log extends SyncService {
@@ -80,9 +154,87 @@ export class Log extends SyncService {
80
154
  super(...arguments);
81
155
  this.Timers = new Map();
82
156
  this.Variables = {};
157
+ /**
158
+ * Lowest level any of this logger's targets accepts ( the MIN across its
159
+ * matched rules ). Set by FrameworkLogger.resolve(); default Trace = allow
160
+ * all. A call below this level would be dropped by every target anyway, so the
161
+ * per-method guard can safely short-circuit on it.
162
+ */
163
+ this.MinLevel = LogLevel.Trace;
164
+ /**
165
+ * Runtime level override ( loglevel-style ). `null` means "no override, use
166
+ * MinLevel". Set via setLevel/enableAll/disableAll, cleared via resetLevel.
167
+ */
168
+ this.LevelOverride = null;
169
+ }
170
+ /** Effective minimum level: the runtime override if set, otherwise MinLevel. */
171
+ getLevel() {
172
+ return this.LevelOverride ?? this.MinLevel;
173
+ }
174
+ /** True when a call at `level` should be emitted given the effective level. */
175
+ isEnabled(level) {
176
+ return level >= this.getLevel();
177
+ }
178
+ /**
179
+ * Set a runtime level override. Accepts a {@link LogLevel} or a level name.
180
+ * When `persist` ( default true ) the choice is stored so it survives a
181
+ * browser reload ( no-op on Node ).
182
+ */
183
+ setLevel(level, persist = true) {
184
+ this.LevelOverride = normalizeLevel(level);
185
+ if (persist) {
186
+ persistLevel(this.Name, this.LevelOverride);
187
+ }
188
+ }
189
+ /**
190
+ * Set the override ONLY if nothing is currently applied ( loglevel semantics:
191
+ * a default must never clobber a user's explicit / persisted choice ). Never
192
+ * persists.
193
+ */
194
+ setDefaultLevel(level) {
195
+ if (this.LevelOverride === null) {
196
+ this.LevelOverride = normalizeLevel(level);
197
+ }
198
+ }
199
+ /** Drop the runtime override ( back to MinLevel ) and clear any persisted value. */
200
+ resetLevel() {
201
+ this.LevelOverride = null;
202
+ clearPersistedLevel(this.Name);
203
+ }
204
+ /** Enable every level ( Trace and up ). */
205
+ enableAll(persist = true) {
206
+ this.setLevel(LogLevel.Trace, persist);
207
+ }
208
+ /**
209
+ * Disable every level - even {@link LogLevel.Security} - by raising the
210
+ * override to {@link SILENT_LEVEL} ( one above Security ).
211
+ */
212
+ disableAll(persist = true) {
213
+ this.setLevel(SILENT_LEVEL, persist);
214
+ }
215
+ /**
216
+ * Force-drain THIS logger's targets' buffers ( eg. File / Loki / OTLP batch
217
+ * queues ) so buffered entries are written out. Does NOT close / dispose the
218
+ * target - handle & timer teardown remains the DI container's job. Calling
219
+ * `forceFlush()` on a non-buffered target is a harmless no-op. Guarded so a
220
+ * logger that failed to resolve ( no `Targets` ) is a safe no-op.
221
+ */
222
+ flush() {
223
+ if (!this.Targets || this.Targets.length === 0) {
224
+ return Promise.resolve();
225
+ }
226
+ return Promise.allSettled(this.Targets.map((t) => t.instance.forceFlush())).then(() => undefined);
227
+ }
228
+ /** Flush every registered logger ( best-effort; never rejects ). */
229
+ static flushAll() {
230
+ return Promise.allSettled([...Log.Loggers.values()].map((l) => l.flush())).then(() => undefined);
83
231
  }
84
232
  static clearLoggers() {
85
- return Promise.all([...Log.Loggers.values()].map((l) => l.dispose()))
233
+ // Flush buffered entries out BEFORE tearing loggers down so File / Loki /
234
+ // OTLP data is not lost when teardown does not go through DI container
235
+ // disposal of the target singletons.
236
+ return Log.flushAll()
237
+ .then(() => Promise.all([...Log.Loggers.values()].map((l) => l.dispose())))
86
238
  .then(() => {
87
239
  Log.Loggers.clear();
88
240
  })
@@ -119,6 +271,28 @@ export class Log extends SyncService {
119
271
  this,
120
272
  ]);
121
273
  }
274
+ /**
275
+ * Attach a sink to THIS logger AT RUNTIME ( bunyan `addStream` style ),
276
+ * without going through config. Returns the resolved target instance, or
277
+ * `undefined` when nothing was attached ( eg. `def.enabled === false` ).
278
+ *
279
+ * Default is a safe no-op ( returns `undefined` ) so `Log`-typed references
280
+ * and bootstrap proxies compile; {@link FrameworkLogger } overrides it with
281
+ * the real target-descriptor build + gate recompute.
282
+ */
283
+ addTarget(_def, _opts) {
284
+ return undefined;
285
+ }
286
+ /**
287
+ * Detach a runtime sink by its target `name`, flushing its buffered entries
288
+ * first ( it is NOT disposed - the instance may be DI-owned / shared ).
289
+ * No-op when no target with that name is attached.
290
+ *
291
+ * Default resolves immediately; {@link FrameworkLogger } overrides it.
292
+ */
293
+ removeTarget(_name) {
294
+ return Promise.resolve();
295
+ }
122
296
  }
123
297
  Log.Loggers = new Map();
124
298
  Log.InternalLoggers = new Map();
@@ -157,4 +331,21 @@ export function Logger(name, variables) {
157
331
  });
158
332
  };
159
333
  }
334
+ /**
335
+ * Ambient log-context provider seam. A Node-side consumer ( @spinajs/log's
336
+ * LogContext ) registers a function returning the current async-context store;
337
+ * `createLogMessageObject` merges its result at LOWEST precedence so every log
338
+ * entry inherits ambient fields ( eg. requestId ) without threading them by hand.
339
+ *
340
+ * Kept here ( not in @spinajs/log ) so the seam is browser-safe: log-common must
341
+ * stay free of `node:async_hooks`. The default provider returns an empty object;
342
+ * the browser build wires a synchronous fallback instead.
343
+ */
344
+ let logContextProvider = () => ({});
345
+ /**
346
+ * Registers the ambient log-context provider. See {@link logContextProvider}.
347
+ */
348
+ export function setLogContextProvider(fn) {
349
+ logContextProvider = fn;
350
+ }
160
351
  //# 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"}