@btravstack/observability 0.5.0 → 0.7.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 +2 -2
- package/dist/index.mjs +2 -2
- package/dist/otel.cjs +23 -20
- package/dist/otel.d.cts +13 -0
- package/dist/otel.d.mts +13 -0
- package/dist/otel.mjs +24 -21
- package/package.json +8 -8
package/dist/index.cjs
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
let _btravstack_config = require("@btravstack/config");
|
|
3
3
|
let _btravstack_core = require("@btravstack/core");
|
|
4
|
-
let unthrown = require("unthrown");
|
|
5
4
|
let _btravstack_di = require("@btravstack/di");
|
|
6
5
|
//#region src/config.ts
|
|
6
|
+
const isLevel = (value) => _btravstack_core.LEVELS.includes(value);
|
|
7
7
|
/**
|
|
8
8
|
* `LOG_LEVEL`, as a `ConfigField` of the six levels and nothing else.
|
|
9
9
|
*
|
|
@@ -18,7 +18,7 @@ const logLevel = (options = {}) => {
|
|
|
18
18
|
const text = _btravstack_config.Config.string("LOG_LEVEL", { default: options.default ?? "info" });
|
|
19
19
|
return {
|
|
20
20
|
variable: text.variable,
|
|
21
|
-
parse: (raw) => text.parse(raw).
|
|
21
|
+
parse: (raw) => text.parse(raw).ensure(isLevel, (value) => new _btravstack_config.ConfigFieldInvalid({ reason: `must be one of ${_btravstack_core.LEVELS.join(", ")}, got ${JSON.stringify(value)}` }))
|
|
22
22
|
};
|
|
23
23
|
};
|
|
24
24
|
/** The schema `observability()` binds `LoggerConfig` through — one field today, and the place a second one lands. */
|
package/dist/index.mjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { Config, ConfigFieldInvalid, Env } from "@btravstack/config";
|
|
2
2
|
import { LEVELS, Logger, currentUnit } from "@btravstack/core";
|
|
3
|
-
import { Err, Ok } from "unthrown";
|
|
4
3
|
import { Module, Port, Provider } from "@btravstack/di";
|
|
5
4
|
//#region src/config.ts
|
|
5
|
+
const isLevel = (value) => LEVELS.includes(value);
|
|
6
6
|
/**
|
|
7
7
|
* `LOG_LEVEL`, as a `ConfigField` of the six levels and nothing else.
|
|
8
8
|
*
|
|
@@ -17,7 +17,7 @@ const logLevel = (options = {}) => {
|
|
|
17
17
|
const text = Config.string("LOG_LEVEL", { default: options.default ?? "info" });
|
|
18
18
|
return {
|
|
19
19
|
variable: text.variable,
|
|
20
|
-
parse: (raw) => text.parse(raw).
|
|
20
|
+
parse: (raw) => text.parse(raw).ensure(isLevel, (value) => new ConfigFieldInvalid({ reason: `must be one of ${LEVELS.join(", ")}, got ${JSON.stringify(value)}` }))
|
|
21
21
|
};
|
|
22
22
|
};
|
|
23
23
|
/** The schema `observability()` binds `LoggerConfig` through — one field today, and the place a second one lands. */
|
package/dist/otel.cjs
CHANGED
|
@@ -1,24 +1,10 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
let _btravstack_core = require("@btravstack/core");
|
|
3
|
-
let unthrown = require("unthrown");
|
|
4
3
|
let _btravstack_di = require("@btravstack/di");
|
|
5
4
|
let _opentelemetry_api = require("@opentelemetry/api");
|
|
6
5
|
let _opentelemetry_sdk_node = require("@opentelemetry/sdk-node");
|
|
6
|
+
let unthrown = require("unthrown");
|
|
7
7
|
//#region src/otel.ts
|
|
8
|
-
/**
|
|
9
|
-
* The tracing half of observability — the ADAPTER, not the contract. `Tracer`
|
|
10
|
-
* and `Meter` are the kernel's ports, and OTel's presence stops at this subpath,
|
|
11
|
-
* behind an optional peer exactly like `pino`.
|
|
12
|
-
*
|
|
13
|
-
* The ports are narrowings of OTel's own shapes, so what the SDK hands back
|
|
14
|
-
* satisfies them with no translation in between.
|
|
15
|
-
*/
|
|
16
|
-
/**
|
|
17
|
-
* The SDK itself, module-private: providing it is what starts it, and `release`
|
|
18
|
-
* is what flushes it. It rides the graph as a RESOURCE so the kernel closes it
|
|
19
|
-
* on every exit path — a span lost in `shutdown()` becomes a `teardownError` and
|
|
20
|
-
* exit `2`, never silence.
|
|
21
|
-
*/
|
|
22
8
|
var OtelSdk = class extends (0, _btravstack_di.Port)("OtelSdk") {};
|
|
23
9
|
/**
|
|
24
10
|
* The OTel starter: a module providing `Tracer` and `Meter` over a `NodeSDK`
|
|
@@ -33,15 +19,32 @@ var OtelSdk = class extends (0, _btravstack_di.Port)("OtelSdk") {};
|
|
|
33
19
|
* **Auto-instrumentation cannot live here**: the register hook must be
|
|
34
20
|
* preloaded before the instrumented libraries are imported, which no DI
|
|
35
21
|
* provider can promise. Preloading is the deployment's line.
|
|
22
|
+
*
|
|
23
|
+
* **What CAN live here is a starter's own instrumentation.** Every package
|
|
24
|
+
* that contributed to `Instrumentations` is loaded and handed to the SDK, so
|
|
25
|
+
* composing a starter is what declares the instrumentation and composing this
|
|
26
|
+
* is what turns it on. A contribution whose optional peer is not installed
|
|
27
|
+
* loads as `undefined` and is dropped — the contributor says so at `debug`,
|
|
28
|
+
* since it is the one that knows why.
|
|
29
|
+
*
|
|
30
|
+
* The module contributes one member of its own, which loads nothing. That is
|
|
31
|
+
* what makes `Instrumentations` a port the graph always has — a collector
|
|
32
|
+
* depending on a set port NOTHING provides is an unmet dependency, both at
|
|
33
|
+
* plan time and in `Needs`. Guice's `newSetBinder` declares the empty set for
|
|
34
|
+
* the same reason.
|
|
36
35
|
*/
|
|
37
36
|
const otel = (options) => (0, _btravstack_di.Module)("Otel")({
|
|
38
37
|
provides: [
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
38
|
+
_btravstack_di.Provider.member(_btravstack_core.Instrumentations)({ value: () => Promise.resolve(void 0) }),
|
|
39
|
+
(0, _btravstack_di.Provider)(OtelSdk)({ offered: _btravstack_core.Instrumentations }, {
|
|
40
|
+
acquire: ({ offered }) => (0, unthrown.fromSafePromise)(Promise.all(offered.map((load) => load())).then((loaded) => {
|
|
41
|
+
const sdk = new _opentelemetry_sdk_node.NodeSDK({
|
|
42
|
+
...options,
|
|
43
|
+
instrumentations: [...options?.instrumentations ?? [], ...loaded.filter((one) => one !== void 0)]
|
|
44
|
+
});
|
|
42
45
|
sdk.start();
|
|
43
|
-
return
|
|
44
|
-
},
|
|
46
|
+
return sdk;
|
|
47
|
+
})),
|
|
45
48
|
release: (sdk) => sdk.shutdown()
|
|
46
49
|
}),
|
|
47
50
|
(0, _btravstack_di.Provider)(_btravstack_core.Tracer)({ sdk: OtelSdk }, { sync: () => {
|
package/dist/otel.d.cts
CHANGED
|
@@ -15,6 +15,19 @@ import { NodeSDKConfiguration } from "@opentelemetry/sdk-node";
|
|
|
15
15
|
* **Auto-instrumentation cannot live here**: the register hook must be
|
|
16
16
|
* preloaded before the instrumented libraries are imported, which no DI
|
|
17
17
|
* provider can promise. Preloading is the deployment's line.
|
|
18
|
+
*
|
|
19
|
+
* **What CAN live here is a starter's own instrumentation.** Every package
|
|
20
|
+
* that contributed to `Instrumentations` is loaded and handed to the SDK, so
|
|
21
|
+
* composing a starter is what declares the instrumentation and composing this
|
|
22
|
+
* is what turns it on. A contribution whose optional peer is not installed
|
|
23
|
+
* loads as `undefined` and is dropped — the contributor says so at `debug`,
|
|
24
|
+
* since it is the one that knows why.
|
|
25
|
+
*
|
|
26
|
+
* The module contributes one member of its own, which loads nothing. That is
|
|
27
|
+
* what makes `Instrumentations` a port the graph always has — a collector
|
|
28
|
+
* depending on a set port NOTHING provides is an unmet dependency, both at
|
|
29
|
+
* plan time and in `Needs`. Guice's `newSetBinder` declares the empty set for
|
|
30
|
+
* the same reason.
|
|
18
31
|
*/
|
|
19
32
|
declare const otel: (options?: Partial<NodeSDKConfiguration>) => Module<Tracer | Meter, never, Scope>;
|
|
20
33
|
declare const UnitSpan_base: import("@btravstack/di").PortClass<"UnitSpan">;
|
package/dist/otel.d.mts
CHANGED
|
@@ -15,6 +15,19 @@ import { NodeSDKConfiguration } from "@opentelemetry/sdk-node";
|
|
|
15
15
|
* **Auto-instrumentation cannot live here**: the register hook must be
|
|
16
16
|
* preloaded before the instrumented libraries are imported, which no DI
|
|
17
17
|
* provider can promise. Preloading is the deployment's line.
|
|
18
|
+
*
|
|
19
|
+
* **What CAN live here is a starter's own instrumentation.** Every package
|
|
20
|
+
* that contributed to `Instrumentations` is loaded and handed to the SDK, so
|
|
21
|
+
* composing a starter is what declares the instrumentation and composing this
|
|
22
|
+
* is what turns it on. A contribution whose optional peer is not installed
|
|
23
|
+
* loads as `undefined` and is dropped — the contributor says so at `debug`,
|
|
24
|
+
* since it is the one that knows why.
|
|
25
|
+
*
|
|
26
|
+
* The module contributes one member of its own, which loads nothing. That is
|
|
27
|
+
* what makes `Instrumentations` a port the graph always has — a collector
|
|
28
|
+
* depending on a set port NOTHING provides is an unmet dependency, both at
|
|
29
|
+
* plan time and in `Needs`. Guice's `newSetBinder` declares the empty set for
|
|
30
|
+
* the same reason.
|
|
18
31
|
*/
|
|
19
32
|
declare const otel: (options?: Partial<NodeSDKConfiguration>) => Module<Tracer | Meter, never, Scope>;
|
|
20
33
|
declare const UnitSpan_base: import("@btravstack/di").PortClass<"UnitSpan">;
|
package/dist/otel.mjs
CHANGED
|
@@ -1,23 +1,9 @@
|
|
|
1
|
-
import { Meter, Tracer, currentUnit } from "@btravstack/core";
|
|
2
|
-
import { Ok } from "unthrown";
|
|
1
|
+
import { Instrumentations, Meter, Tracer, currentUnit } from "@btravstack/core";
|
|
3
2
|
import { Module, Port, Provider } from "@btravstack/di";
|
|
4
3
|
import { metrics, trace } from "@opentelemetry/api";
|
|
5
4
|
import { NodeSDK } from "@opentelemetry/sdk-node";
|
|
5
|
+
import { fromSafePromise } from "unthrown";
|
|
6
6
|
//#region src/otel.ts
|
|
7
|
-
/**
|
|
8
|
-
* The tracing half of observability — the ADAPTER, not the contract. `Tracer`
|
|
9
|
-
* and `Meter` are the kernel's ports, and OTel's presence stops at this subpath,
|
|
10
|
-
* behind an optional peer exactly like `pino`.
|
|
11
|
-
*
|
|
12
|
-
* The ports are narrowings of OTel's own shapes, so what the SDK hands back
|
|
13
|
-
* satisfies them with no translation in between.
|
|
14
|
-
*/
|
|
15
|
-
/**
|
|
16
|
-
* The SDK itself, module-private: providing it is what starts it, and `release`
|
|
17
|
-
* is what flushes it. It rides the graph as a RESOURCE so the kernel closes it
|
|
18
|
-
* on every exit path — a span lost in `shutdown()` becomes a `teardownError` and
|
|
19
|
-
* exit `2`, never silence.
|
|
20
|
-
*/
|
|
21
7
|
var OtelSdk = class extends Port("OtelSdk") {};
|
|
22
8
|
/**
|
|
23
9
|
* The OTel starter: a module providing `Tracer` and `Meter` over a `NodeSDK`
|
|
@@ -32,15 +18,32 @@ var OtelSdk = class extends Port("OtelSdk") {};
|
|
|
32
18
|
* **Auto-instrumentation cannot live here**: the register hook must be
|
|
33
19
|
* preloaded before the instrumented libraries are imported, which no DI
|
|
34
20
|
* provider can promise. Preloading is the deployment's line.
|
|
21
|
+
*
|
|
22
|
+
* **What CAN live here is a starter's own instrumentation.** Every package
|
|
23
|
+
* that contributed to `Instrumentations` is loaded and handed to the SDK, so
|
|
24
|
+
* composing a starter is what declares the instrumentation and composing this
|
|
25
|
+
* is what turns it on. A contribution whose optional peer is not installed
|
|
26
|
+
* loads as `undefined` and is dropped — the contributor says so at `debug`,
|
|
27
|
+
* since it is the one that knows why.
|
|
28
|
+
*
|
|
29
|
+
* The module contributes one member of its own, which loads nothing. That is
|
|
30
|
+
* what makes `Instrumentations` a port the graph always has — a collector
|
|
31
|
+
* depending on a set port NOTHING provides is an unmet dependency, both at
|
|
32
|
+
* plan time and in `Needs`. Guice's `newSetBinder` declares the empty set for
|
|
33
|
+
* the same reason.
|
|
35
34
|
*/
|
|
36
35
|
const otel = (options) => Module("Otel")({
|
|
37
36
|
provides: [
|
|
38
|
-
Provider(
|
|
39
|
-
|
|
40
|
-
|
|
37
|
+
Provider.member(Instrumentations)({ value: () => Promise.resolve(void 0) }),
|
|
38
|
+
Provider(OtelSdk)({ offered: Instrumentations }, {
|
|
39
|
+
acquire: ({ offered }) => fromSafePromise(Promise.all(offered.map((load) => load())).then((loaded) => {
|
|
40
|
+
const sdk = new NodeSDK({
|
|
41
|
+
...options,
|
|
42
|
+
instrumentations: [...options?.instrumentations ?? [], ...loaded.filter((one) => one !== void 0)]
|
|
43
|
+
});
|
|
41
44
|
sdk.start();
|
|
42
|
-
return
|
|
43
|
-
},
|
|
45
|
+
return sdk;
|
|
46
|
+
})),
|
|
44
47
|
release: (sdk) => sdk.shutdown()
|
|
45
48
|
}),
|
|
46
49
|
Provider(Tracer)({ sdk: OtelSdk }, { sync: () => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@btravstack/observability",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.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/
|
|
81
|
-
"@btravstack/
|
|
82
|
-
"@btravstack/di": "0.
|
|
83
|
-
"@btravstack/testing": "0.
|
|
80
|
+
"@btravstack/config": "0.7.0",
|
|
81
|
+
"@btravstack/core": "0.7.0",
|
|
82
|
+
"@btravstack/di": "0.7.0",
|
|
83
|
+
"@btravstack/testing": "0.7.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.7.0",
|
|
91
|
+
"@btravstack/core": "^0.7.0",
|
|
92
|
+
"@btravstack/di": "^0.7.0"
|
|
93
93
|
},
|
|
94
94
|
"peerDependenciesMeta": {
|
|
95
95
|
"@opentelemetry/api": {
|