@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.
- package/README.md +125 -4
- package/lib/cjs/BatchQueue.d.ts +127 -0
- package/lib/cjs/BatchQueue.d.ts.map +1 -0
- package/lib/cjs/BatchQueue.js +126 -0
- package/lib/cjs/BatchQueue.js.map +1 -0
- package/lib/cjs/filters/filter.d.ts +27 -0
- package/lib/cjs/filters/filter.d.ts.map +1 -0
- package/lib/cjs/filters/filter.js +20 -0
- package/lib/cjs/filters/filter.js.map +1 -0
- package/lib/cjs/filters/whenRepeated.d.ts +52 -0
- package/lib/cjs/filters/whenRepeated.d.ts.map +1 -0
- package/lib/cjs/filters/whenRepeated.js +98 -0
- package/lib/cjs/filters/whenRepeated.js.map +1 -0
- package/lib/cjs/format.d.ts +20 -0
- package/lib/cjs/format.d.ts.map +1 -0
- package/lib/cjs/format.js +75 -0
- package/lib/cjs/format.js.map +1 -0
- package/lib/cjs/index.d.ts +260 -21
- package/lib/cjs/index.d.ts.map +1 -1
- package/lib/cjs/index.js +211 -34
- package/lib/cjs/index.js.map +1 -1
- package/lib/cjs/perf.d.ts +109 -0
- package/lib/cjs/perf.d.ts.map +1 -0
- package/lib/cjs/perf.js +162 -0
- package/lib/cjs/perf.js.map +1 -0
- package/lib/cjs/persistence.d.ts +19 -0
- package/lib/cjs/persistence.d.ts.map +1 -0
- package/lib/cjs/persistence.js +137 -0
- package/lib/cjs/persistence.js.map +1 -0
- package/lib/cjs/serializers.d.ts +77 -0
- package/lib/cjs/serializers.d.ts.map +1 -0
- package/lib/cjs/serializers.js +215 -0
- package/lib/cjs/serializers.js.map +1 -0
- package/lib/mjs/BatchQueue.d.ts +127 -0
- package/lib/mjs/BatchQueue.d.ts.map +1 -0
- package/lib/mjs/BatchQueue.js +122 -0
- package/lib/mjs/BatchQueue.js.map +1 -0
- package/lib/mjs/filters/filter.d.ts +27 -0
- package/lib/mjs/filters/filter.d.ts.map +1 -0
- package/lib/mjs/filters/filter.js +16 -0
- package/lib/mjs/filters/filter.js.map +1 -0
- package/lib/mjs/filters/whenRepeated.d.ts +52 -0
- package/lib/mjs/filters/whenRepeated.d.ts.map +1 -0
- package/lib/mjs/filters/whenRepeated.js +95 -0
- package/lib/mjs/filters/whenRepeated.js.map +1 -0
- package/lib/mjs/format.d.ts +20 -0
- package/lib/mjs/format.d.ts.map +1 -0
- package/lib/mjs/format.js +72 -0
- package/lib/mjs/format.js.map +1 -0
- package/lib/mjs/index.d.ts +260 -21
- package/lib/mjs/index.d.ts.map +1 -1
- package/lib/mjs/index.js +205 -11
- package/lib/mjs/index.js.map +1 -1
- package/lib/mjs/perf.d.ts +109 -0
- package/lib/mjs/perf.d.ts.map +1 -0
- package/lib/mjs/perf.js +157 -0
- package/lib/mjs/perf.js.map +1 -0
- package/lib/mjs/persistence.d.ts +19 -0
- package/lib/mjs/persistence.d.ts.map +1 -0
- package/lib/mjs/persistence.js +132 -0
- package/lib/mjs/persistence.js.map +1 -0
- package/lib/mjs/serializers.d.ts +77 -0
- package/lib/mjs/serializers.d.ts.map +1 -0
- package/lib/mjs/serializers.js +208 -0
- package/lib/mjs/serializers.js.map +1 -0
- package/lib/tsconfig.cjs.tsbuildinfo +1 -1
- package/lib/tsconfig.mjs.tsbuildinfo +1 -1
- 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
|
|
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
|
-
|
|
65
|
-
|
|
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
|
-
|
|
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
|
package/lib/mjs/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,EAAE,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AACrE,OAAO,CAAC,MAAM,QAAQ,CAAC;AACvB,OAAO,
|
|
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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"}
|
package/lib/mjs/perf.js
ADDED
|
@@ -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"}
|