@btravstack/observability 0.9.0 → 0.10.0
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/dist/index.cjs +23 -5
- package/dist/index.d.cts +2 -2
- package/dist/index.d.mts +2 -2
- package/dist/index.mjs +24 -6
- package/dist/otel.cjs +45 -1
- package/dist/otel.d.cts +2 -2
- package/dist/otel.d.mts +2 -2
- package/dist/otel.mjs +46 -2
- package/package.json +8 -8
package/dist/index.cjs
CHANGED
|
@@ -150,11 +150,29 @@ var LoggerConfig = class extends (0, _btravstack_di.Port)("LoggerConfig") {};
|
|
|
150
150
|
*/
|
|
151
151
|
const observability = (options = {}) => (0, _btravstack_di.Module)("Observability")({
|
|
152
152
|
needs: [_btravstack_config.Env],
|
|
153
|
-
provides: [
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
153
|
+
provides: [
|
|
154
|
+
_btravstack_config.Config.provider(LoggerConfig)(loggerSchema(options.level)),
|
|
155
|
+
(0, _btravstack_di.Provider)(_btravstack_core.Logger)({
|
|
156
|
+
inject: { config: LoggerConfig },
|
|
157
|
+
sync: ({ config }) => createLogger(options.sink ?? jsonSink(), config.level)
|
|
158
|
+
}),
|
|
159
|
+
_btravstack_di.Provider.member(_btravstack_core.Observers)({
|
|
160
|
+
inject: { logger: _btravstack_core.Logger },
|
|
161
|
+
sync: ({ logger }) => ({ component, name, attributes, details }) => ({ outcome, attributes: settled, cause }) => {
|
|
162
|
+
if (outcome !== "error") return;
|
|
163
|
+
logger.error(`${component}.${name} failed`, {
|
|
164
|
+
...attributes,
|
|
165
|
+
...details,
|
|
166
|
+
...settled
|
|
167
|
+
}, cause);
|
|
168
|
+
}
|
|
169
|
+
})
|
|
170
|
+
],
|
|
171
|
+
exports: [
|
|
172
|
+
_btravstack_core.Logger,
|
|
173
|
+
LoggerConfig,
|
|
174
|
+
_btravstack_core.Observers
|
|
175
|
+
]
|
|
158
176
|
});
|
|
159
177
|
/**
|
|
160
178
|
* The kernel's nine lifecycle events, as log lines on `logger` — the adapter
|
package/dist/index.d.cts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { n as Sink, r as createLogger, t as Line } from "./logger-B1-_76ej.cjs";
|
|
2
2
|
import { ConfigField, ConfigInvalid, Env } from "@btravstack/config";
|
|
3
|
-
import { EventSink, Level, Logger, LoggerService } from "@btravstack/core";
|
|
3
|
+
import { EventSink, Level, Logger, LoggerService, Observers } from "@btravstack/core";
|
|
4
4
|
import { Module } from "@btravstack/di";
|
|
5
5
|
//#region src/config.d.ts
|
|
6
6
|
/**
|
|
@@ -63,7 +63,7 @@ type ObservabilityOptions = {
|
|
|
63
63
|
* `currentUnit()` per call — so a request's lines are attributable with no
|
|
64
64
|
* argument threaded through the call stack.
|
|
65
65
|
*/
|
|
66
|
-
declare const observability: (options?: ObservabilityOptions) => Module<Logger | LoggerConfig, ConfigInvalid, Env>;
|
|
66
|
+
declare const observability: (options?: ObservabilityOptions) => Module<Logger | LoggerConfig | Observers, ConfigInvalid, Env>;
|
|
67
67
|
/**
|
|
68
68
|
* The kernel's nine lifecycle events, as log lines on `logger` — the adapter
|
|
69
69
|
* between `StartOptions.onEvent` and an application's own stream.
|
package/dist/index.d.mts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { n as Sink, r as createLogger, t as Line } from "./logger-B1-_76ej.mjs";
|
|
2
2
|
import { ConfigField, ConfigInvalid, Env } from "@btravstack/config";
|
|
3
|
-
import { EventSink, Level, Logger, LoggerService } from "@btravstack/core";
|
|
3
|
+
import { EventSink, Level, Logger, LoggerService, Observers } from "@btravstack/core";
|
|
4
4
|
import { Module } from "@btravstack/di";
|
|
5
5
|
//#region src/config.d.ts
|
|
6
6
|
/**
|
|
@@ -63,7 +63,7 @@ type ObservabilityOptions = {
|
|
|
63
63
|
* `currentUnit()` per call — so a request's lines are attributable with no
|
|
64
64
|
* argument threaded through the call stack.
|
|
65
65
|
*/
|
|
66
|
-
declare const observability: (options?: ObservabilityOptions) => Module<Logger | LoggerConfig, ConfigInvalid, Env>;
|
|
66
|
+
declare const observability: (options?: ObservabilityOptions) => Module<Logger | LoggerConfig | Observers, ConfigInvalid, Env>;
|
|
67
67
|
/**
|
|
68
68
|
* The kernel's nine lifecycle events, as log lines on `logger` — the adapter
|
|
69
69
|
* between `StartOptions.onEvent` and an application's own stream.
|
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Config, ConfigFieldInvalid, Env } from "@btravstack/config";
|
|
2
|
-
import { LEVELS, Logger, currentUnit } from "@btravstack/core";
|
|
2
|
+
import { LEVELS, Logger, Observers, currentUnit } from "@btravstack/core";
|
|
3
3
|
import { Module, Port, Provider } from "@btravstack/di";
|
|
4
4
|
//#region src/config.ts
|
|
5
5
|
const isLevel = (value) => LEVELS.includes(value);
|
|
@@ -149,11 +149,29 @@ var LoggerConfig = class extends Port("LoggerConfig") {};
|
|
|
149
149
|
*/
|
|
150
150
|
const observability = (options = {}) => Module("Observability")({
|
|
151
151
|
needs: [Env],
|
|
152
|
-
provides: [
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
152
|
+
provides: [
|
|
153
|
+
Config.provider(LoggerConfig)(loggerSchema(options.level)),
|
|
154
|
+
Provider(Logger)({
|
|
155
|
+
inject: { config: LoggerConfig },
|
|
156
|
+
sync: ({ config }) => createLogger(options.sink ?? jsonSink(), config.level)
|
|
157
|
+
}),
|
|
158
|
+
Provider.member(Observers)({
|
|
159
|
+
inject: { logger: Logger },
|
|
160
|
+
sync: ({ logger }) => ({ component, name, attributes, details }) => ({ outcome, attributes: settled, cause }) => {
|
|
161
|
+
if (outcome !== "error") return;
|
|
162
|
+
logger.error(`${component}.${name} failed`, {
|
|
163
|
+
...attributes,
|
|
164
|
+
...details,
|
|
165
|
+
...settled
|
|
166
|
+
}, cause);
|
|
167
|
+
}
|
|
168
|
+
})
|
|
169
|
+
],
|
|
170
|
+
exports: [
|
|
171
|
+
Logger,
|
|
172
|
+
LoggerConfig,
|
|
173
|
+
Observers
|
|
174
|
+
]
|
|
157
175
|
});
|
|
158
176
|
/**
|
|
159
177
|
* The kernel's nine lifecycle events, as log lines on `logger` — the adapter
|
package/dist/otel.cjs
CHANGED
|
@@ -39,6 +39,46 @@ const otel = (options) => (0, _btravstack_di.Module)("Otel")({
|
|
|
39
39
|
inject: {},
|
|
40
40
|
value: () => Promise.resolve(void 0)
|
|
41
41
|
}),
|
|
42
|
+
_btravstack_di.Provider.member(_btravstack_core.Observers)({
|
|
43
|
+
inject: {},
|
|
44
|
+
sync: () => {
|
|
45
|
+
const tracer = _opentelemetry_api.trace.getTracer("@btravstack/observability");
|
|
46
|
+
const counters = /* @__PURE__ */ new Map();
|
|
47
|
+
const durations = /* @__PURE__ */ new Map();
|
|
48
|
+
const instrument = (cache, key, make) => {
|
|
49
|
+
const existing = cache.get(key);
|
|
50
|
+
if (existing !== void 0) return existing;
|
|
51
|
+
const minted = make();
|
|
52
|
+
cache.set(key, minted);
|
|
53
|
+
return minted;
|
|
54
|
+
};
|
|
55
|
+
return ({ component, name, attributes, details, traced }) => {
|
|
56
|
+
const meter = _opentelemetry_api.metrics.getMeter("@btravstack/observability");
|
|
57
|
+
const span = traced === false ? void 0 : tracer.startSpan(`${component}.${name}`);
|
|
58
|
+
span?.setAttributes({
|
|
59
|
+
...attributes,
|
|
60
|
+
...details
|
|
61
|
+
});
|
|
62
|
+
const startedAt = performance.now();
|
|
63
|
+
const operations = instrument(counters, component, () => meter.createCounter(`btravstack.${component}.operations`, { description: `${component} operations, by operation and outcome` }));
|
|
64
|
+
const duration = instrument(durations, component, () => meter.createHistogram(`btravstack.${component}.duration`, {
|
|
65
|
+
description: `${component} operation duration`,
|
|
66
|
+
unit: "ms"
|
|
67
|
+
}));
|
|
68
|
+
return ({ outcome, attributes: settled }) => {
|
|
69
|
+
const all = {
|
|
70
|
+
...attributes,
|
|
71
|
+
...settled,
|
|
72
|
+
outcome
|
|
73
|
+
};
|
|
74
|
+
operations.add(1, all);
|
|
75
|
+
duration.record(performance.now() - startedAt, all);
|
|
76
|
+
if (outcome === "error") span?.setStatus({ code: _btravstack_core.SPAN_STATUS.error });
|
|
77
|
+
span?.end();
|
|
78
|
+
};
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
}),
|
|
42
82
|
(0, _btravstack_di.Provider)(OtelSdk)({
|
|
43
83
|
inject: { offered: _btravstack_core.Instrumentations },
|
|
44
84
|
acquire: ({ offered }) => (0, unthrown.fromSafePromise)(Promise.all(offered.map((load) => load())).then((loaded) => {
|
|
@@ -63,7 +103,11 @@ const otel = (options) => (0, _btravstack_di.Module)("Otel")({
|
|
|
63
103
|
sync: () => _opentelemetry_api.metrics.getMeter("@btravstack/observability")
|
|
64
104
|
})
|
|
65
105
|
],
|
|
66
|
-
exports: [
|
|
106
|
+
exports: [
|
|
107
|
+
_btravstack_core.Tracer,
|
|
108
|
+
_btravstack_core.Meter,
|
|
109
|
+
_btravstack_core.Observers
|
|
110
|
+
]
|
|
67
111
|
});
|
|
68
112
|
/** The span a unit rides, ended when the unit's fork closes. */
|
|
69
113
|
var UnitSpan = class extends (0, _btravstack_di.Port)("UnitSpan") {};
|
package/dist/otel.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Meter, Span, Tracer } from "@btravstack/core";
|
|
1
|
+
import { Meter, Observers, Span, Tracer } from "@btravstack/core";
|
|
2
2
|
import { Module, Scope } from "@btravstack/di";
|
|
3
3
|
import { NodeSDKConfiguration } from "@opentelemetry/sdk-node";
|
|
4
4
|
//#region src/otel.d.ts
|
|
@@ -29,7 +29,7 @@ import { NodeSDKConfiguration } from "@opentelemetry/sdk-node";
|
|
|
29
29
|
* plan time and in `Needs`. Guice's `newSetBinder` declares the empty set for
|
|
30
30
|
* the same reason.
|
|
31
31
|
*/
|
|
32
|
-
declare const otel: (options?: Partial<NodeSDKConfiguration>) => Module<Tracer | Meter, never, Scope>;
|
|
32
|
+
declare const otel: (options?: Partial<NodeSDKConfiguration>) => Module<Tracer | Meter | Observers, never, Scope>;
|
|
33
33
|
declare const UnitSpan_base: import("@btravstack/di").PortClass<"UnitSpan">;
|
|
34
34
|
/** The span a unit rides, ended when the unit's fork closes. */
|
|
35
35
|
declare class UnitSpan extends UnitSpan_base<Span> {}
|
package/dist/otel.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Meter, Span, Tracer } from "@btravstack/core";
|
|
1
|
+
import { Meter, Observers, Span, Tracer } from "@btravstack/core";
|
|
2
2
|
import { Module, Scope } from "@btravstack/di";
|
|
3
3
|
import { NodeSDKConfiguration } from "@opentelemetry/sdk-node";
|
|
4
4
|
//#region src/otel.d.ts
|
|
@@ -29,7 +29,7 @@ import { NodeSDKConfiguration } from "@opentelemetry/sdk-node";
|
|
|
29
29
|
* plan time and in `Needs`. Guice's `newSetBinder` declares the empty set for
|
|
30
30
|
* the same reason.
|
|
31
31
|
*/
|
|
32
|
-
declare const otel: (options?: Partial<NodeSDKConfiguration>) => Module<Tracer | Meter, never, Scope>;
|
|
32
|
+
declare const otel: (options?: Partial<NodeSDKConfiguration>) => Module<Tracer | Meter | Observers, never, Scope>;
|
|
33
33
|
declare const UnitSpan_base: import("@btravstack/di").PortClass<"UnitSpan">;
|
|
34
34
|
/** The span a unit rides, ended when the unit's fork closes. */
|
|
35
35
|
declare class UnitSpan extends UnitSpan_base<Span> {}
|
package/dist/otel.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Instrumentations, Meter, Tracer, currentUnit } from "@btravstack/core";
|
|
1
|
+
import { Instrumentations, Meter, Observers, SPAN_STATUS, Tracer, currentUnit } from "@btravstack/core";
|
|
2
2
|
import { Module, Port, Provider } from "@btravstack/di";
|
|
3
3
|
import { metrics, trace } from "@opentelemetry/api";
|
|
4
4
|
import { NodeSDK } from "@opentelemetry/sdk-node";
|
|
@@ -38,6 +38,46 @@ const otel = (options) => Module("Otel")({
|
|
|
38
38
|
inject: {},
|
|
39
39
|
value: () => Promise.resolve(void 0)
|
|
40
40
|
}),
|
|
41
|
+
Provider.member(Observers)({
|
|
42
|
+
inject: {},
|
|
43
|
+
sync: () => {
|
|
44
|
+
const tracer = trace.getTracer("@btravstack/observability");
|
|
45
|
+
const counters = /* @__PURE__ */ new Map();
|
|
46
|
+
const durations = /* @__PURE__ */ new Map();
|
|
47
|
+
const instrument = (cache, key, make) => {
|
|
48
|
+
const existing = cache.get(key);
|
|
49
|
+
if (existing !== void 0) return existing;
|
|
50
|
+
const minted = make();
|
|
51
|
+
cache.set(key, minted);
|
|
52
|
+
return minted;
|
|
53
|
+
};
|
|
54
|
+
return ({ component, name, attributes, details, traced }) => {
|
|
55
|
+
const meter = metrics.getMeter("@btravstack/observability");
|
|
56
|
+
const span = traced === false ? void 0 : tracer.startSpan(`${component}.${name}`);
|
|
57
|
+
span?.setAttributes({
|
|
58
|
+
...attributes,
|
|
59
|
+
...details
|
|
60
|
+
});
|
|
61
|
+
const startedAt = performance.now();
|
|
62
|
+
const operations = instrument(counters, component, () => meter.createCounter(`btravstack.${component}.operations`, { description: `${component} operations, by operation and outcome` }));
|
|
63
|
+
const duration = instrument(durations, component, () => meter.createHistogram(`btravstack.${component}.duration`, {
|
|
64
|
+
description: `${component} operation duration`,
|
|
65
|
+
unit: "ms"
|
|
66
|
+
}));
|
|
67
|
+
return ({ outcome, attributes: settled }) => {
|
|
68
|
+
const all = {
|
|
69
|
+
...attributes,
|
|
70
|
+
...settled,
|
|
71
|
+
outcome
|
|
72
|
+
};
|
|
73
|
+
operations.add(1, all);
|
|
74
|
+
duration.record(performance.now() - startedAt, all);
|
|
75
|
+
if (outcome === "error") span?.setStatus({ code: SPAN_STATUS.error });
|
|
76
|
+
span?.end();
|
|
77
|
+
};
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
}),
|
|
41
81
|
Provider(OtelSdk)({
|
|
42
82
|
inject: { offered: Instrumentations },
|
|
43
83
|
acquire: ({ offered }) => fromSafePromise(Promise.all(offered.map((load) => load())).then((loaded) => {
|
|
@@ -62,7 +102,11 @@ const otel = (options) => Module("Otel")({
|
|
|
62
102
|
sync: () => metrics.getMeter("@btravstack/observability")
|
|
63
103
|
})
|
|
64
104
|
],
|
|
65
|
-
exports: [
|
|
105
|
+
exports: [
|
|
106
|
+
Tracer,
|
|
107
|
+
Meter,
|
|
108
|
+
Observers
|
|
109
|
+
]
|
|
66
110
|
});
|
|
67
111
|
/** The span a unit rides, ended when the unit's fork closes. */
|
|
68
112
|
var UnitSpan = class extends Port("UnitSpan") {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@btravstack/observability",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.0",
|
|
4
4
|
"description": "Observability for @btravstack/core: a strict Logger port correlated with the kernel's units, a dependency-free JSON sink, and the lifecycle events as log lines",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"dependency-injection",
|
|
@@ -77,19 +77,19 @@
|
|
|
77
77
|
"typescript": "7.0.2",
|
|
78
78
|
"unthrown": "5.7.0",
|
|
79
79
|
"vitest": "4.1.11",
|
|
80
|
-
"@btravstack/config": "0.
|
|
81
|
-
"@btravstack/core": "0.
|
|
82
|
-
"@btravstack/di": "0.
|
|
83
|
-
"@btravstack/testing": "0.
|
|
80
|
+
"@btravstack/config": "0.10.0",
|
|
81
|
+
"@btravstack/core": "0.10.0",
|
|
82
|
+
"@btravstack/di": "0.10.0",
|
|
83
|
+
"@btravstack/testing": "0.10.0"
|
|
84
84
|
},
|
|
85
85
|
"peerDependencies": {
|
|
86
86
|
"@opentelemetry/api": "^1.9.0",
|
|
87
87
|
"@opentelemetry/sdk-node": "^0.221.0",
|
|
88
88
|
"pino": "^10",
|
|
89
89
|
"unthrown": "^5.0.0",
|
|
90
|
-
"@btravstack/config": "^0.
|
|
91
|
-
"@btravstack/core": "^0.
|
|
92
|
-
"@btravstack/di": "^0.
|
|
90
|
+
"@btravstack/config": "^0.10.0",
|
|
91
|
+
"@btravstack/core": "^0.10.0",
|
|
92
|
+
"@btravstack/di": "^0.10.0"
|
|
93
93
|
},
|
|
94
94
|
"peerDependenciesMeta": {
|
|
95
95
|
"@opentelemetry/api": {
|