@zudojs/observability 1.1.1 → 1.2.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 +39 -8
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/observability/observability.core.d.ts +6 -1
- package/dist/observability/observability.core.js +27 -11
- package/dist/redaction/index.d.ts +2 -1
- package/dist/redaction/index.js +2 -1
- package/dist/redaction/redaction.core.d.ts +0 -2
- package/dist/redaction/redaction.core.js +16 -28
- package/dist/redaction/redaction.defaults.d.ts +18 -0
- package/dist/redaction/redaction.defaults.js +33 -0
- package/dist/types/config.types.d.ts +16 -4
- package/package.json +6 -5
package/README.md
CHANGED
|
@@ -33,8 +33,7 @@ const obs = createObservability({
|
|
|
33
33
|
environment: "production",
|
|
34
34
|
logLevel: LogLevel.INFO,
|
|
35
35
|
|
|
36
|
-
//
|
|
37
|
-
redaction: {},
|
|
36
|
+
// Redaction is on by default — see "Redaction" below.
|
|
38
37
|
|
|
39
38
|
// Sample 10% of traces. The decision is derived from the trace ID, so a
|
|
40
39
|
// trace is never sampled in half across services.
|
|
@@ -82,8 +81,19 @@ Never pass a raw level number between the two; convert with
|
|
|
82
81
|
|
|
83
82
|
## Redaction
|
|
84
83
|
|
|
85
|
-
Redaction is
|
|
86
|
-
|
|
84
|
+
Redaction is **on by default**, as it is in `@zudojs/logger`: with no
|
|
85
|
+
`redaction` option, every name the logger's default matcher redacts
|
|
86
|
+
(`DEFAULT_LOGGER_SECRET_FIELDS` — password, passphrase, secret, token, jwt,
|
|
87
|
+
bearer, auth, authorization, cookie, session, sid, credential, api key,
|
|
88
|
+
private key, client secret, card number, cvv, ssn, pin, otp and more) is
|
|
89
|
+
redacted here too. `DEFAULT_SENSITIVE_FIELDS` is that effective default list:
|
|
90
|
+
the logger's `DEFAULT_LOGGER_SECRET_FIELDS` plus a few spellings of its own
|
|
91
|
+
(`apikey`, `access_token`, `cardnumber`, …).
|
|
92
|
+
Pass a config to change the rules, or `redaction: false` to turn it off.
|
|
93
|
+
Before 1.2 redaction was off unless configured, so a `password` field was
|
|
94
|
+
exported in the clear.
|
|
95
|
+
|
|
96
|
+
The logger applies it to every record before any transport sees it, and the tracer
|
|
87
97
|
applies it to every span attribute and span event attribute before any
|
|
88
98
|
processor or exporter sees it — a `Bearer` token attached to a span is
|
|
89
99
|
redacted the same way one written to a log field is.
|
|
@@ -92,8 +102,8 @@ redacted the same way one written to a log field is.
|
|
|
92
102
|
const obs = createObservability({
|
|
93
103
|
serviceName: "api",
|
|
94
104
|
redaction: {
|
|
95
|
-
//
|
|
96
|
-
fields: ["
|
|
105
|
+
// `fields` adds to the defaults; they stay in force.
|
|
106
|
+
fields: ["nationalId", "taxNumber"],
|
|
97
107
|
patterns: [/^x-.*-secret$/i],
|
|
98
108
|
// "contains" (the default) matches on word boundaries: "userPassword"
|
|
99
109
|
// and "x-api-key" match, "shippingAddress" and "authorId" do not.
|
|
@@ -109,6 +119,22 @@ obs.logger.info("login", {
|
|
|
109
119
|
});
|
|
110
120
|
```
|
|
111
121
|
|
|
122
|
+
`fields` **extends** the defaults (since 1.2.1): the default names and the
|
|
123
|
+
logger's matcher stay in force, so a field list can only add redaction —
|
|
124
|
+
`fields: ["nationalId"]` and `fields: [...DEFAULT_SENSITIVE_FIELDS, "nationalId"]`
|
|
125
|
+
mean the same thing. In 1.2.0 a list replaced the defaults, and because
|
|
126
|
+
`DEFAULT_SENSITIVE_FIELDS` then lacked `jwt`, `sid`, `pwd`, `passphrase` and
|
|
127
|
+
`bearer`, spreading it redacted less than the default. To use your list alone,
|
|
128
|
+
opt out explicitly:
|
|
129
|
+
|
|
130
|
+
```typescript
|
|
131
|
+
createObservability({
|
|
132
|
+
serviceName: "api",
|
|
133
|
+
// Only `ssn` is redacted — no default names, no logger matcher.
|
|
134
|
+
redaction: { fields: ["ssn"], replaceDefaults: true },
|
|
135
|
+
});
|
|
136
|
+
```
|
|
137
|
+
|
|
112
138
|
Traversal handles the shapes secrets actually arrive in: arrays, nested
|
|
113
139
|
objects, instances of your own classes (a DTO carrying a `password` field is
|
|
114
140
|
redacted and keeps its prototype), and cyclic graphs (a request object in a log
|
|
@@ -119,6 +145,10 @@ being flattened to `{}`.
|
|
|
119
145
|
`redactObject`, `redactValue` and `createStructureRedactor` are exported for
|
|
120
146
|
use outside the logger.
|
|
121
147
|
|
|
148
|
+
```typescript
|
|
149
|
+
createObservability({ serviceName: "api", redaction: false }); // opt out
|
|
150
|
+
```
|
|
151
|
+
|
|
122
152
|
## Metrics
|
|
123
153
|
|
|
124
154
|
Counters, gauges and histograms, keyed by name **and** labels.
|
|
@@ -165,8 +195,9 @@ name as two types is rejected wholesale by OTLP and Prometheus.
|
|
|
165
195
|
|
|
166
196
|
Metrics are exported by a `PeriodicMetricReader`, which the facade starts for
|
|
167
197
|
you when a `metricExporter` is configured. `metricExportIntervalMs: 0`
|
|
168
|
-
disables the periodic export while still collecting a
|
|
169
|
-
`
|
|
198
|
+
disables the periodic export while still collecting a snapshot on `flush()`
|
|
199
|
+
and a final one on `shutdown()`. `shutdown()` exports that final snapshot
|
|
200
|
+
exactly once (before 1.2 it was exported twice):
|
|
170
201
|
|
|
171
202
|
```typescript
|
|
172
203
|
const obs = createObservability({
|
package/dist/index.d.ts
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
* const obs = createObservability({
|
|
17
17
|
* serviceName: "my-api",
|
|
18
18
|
* logLevel: LogLevel.INFO,
|
|
19
|
-
* redaction:
|
|
19
|
+
* // Redaction is on by default; `redaction: false` turns it off.
|
|
20
20
|
* sampler: createProbabilitySampler(0.1),
|
|
21
21
|
* });
|
|
22
22
|
*
|
package/dist/index.js
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
* const obs = createObservability({
|
|
17
17
|
* serviceName: "my-api",
|
|
18
18
|
* logLevel: LogLevel.INFO,
|
|
19
|
-
* redaction:
|
|
19
|
+
* // Redaction is on by default; `redaction: false` turns it off.
|
|
20
20
|
* sampler: createProbabilitySampler(0.1),
|
|
21
21
|
* });
|
|
22
22
|
*
|
|
@@ -23,7 +23,7 @@ interface TelemetryPipeline {
|
|
|
23
23
|
readonly metricReader: PeriodicMetricReader;
|
|
24
24
|
readonly config: ObservabilityConfig;
|
|
25
25
|
readonly sampler: ObservabilityConfig["sampler"];
|
|
26
|
-
/** Redacts span attributes,
|
|
26
|
+
/** Redacts span attributes, unless `config.redaction` is `false`. */
|
|
27
27
|
readonly redactAttribute?: (key: string, value: unknown) => unknown;
|
|
28
28
|
}
|
|
29
29
|
/**
|
|
@@ -64,6 +64,11 @@ export declare class DefaultObservability implements Observability {
|
|
|
64
64
|
* when the caller went on to exit.
|
|
65
65
|
*/
|
|
66
66
|
flush(): Promise<void>;
|
|
67
|
+
/**
|
|
68
|
+
* Drains the log and span buffers, and — when `includeMetrics` — exports a
|
|
69
|
+
* metric snapshot. Shutdown passes `false`: the reader's own `shutdown()`
|
|
70
|
+
* exports the final snapshot, and collecting here as well sent it twice.
|
|
71
|
+
*/
|
|
67
72
|
private drain;
|
|
68
73
|
private reportFailures;
|
|
69
74
|
/**
|
|
@@ -79,9 +79,14 @@ export class DefaultObservability {
|
|
|
79
79
|
* when the caller went on to exit.
|
|
80
80
|
*/
|
|
81
81
|
async flush() {
|
|
82
|
-
await this.drain();
|
|
82
|
+
await this.drain(true);
|
|
83
83
|
}
|
|
84
|
-
|
|
84
|
+
/**
|
|
85
|
+
* Drains the log and span buffers, and — when `includeMetrics` — exports a
|
|
86
|
+
* metric snapshot. Shutdown passes `false`: the reader's own `shutdown()`
|
|
87
|
+
* exports the final snapshot, and collecting here as well sent it twice.
|
|
88
|
+
*/
|
|
89
|
+
async drain(includeMetrics) {
|
|
85
90
|
const tasks = [];
|
|
86
91
|
if (this.pipeline.logProcessor) {
|
|
87
92
|
tasks.push(this.pipeline.logProcessor.flush());
|
|
@@ -90,7 +95,8 @@ export class DefaultObservability {
|
|
|
90
95
|
if (processor.forceFlush)
|
|
91
96
|
tasks.push(processor.forceFlush());
|
|
92
97
|
}
|
|
93
|
-
|
|
98
|
+
if (includeMetrics)
|
|
99
|
+
tasks.push(this.pipeline.metricReader.collect());
|
|
94
100
|
await this.reportFailures(await Promise.allSettled(tasks), "flush");
|
|
95
101
|
}
|
|
96
102
|
async reportFailures(results, source) {
|
|
@@ -115,8 +121,9 @@ export class DefaultObservability {
|
|
|
115
121
|
}
|
|
116
122
|
async performShutdown() {
|
|
117
123
|
// Drain first: whatever is still queued should reach the backend before
|
|
118
|
-
// the exporters close.
|
|
119
|
-
|
|
124
|
+
// the exporters close. Metrics are left to the reader's shutdown, which
|
|
125
|
+
// exports the final snapshot exactly once.
|
|
126
|
+
await this.drain(false);
|
|
120
127
|
const steps = [];
|
|
121
128
|
steps.push(this.pipeline.metricReader.shutdown());
|
|
122
129
|
if (this.pipeline.logProcessor) {
|
|
@@ -186,10 +193,10 @@ function buildPipeline(config) {
|
|
|
186
193
|
});
|
|
187
194
|
// Redaction is applied by the logger, so every transport and exporter
|
|
188
195
|
// downstream sees redacted records — configuring it and not wiring it here
|
|
189
|
-
// is what made the "credentials are never logged" promise untrue.
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
196
|
+
// is what made the "credentials are never logged" promise untrue. It is on
|
|
197
|
+
// unless the caller opts out with `redaction: false`, as in @zudojs/logger.
|
|
198
|
+
const redaction = resolveRedaction(config);
|
|
199
|
+
const redactor = redaction ? createStructureRedactor(redaction) : undefined;
|
|
193
200
|
const logger = new StructuredLogger({
|
|
194
201
|
name: config.serviceName,
|
|
195
202
|
level: config.logLevel ?? LogLevel.INFO,
|
|
@@ -244,8 +251,8 @@ function buildPipeline(config) {
|
|
|
244
251
|
onError: config.onError,
|
|
245
252
|
});
|
|
246
253
|
metricReader.start();
|
|
247
|
-
const redactAttribute =
|
|
248
|
-
? buildAttributeRedactor(
|
|
254
|
+
const redactAttribute = redaction
|
|
255
|
+
? buildAttributeRedactor(redaction)
|
|
249
256
|
: undefined;
|
|
250
257
|
return {
|
|
251
258
|
logger,
|
|
@@ -259,6 +266,15 @@ function buildPipeline(config) {
|
|
|
259
266
|
redactAttribute,
|
|
260
267
|
};
|
|
261
268
|
}
|
|
269
|
+
/**
|
|
270
|
+
* The redaction rules in force: the caller's, the defaults when none were
|
|
271
|
+
* given, or none at all for an explicit `redaction: false`.
|
|
272
|
+
*/
|
|
273
|
+
function resolveRedaction(config) {
|
|
274
|
+
if (config.redaction === false)
|
|
275
|
+
return undefined;
|
|
276
|
+
return config.redaction ?? {};
|
|
277
|
+
}
|
|
262
278
|
/**
|
|
263
279
|
* Builds the span-attribute redactor.
|
|
264
280
|
*
|
|
@@ -3,5 +3,6 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Sensitive field redaction for logs and traces.
|
|
5
5
|
*/
|
|
6
|
-
export { createRedactor, createStructureRedactor, redactObject, redactValue, isSensitiveField,
|
|
6
|
+
export { createRedactor, createStructureRedactor, redactObject, redactValue, isSensitiveField, CIRCULAR_MARKER, MAX_DEPTH_MARKER, } from "./redaction.core.js";
|
|
7
|
+
export { DEFAULT_SENSITIVE_FIELDS } from "./redaction.defaults.js";
|
|
7
8
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/redaction/index.js
CHANGED
|
@@ -3,5 +3,6 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Sensitive field redaction for logs and traces.
|
|
5
5
|
*/
|
|
6
|
-
export { createRedactor, createStructureRedactor, redactObject, redactValue, isSensitiveField,
|
|
6
|
+
export { createRedactor, createStructureRedactor, redactObject, redactValue, isSensitiveField, CIRCULAR_MARKER, MAX_DEPTH_MARKER, } from "./redaction.core.js";
|
|
7
|
+
export { DEFAULT_SENSITIVE_FIELDS } from "./redaction.defaults.js";
|
|
7
8
|
//# sourceMappingURL=index.js.map
|
|
@@ -17,8 +17,6 @@
|
|
|
17
17
|
* `x-api-key` are caught, not just the exact names in the list.
|
|
18
18
|
*/
|
|
19
19
|
import type { RedactionConfig } from "../types.js";
|
|
20
|
-
/** Default sensitive field names, matched case-insensitively. */
|
|
21
|
-
export declare const DEFAULT_SENSITIVE_FIELDS: readonly string[];
|
|
22
20
|
/** Marker used in place of a structure that was too deep or already seen. */
|
|
23
21
|
export declare const CIRCULAR_MARKER = "[CIRCULAR]";
|
|
24
22
|
export declare const MAX_DEPTH_MARKER = "[MAX_DEPTH]";
|
|
@@ -16,33 +16,14 @@
|
|
|
16
16
|
* - matching is substring-based by default, so `userPassword` and
|
|
17
17
|
* `x-api-key` are caught, not just the exact names in the list.
|
|
18
18
|
*/
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
"cookie",
|
|
28
|
-
"session",
|
|
29
|
-
"credential",
|
|
30
|
-
"api_key",
|
|
31
|
-
"apikey",
|
|
32
|
-
"access_token",
|
|
33
|
-
"refresh_token",
|
|
34
|
-
"private_key",
|
|
35
|
-
"client_secret",
|
|
36
|
-
"credit_card",
|
|
37
|
-
"creditcard",
|
|
38
|
-
"card_number",
|
|
39
|
-
"cardnumber",
|
|
40
|
-
"cvv",
|
|
41
|
-
"ssn",
|
|
42
|
-
"social_security",
|
|
43
|
-
"pin",
|
|
44
|
-
"otp",
|
|
45
|
-
];
|
|
19
|
+
import { createDefaultSecretFieldMatcher } from "@zudojs/logger";
|
|
20
|
+
import { DEFAULT_SENSITIVE_FIELDS } from "./redaction.defaults.js";
|
|
21
|
+
/**
|
|
22
|
+
* @zudojs/logger's default secret-name matcher. The default rules here
|
|
23
|
+
* include it, so a field the logger redacts is never exported in the clear
|
|
24
|
+
* by this package.
|
|
25
|
+
*/
|
|
26
|
+
const isLoggerSecretField = createDefaultSecretFieldMatcher();
|
|
46
27
|
const DEFAULT_REPLACEMENT = "[REDACTED]";
|
|
47
28
|
const DEFAULT_MAX_DEPTH = 8;
|
|
48
29
|
/** Marker used in place of a structure that was too deep or already seen. */
|
|
@@ -87,15 +68,22 @@ function wordJoins(key) {
|
|
|
87
68
|
return joins;
|
|
88
69
|
}
|
|
89
70
|
function compile(config) {
|
|
90
|
-
const
|
|
71
|
+
const configured = config?.fields;
|
|
72
|
+
const replaceDefaults = configured !== undefined && config?.replaceDefaults === true;
|
|
73
|
+
const fields = (replaceDefaults
|
|
74
|
+
? configured
|
|
75
|
+
: [...DEFAULT_SENSITIVE_FIELDS, ...(configured ?? [])]).map((field) => field.toLowerCase());
|
|
91
76
|
const patterns = config?.patterns ?? [];
|
|
92
77
|
const matchMode = config?.matchMode ?? "contains";
|
|
93
78
|
const exact = new Set(fields);
|
|
94
79
|
const normalizedFields = new Set(fields.map((field) => field.replace(/[^a-z0-9]/g, "")).filter(Boolean));
|
|
80
|
+
const withLoggerDefaults = !replaceDefaults && matchMode === "contains";
|
|
95
81
|
const isSensitive = (key) => {
|
|
96
82
|
const lower = key.toLowerCase();
|
|
97
83
|
if (exact.has(lower))
|
|
98
84
|
return true;
|
|
85
|
+
if (withLoggerDefaults && isLoggerSecretField(key))
|
|
86
|
+
return true;
|
|
99
87
|
if (matchMode === "contains") {
|
|
100
88
|
for (const candidate of wordJoins(key)) {
|
|
101
89
|
if (normalizedFields.has(candidate))
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @zudojs/observability — Default redaction field list
|
|
3
|
+
*
|
|
4
|
+
* One list, built from @zudojs/logger's rather than copied from it, so the
|
|
5
|
+
* documented "extend the defaults" pattern
|
|
6
|
+
* (`fields: [...DEFAULT_SENSITIVE_FIELDS, "nationalId"]`) can never cover
|
|
7
|
+
* fewer names than the default rules do.
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Default sensitive field names, matched case-insensitively.
|
|
11
|
+
*
|
|
12
|
+
* Every entry of @zudojs/logger's `DEFAULT_LOGGER_SECRET_FIELDS` (password,
|
|
13
|
+
* passphrase, pwd, secret, token, jwt, bearer, auth, cookie, session, sid,
|
|
14
|
+
* credential, api key, card number, cvv, ssn, pin, otp, …) plus the
|
|
15
|
+
* spellings in {@link OBSERVABILITY_EXTRA_FIELDS}.
|
|
16
|
+
*/
|
|
17
|
+
export declare const DEFAULT_SENSITIVE_FIELDS: readonly string[];
|
|
18
|
+
//# sourceMappingURL=redaction.defaults.d.ts.map
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @zudojs/observability — Default redaction field list
|
|
3
|
+
*
|
|
4
|
+
* One list, built from @zudojs/logger's rather than copied from it, so the
|
|
5
|
+
* documented "extend the defaults" pattern
|
|
6
|
+
* (`fields: [...DEFAULT_SENSITIVE_FIELDS, "nationalId"]`) can never cover
|
|
7
|
+
* fewer names than the default rules do.
|
|
8
|
+
*/
|
|
9
|
+
import { DEFAULT_LOGGER_SECRET_FIELDS } from "@zudojs/logger";
|
|
10
|
+
/**
|
|
11
|
+
* Spellings this package matched before it adopted the logger's list. In
|
|
12
|
+
* `"contains"` mode they are already covered by a logger entry; they are kept
|
|
13
|
+
* so `"exact"` mode (`apikey` vs `api_key`) does not lose them.
|
|
14
|
+
*/
|
|
15
|
+
const OBSERVABILITY_EXTRA_FIELDS = [
|
|
16
|
+
"apikey",
|
|
17
|
+
"access_token",
|
|
18
|
+
"refresh_token",
|
|
19
|
+
"creditcard",
|
|
20
|
+
"cardnumber",
|
|
21
|
+
];
|
|
22
|
+
/**
|
|
23
|
+
* Default sensitive field names, matched case-insensitively.
|
|
24
|
+
*
|
|
25
|
+
* Every entry of @zudojs/logger's `DEFAULT_LOGGER_SECRET_FIELDS` (password,
|
|
26
|
+
* passphrase, pwd, secret, token, jwt, bearer, auth, cookie, session, sid,
|
|
27
|
+
* credential, api key, card number, cvv, ssn, pin, otp, …) plus the
|
|
28
|
+
* spellings in {@link OBSERVABILITY_EXTRA_FIELDS}.
|
|
29
|
+
*/
|
|
30
|
+
export const DEFAULT_SENSITIVE_FIELDS = Object.freeze([
|
|
31
|
+
...new Set([...DEFAULT_LOGGER_SECRET_FIELDS, ...OBSERVABILITY_EXTRA_FIELDS]),
|
|
32
|
+
]);
|
|
33
|
+
//# sourceMappingURL=redaction.defaults.js.map
|
|
@@ -50,10 +50,18 @@ export type RedactionMatchMode = "exact" | "contains";
|
|
|
50
50
|
/** Configuration for redacting sensitive fields from logs and traces. */
|
|
51
51
|
export interface RedactionConfig {
|
|
52
52
|
/**
|
|
53
|
-
*
|
|
54
|
-
*
|
|
53
|
+
* Extra field names to redact (case-insensitive), added to the defaults:
|
|
54
|
+
* `DEFAULT_SENSITIVE_FIELDS` and @zudojs/logger's default matcher stay in
|
|
55
|
+
* force, so a list can only ever add redaction. Set
|
|
56
|
+
* {@link RedactionConfig.replaceDefaults} to use this list alone.
|
|
55
57
|
*/
|
|
56
58
|
readonly fields?: readonly string[];
|
|
59
|
+
/**
|
|
60
|
+
* `true` makes {@link RedactionConfig.fields} replace the default names and
|
|
61
|
+
* the logger's matcher instead of extending them — the pre-1.2.1 meaning
|
|
62
|
+
* of `fields`. Ignored when `fields` is not set. Default: `false`.
|
|
63
|
+
*/
|
|
64
|
+
readonly replaceDefaults?: boolean;
|
|
57
65
|
/**
|
|
58
66
|
* Additional patterns tested against the field name. Useful for
|
|
59
67
|
* conventions a name list cannot express, such as `/^x-.*-token$/i`.
|
|
@@ -101,9 +109,13 @@ export interface ObservabilityConfig {
|
|
|
101
109
|
readonly processors?: readonly SpanProcessor[];
|
|
102
110
|
/**
|
|
103
111
|
* Redacts sensitive fields from log contexts *and* from span attributes and
|
|
104
|
-
* span event attributes.
|
|
112
|
+
* span event attributes.
|
|
113
|
+
*
|
|
114
|
+
* On by default: omitting it applies the default rules, which include
|
|
115
|
+
* every name @zudojs/logger redacts. Pass a config to change the rules, or
|
|
116
|
+
* `false` to turn redaction off.
|
|
105
117
|
*/
|
|
106
|
-
readonly redaction?: RedactionConfig;
|
|
118
|
+
readonly redaction?: RedactionConfig | false;
|
|
107
119
|
/**
|
|
108
120
|
* Metrics registry tuning: the series cap that bounds cardinality, and the
|
|
109
121
|
* histogram bucket boundaries. Without this the defaults were unreachable
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zudojs/observability",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.1",
|
|
4
4
|
"description": "Structured logging, metrics, tracing, context propagation, and exporters for Zudojs applications.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": {
|
|
@@ -26,12 +26,13 @@
|
|
|
26
26
|
"!dist/.tsbuildinfo"
|
|
27
27
|
],
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@zudojs/errors": "1.
|
|
29
|
+
"@zudojs/errors": "1.3.0",
|
|
30
|
+
"@zudojs/logger": "1.4.1"
|
|
30
31
|
},
|
|
31
32
|
"devDependencies": {
|
|
32
33
|
"typescript": "7.0.2",
|
|
33
|
-
"vitest": "^
|
|
34
|
-
"@types/node": "^26.
|
|
34
|
+
"vitest": "^5.0.1",
|
|
35
|
+
"@types/node": "^26.6.2"
|
|
35
36
|
},
|
|
36
37
|
"engines": {
|
|
37
38
|
"node": ">=24.0.0"
|
|
@@ -46,7 +47,7 @@
|
|
|
46
47
|
"tracing",
|
|
47
48
|
"logs"
|
|
48
49
|
],
|
|
49
|
-
"homepage": "https://
|
|
50
|
+
"homepage": "https://zudojs.oyinlola.site/docs/packages-observability",
|
|
50
51
|
"bugs": {
|
|
51
52
|
"url": "https://github.com/oyinlola-tech/zudo/issues"
|
|
52
53
|
},
|