@dxos/observability 0.6.2 → 0.6.3-main.0308ae2
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/lib/browser/{chunk-HKNRDUTP.mjs → chunk-2CXA7PYK.mjs} +187 -221
- package/dist/lib/browser/chunk-2CXA7PYK.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +1 -2
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/observability-MXAPN7J6.mjs +7 -0
- package/dist/lib/browser/otel-BUKBDMAL.mjs +275 -0
- package/dist/lib/browser/otel-BUKBDMAL.mjs.map +7 -0
- package/dist/lib/browser/sentry-log-processor-DVUUOZ6G.mjs +132 -0
- package/dist/lib/browser/sentry-log-processor-DVUUOZ6G.mjs.map +7 -0
- package/dist/lib/node/{chunk-6QQAPUDU.cjs → chunk-HBLKTDQE.cjs} +190 -217
- package/dist/lib/node/chunk-HBLKTDQE.cjs.map +7 -0
- package/dist/lib/node/index.cjs +15 -16
- package/dist/lib/node/index.cjs.map +2 -2
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node/{observability-7TFOBOTA.cjs → observability-4R6M4JMU.cjs} +6 -7
- package/dist/lib/node/observability-4R6M4JMU.cjs.map +7 -0
- package/dist/lib/node/otel-TSHMOAB4.cjs +276 -0
- package/dist/lib/node/otel-TSHMOAB4.cjs.map +7 -0
- package/dist/lib/node/sentry-log-processor-H6FUSKZI.cjs +150 -0
- package/dist/lib/node/sentry-log-processor-H6FUSKZI.cjs.map +7 -0
- package/dist/types/src/cli-observability-secrets.json +3 -1
- package/dist/types/src/helpers/browser-observability.d.ts.map +1 -1
- package/dist/types/src/helpers/browser-observability.js +1 -0
- package/dist/types/src/helpers/browser-observability.js.map +1 -1
- package/dist/types/src/observability.d.ts +12 -2
- package/dist/types/src/observability.d.ts.map +1 -1
- package/dist/types/src/observability.js +125 -42
- package/dist/types/src/observability.js.map +1 -1
- package/dist/types/src/otel/index.d.ts +5 -0
- package/dist/types/src/otel/index.d.ts.map +1 -0
- package/dist/types/src/otel/index.js +24 -0
- package/dist/types/src/otel/index.js.map +1 -0
- package/dist/types/src/otel/logs.d.ts +11 -0
- package/dist/types/src/otel/logs.d.ts.map +1 -0
- package/dist/types/src/otel/logs.js +72 -0
- package/dist/types/src/otel/logs.js.map +1 -0
- package/dist/types/src/otel/metrics.d.ts +14 -0
- package/dist/types/src/otel/metrics.d.ts.map +1 -0
- package/dist/types/src/otel/metrics.js +91 -0
- package/dist/types/src/otel/metrics.js.map +1 -0
- package/dist/types/src/otel/otel.d.ts +12 -0
- package/dist/types/src/otel/otel.d.ts.map +1 -0
- package/dist/types/src/otel/otel.js +15 -0
- package/dist/types/src/otel/otel.js.map +1 -0
- package/dist/types/src/otel/traces-browser.d.ts +8 -0
- package/dist/types/src/otel/traces-browser.d.ts.map +1 -0
- package/dist/types/src/otel/traces-browser.js +51 -0
- package/dist/types/src/otel/traces-browser.js.map +1 -0
- package/dist/types/src/otel/traces.d.ts +8 -0
- package/dist/types/src/otel/traces.d.ts.map +1 -0
- package/dist/types/src/otel/traces.js +44 -0
- package/dist/types/src/otel/traces.js.map +1 -0
- package/package.json +35 -20
- package/src/cli-observability-secrets.json +3 -1
- package/src/helpers/browser-observability.ts +1 -0
- package/src/observability.ts +141 -42
- package/src/otel/index.ts +8 -0
- package/src/otel/logs.ts +86 -0
- package/src/otel/metrics.ts +111 -0
- package/src/otel/otel.ts +21 -0
- package/src/otel/traces-browser.ts +59 -0
- package/src/otel/traces.ts +57 -0
- package/dist/lib/browser/chunk-HKNRDUTP.mjs.map +0 -7
- package/dist/lib/browser/observability-6FYBCIL6.mjs +0 -8
- package/dist/lib/node/chunk-6QQAPUDU.cjs.map +0 -7
- package/dist/lib/node/observability-7TFOBOTA.cjs.map +0 -7
- /package/dist/lib/browser/{observability-6FYBCIL6.mjs.map → observability-MXAPN7J6.mjs.map} +0 -0
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
//
|
|
3
|
+
// Copyright 2024 DXOS.org
|
|
4
|
+
//
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.setDiagLogger = void 0;
|
|
7
|
+
const api_1 = require("@opentelemetry/api");
|
|
8
|
+
const setDiagLogger = (level) => {
|
|
9
|
+
const logLevel = api_1.DiagLogLevel[level];
|
|
10
|
+
if (logLevel) {
|
|
11
|
+
api_1.diag.setLogger(new api_1.DiagConsoleLogger(), logLevel);
|
|
12
|
+
}
|
|
13
|
+
};
|
|
14
|
+
exports.setDiagLogger = setDiagLogger;
|
|
15
|
+
//# sourceMappingURL=otel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"otel.js","sourceRoot":"","sources":["../../../../src/otel/otel.ts"],"names":[],"mappings":";AAAA,EAAE;AACF,0BAA0B;AAC1B,EAAE;;;AAEF,4CAA2E;AAWpE,MAAM,aAAa,GAAG,CAAC,KAAc,EAAE,EAAE;IAC9C,MAAM,QAAQ,GAAG,kBAAY,CAAC,KAAkC,CAAC,CAAC;IAClE,IAAI,QAAQ,EAAE,CAAC;QACb,UAAI,CAAC,SAAS,CAAC,IAAI,uBAAiB,EAAE,EAAE,QAAQ,CAAC,CAAC;IACpD,CAAC;AACH,CAAC,CAAC;AALW,QAAA,aAAa,iBAKxB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"traces-browser.d.ts","sourceRoot":"","sources":["../../../../src/otel/traces-browser.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,QAAQ,CAAC;AAE1C,qBAAa,UAAU;IAET,OAAO,CAAC,QAAQ,CAAC,OAAO;IADpC,OAAO,CAAC,OAAO,CAAS;gBACK,OAAO,EAAE,WAAW;IA0B1C,KAAK;CAYb"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
//
|
|
3
|
+
// Copyright 2024 DXOS.org
|
|
4
|
+
//
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.OtelTraces = void 0;
|
|
7
|
+
const api_1 = require("@opentelemetry/api");
|
|
8
|
+
const auto_instrumentations_web_1 = require("@opentelemetry/auto-instrumentations-web");
|
|
9
|
+
const exporter_trace_otlp_http_1 = require("@opentelemetry/exporter-trace-otlp-http");
|
|
10
|
+
const instrumentation_1 = require("@opentelemetry/instrumentation");
|
|
11
|
+
const resources_1 = require("@opentelemetry/resources");
|
|
12
|
+
const sdk_trace_base_1 = require("@opentelemetry/sdk-trace-base");
|
|
13
|
+
const sdk_trace_web_1 = require("@opentelemetry/sdk-trace-web");
|
|
14
|
+
const semantic_conventions_1 = require("@opentelemetry/semantic-conventions");
|
|
15
|
+
const log_1 = require("@dxos/log");
|
|
16
|
+
const tracing_1 = require("@dxos/tracing");
|
|
17
|
+
class OtelTraces {
|
|
18
|
+
constructor(options) {
|
|
19
|
+
this.options = options;
|
|
20
|
+
const resource = resources_1.Resource.default().merge(new resources_1.Resource({
|
|
21
|
+
[semantic_conventions_1.SEMRESATTRS_SERVICE_NAME]: this.options.serviceName,
|
|
22
|
+
[semantic_conventions_1.SEMRESATTRS_SERVICE_VERSION]: this.options.serviceVersion,
|
|
23
|
+
}));
|
|
24
|
+
const tracerProvider = new sdk_trace_web_1.WebTracerProvider({ resource });
|
|
25
|
+
tracerProvider.addSpanProcessor(new sdk_trace_base_1.SimpleSpanProcessor(new sdk_trace_base_1.ConsoleSpanExporter()));
|
|
26
|
+
tracerProvider.addSpanProcessor(new sdk_trace_base_1.BatchSpanProcessor(new exporter_trace_otlp_http_1.OTLPTraceExporter({
|
|
27
|
+
url: this.options.endpoint + '/v1/traces',
|
|
28
|
+
headers: {
|
|
29
|
+
Authorization: this.options.authorizationHeader,
|
|
30
|
+
},
|
|
31
|
+
concurrencyLimit: 10, // an optional limit on pending requests
|
|
32
|
+
})));
|
|
33
|
+
// TODO(nf): ContextManager? Propogator?
|
|
34
|
+
tracerProvider.register({});
|
|
35
|
+
this._tracer = api_1.trace.getTracer('dxos-observability', this.options.serviceVersion);
|
|
36
|
+
}
|
|
37
|
+
start() {
|
|
38
|
+
(0, instrumentation_1.registerInstrumentations)({
|
|
39
|
+
instrumentations: [(0, auto_instrumentations_web_1.getWebAutoInstrumentations)()],
|
|
40
|
+
});
|
|
41
|
+
(0, log_1.log)('trace processor registered');
|
|
42
|
+
tracing_1.TRACE_PROCESSOR.remoteTracing.registerProcessor({
|
|
43
|
+
startSpan: (options) => {
|
|
44
|
+
(0, log_1.log)('begin otel trace', { options });
|
|
45
|
+
return this._tracer.startSpan(options.name, options);
|
|
46
|
+
},
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
exports.OtelTraces = OtelTraces;
|
|
51
|
+
//# sourceMappingURL=traces-browser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"traces-browser.js","sourceRoot":"","sources":["../../../../src/otel/traces-browser.ts"],"names":[],"mappings":";AAAA,EAAE;AACF,0BAA0B;AAC1B,EAAE;;;AAEF,4CAAwD;AACxD,wFAAsF;AACtF,sFAA4E;AAC5E,oEAA0E;AAC1E,wDAAoD;AACpD,kEAA6G;AAC7G,gEAAiE;AACjE,8EAA4G;AAE5G,mCAAgC;AAChC,2CAAuE;AAIvE,MAAa,UAAU;IAErB,YAA6B,OAAoB;QAApB,YAAO,GAAP,OAAO,CAAa;QAC/C,MAAM,QAAQ,GAAG,oBAAQ,CAAC,OAAO,EAAE,CAAC,KAAK,CACvC,IAAI,oBAAQ,CAAC;YACX,CAAC,+CAAwB,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,WAAW;YACpD,CAAC,kDAA2B,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,cAAc;SAC3D,CAAC,CACH,CAAC;QAEF,MAAM,cAAc,GAAG,IAAI,iCAAiB,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC;QAC3D,cAAc,CAAC,gBAAgB,CAAC,IAAI,oCAAmB,CAAC,IAAI,oCAAmB,EAAE,CAAC,CAAC,CAAC;QACpF,cAAc,CAAC,gBAAgB,CAC7B,IAAI,mCAAkB,CACpB,IAAI,4CAAiB,CAAC;YACpB,GAAG,EAAE,IAAI,CAAC,OAAO,CAAC,QAAQ,GAAG,YAAY;YACzC,OAAO,EAAE;gBACP,aAAa,EAAE,IAAI,CAAC,OAAO,CAAC,mBAAmB;aAChD;YACD,gBAAgB,EAAE,EAAE,EAAE,wCAAwC;SAC/D,CAAC,CACH,CACF,CAAC;QACF,wCAAwC;QACxC,cAAc,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QAC5B,IAAI,CAAC,OAAO,GAAG,WAAK,CAAC,SAAS,CAAC,oBAAoB,EAAE,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;IACpF,CAAC;IAEM,KAAK;QACV,IAAA,0CAAwB,EAAC;YACvB,gBAAgB,EAAE,CAAC,IAAA,sDAA0B,GAAE,CAAC;SACjD,CAAC,CAAC;QACH,IAAA,SAAG,EAAC,4BAA4B,CAAC,CAAC;QAClC,yBAAe,CAAC,aAAa,CAAC,iBAAiB,CAAC;YAC9C,SAAS,EAAE,CAAC,OAAyB,EAAE,EAAE;gBACvC,IAAA,SAAG,EAAC,kBAAkB,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;gBACrC,OAAO,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;YACvD,CAAC;SACF,CAAC,CAAC;IACL,CAAC;CACF;AAxCD,gCAwCC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"traces.d.ts","sourceRoot":"","sources":["../../../../src/otel/traces.ts"],"names":[],"mappings":"AAkBA,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,QAAQ,CAAC;AAE1C,qBAAa,UAAU;IAET,OAAO,CAAC,QAAQ,CAAC,OAAO;IADpC,OAAO,CAAC,OAAO,CAAS;gBACK,OAAO,EAAE,WAAW;IAyB1C,KAAK;CASb"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
//
|
|
3
|
+
// Copyright 2024 DXOS.org
|
|
4
|
+
//
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.OtelTraces = void 0;
|
|
7
|
+
const api_1 = require("@opentelemetry/api");
|
|
8
|
+
const exporter_trace_otlp_http_1 = require("@opentelemetry/exporter-trace-otlp-http");
|
|
9
|
+
const resources_1 = require("@opentelemetry/resources");
|
|
10
|
+
const sdk_trace_base_1 = require("@opentelemetry/sdk-trace-base");
|
|
11
|
+
const semantic_conventions_1 = require("@opentelemetry/semantic-conventions");
|
|
12
|
+
const debug_1 = require("debug");
|
|
13
|
+
const tracing_1 = require("@dxos/tracing");
|
|
14
|
+
class OtelTraces {
|
|
15
|
+
constructor(options) {
|
|
16
|
+
this.options = options;
|
|
17
|
+
const resource = resources_1.Resource.default().merge(new resources_1.Resource({
|
|
18
|
+
[semantic_conventions_1.SEMRESATTRS_SERVICE_NAME]: this.options.serviceName,
|
|
19
|
+
[semantic_conventions_1.SEMRESATTRS_SERVICE_VERSION]: this.options.serviceVersion,
|
|
20
|
+
}));
|
|
21
|
+
const tracerProvider = new sdk_trace_base_1.BasicTracerProvider({ resource });
|
|
22
|
+
tracerProvider.addSpanProcessor(new sdk_trace_base_1.SimpleSpanProcessor(new sdk_trace_base_1.ConsoleSpanExporter()));
|
|
23
|
+
tracerProvider.addSpanProcessor(new sdk_trace_base_1.BatchSpanProcessor(new exporter_trace_otlp_http_1.OTLPTraceExporter({
|
|
24
|
+
url: this.options.endpoint + '/v1/traces',
|
|
25
|
+
headers: {
|
|
26
|
+
Authorization: this.options.authorizationHeader,
|
|
27
|
+
},
|
|
28
|
+
concurrencyLimit: 10, // an optional limit on pending requests
|
|
29
|
+
})));
|
|
30
|
+
tracerProvider.register();
|
|
31
|
+
this._tracer = api_1.trace.getTracer('dxos-observability', this.options.serviceVersion);
|
|
32
|
+
}
|
|
33
|
+
start() {
|
|
34
|
+
(0, debug_1.log)('trace processor registered');
|
|
35
|
+
tracing_1.TRACE_PROCESSOR.remoteTracing.registerProcessor({
|
|
36
|
+
startSpan: (options) => {
|
|
37
|
+
(0, debug_1.log)('begin otel trace', { options });
|
|
38
|
+
return this._tracer.startSpan(options.name, options);
|
|
39
|
+
},
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
exports.OtelTraces = OtelTraces;
|
|
44
|
+
//# sourceMappingURL=traces.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"traces.js","sourceRoot":"","sources":["../../../../src/otel/traces.ts"],"names":[],"mappings":";AAAA,EAAE;AACF,0BAA0B;AAC1B,EAAE;;;AAEF,4CAAwD;AACxD,sFAA4E;AAC5E,wDAAoD;AACpD,kEAKuC;AACvC,8EAA4G;AAC5G,iCAA4B;AAE5B,2CAAuE;AAIvE,MAAa,UAAU;IAErB,YAA6B,OAAoB;QAApB,YAAO,GAAP,OAAO,CAAa;QAC/C,MAAM,QAAQ,GAAG,oBAAQ,CAAC,OAAO,EAAE,CAAC,KAAK,CACvC,IAAI,oBAAQ,CAAC;YACX,CAAC,+CAAwB,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,WAAW;YACpD,CAAC,kDAA2B,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,cAAc;SAC3D,CAAC,CACH,CAAC;QAEF,MAAM,cAAc,GAAG,IAAI,oCAAmB,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC;QAC7D,cAAc,CAAC,gBAAgB,CAAC,IAAI,oCAAmB,CAAC,IAAI,oCAAmB,EAAE,CAAC,CAAC,CAAC;QACpF,cAAc,CAAC,gBAAgB,CAC7B,IAAI,mCAAkB,CACpB,IAAI,4CAAiB,CAAC;YACpB,GAAG,EAAE,IAAI,CAAC,OAAO,CAAC,QAAQ,GAAG,YAAY;YACzC,OAAO,EAAE;gBACP,aAAa,EAAE,IAAI,CAAC,OAAO,CAAC,mBAAmB;aAChD;YACD,gBAAgB,EAAE,EAAE,EAAE,wCAAwC;SAC/D,CAAC,CACH,CACF,CAAC;QACF,cAAc,CAAC,QAAQ,EAAE,CAAC;QAC1B,IAAI,CAAC,OAAO,GAAG,WAAK,CAAC,SAAS,CAAC,oBAAoB,EAAE,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;IACpF,CAAC;IAEM,KAAK;QACV,IAAA,WAAG,EAAC,4BAA4B,CAAC,CAAC;QAClC,yBAAe,CAAC,aAAa,CAAC,iBAAiB,CAAC;YAC9C,SAAS,EAAE,CAAC,OAAyB,EAAE,EAAE;gBACvC,IAAA,WAAG,EAAC,kBAAkB,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;gBACrC,OAAO,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;YACvD,CAAC;SACF,CAAC,CAAC;IACL,CAAC;CACF;AApCD,gCAoCC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dxos/observability",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.3-main.0308ae2",
|
|
4
4
|
"description": "Provides a common interface for app and platform observability",
|
|
5
5
|
"homepage": "https://dxos.org",
|
|
6
6
|
"bugs": "https://github.com/dxos/dxos/issues",
|
|
@@ -37,7 +37,8 @@
|
|
|
37
37
|
"./src/datadog/node.ts": "./src/datadog/browser.ts",
|
|
38
38
|
"./src/segment/node.ts": "./src/segment/browser.ts",
|
|
39
39
|
"./src/sentry/node.ts": "./src/sentry/browser.ts",
|
|
40
|
-
"./testing/testkit/index.ts": "./testing/testkit/browser.ts"
|
|
40
|
+
"./testing/testkit/index.ts": "./testing/testkit/browser.ts",
|
|
41
|
+
"./src/otel/traces.ts": "./src/otel/traces-browser.ts"
|
|
41
42
|
},
|
|
42
43
|
"types": "dist/types/src/index.d.ts",
|
|
43
44
|
"typesVersions": {
|
|
@@ -58,35 +59,49 @@
|
|
|
58
59
|
"src"
|
|
59
60
|
],
|
|
60
61
|
"dependencies": {
|
|
62
|
+
"@opentelemetry/api": "^1.9.0",
|
|
63
|
+
"@opentelemetry/api-logs": "^0.52.1",
|
|
64
|
+
"@opentelemetry/auto-instrumentations-web": "^0.40.0",
|
|
65
|
+
"@opentelemetry/exporter-logs-otlp-http": "^0.52.1",
|
|
66
|
+
"@opentelemetry/exporter-metrics-otlp-http": "^0.52.0",
|
|
67
|
+
"@opentelemetry/exporter-trace-otlp-http": "^0.52.1",
|
|
68
|
+
"@opentelemetry/instrumentation": "^0.52.1",
|
|
69
|
+
"@opentelemetry/resources": "^1.25.1",
|
|
70
|
+
"@opentelemetry/sdk-logs": "^0.52.1",
|
|
71
|
+
"@opentelemetry/sdk-metrics": "^1.25.1",
|
|
72
|
+
"@opentelemetry/sdk-trace-base": "^1.25.1",
|
|
73
|
+
"@opentelemetry/sdk-trace-web": "^1.25.1",
|
|
74
|
+
"@opentelemetry/semantic-conventions": "^1.25.0",
|
|
61
75
|
"@segment/analytics-node": "^2.1.0",
|
|
62
76
|
"@segment/snippet": "^4.15.3",
|
|
63
|
-
"@sentry/browser": "^8.
|
|
64
|
-
"@sentry/node": "^8.
|
|
77
|
+
"@sentry/browser": "^8.8.0",
|
|
78
|
+
"@sentry/node": "^8.8.0",
|
|
65
79
|
"datadog-metrics": "^0.11.1",
|
|
66
80
|
"debug": "^4.3.4",
|
|
67
81
|
"js-yaml": "^4.1.0",
|
|
68
82
|
"localforage": "^1.10.0",
|
|
69
83
|
"uuid": "^9.0.0",
|
|
70
|
-
"@dxos/async": "0.6.
|
|
71
|
-
"@dxos/client": "0.6.
|
|
72
|
-
"@dxos/
|
|
73
|
-
"@dxos/config": "0.6.
|
|
74
|
-
"@dxos/client
|
|
75
|
-
"@dxos/
|
|
76
|
-
"@dxos/debug": "0.6.
|
|
77
|
-
"@dxos/invariant": "0.6.
|
|
78
|
-
"@dxos/log": "0.6.
|
|
79
|
-
"@dxos/
|
|
80
|
-
"@dxos/
|
|
81
|
-
"@dxos/protocols": "0.6.
|
|
82
|
-
"@dxos/tracing": "0.6.
|
|
83
|
-
"@dxos/util": "0.6.
|
|
84
|
+
"@dxos/async": "0.6.3-main.0308ae2",
|
|
85
|
+
"@dxos/client-protocol": "0.6.3-main.0308ae2",
|
|
86
|
+
"@dxos/context": "0.6.3-main.0308ae2",
|
|
87
|
+
"@dxos/config": "0.6.3-main.0308ae2",
|
|
88
|
+
"@dxos/client": "0.6.3-main.0308ae2",
|
|
89
|
+
"@dxos/client-services": "0.6.3-main.0308ae2",
|
|
90
|
+
"@dxos/debug": "0.6.3-main.0308ae2",
|
|
91
|
+
"@dxos/invariant": "0.6.3-main.0308ae2",
|
|
92
|
+
"@dxos/log": "0.6.3-main.0308ae2",
|
|
93
|
+
"@dxos/network-manager": "0.6.3-main.0308ae2",
|
|
94
|
+
"@dxos/node-std": "0.6.3-main.0308ae2",
|
|
95
|
+
"@dxos/protocols": "0.6.3-main.0308ae2",
|
|
96
|
+
"@dxos/tracing": "0.6.3-main.0308ae2",
|
|
97
|
+
"@dxos/util": "0.6.3-main.0308ae2"
|
|
84
98
|
},
|
|
85
99
|
"devDependencies": {
|
|
86
|
-
"@sentry/types": "^8.
|
|
100
|
+
"@sentry/types": "^8.8.0",
|
|
87
101
|
"@types/debug": "^4.1.10",
|
|
88
102
|
"@types/js-yaml": "^4.0.5",
|
|
89
|
-
"sentry-testkit": "^5.0.5"
|
|
103
|
+
"sentry-testkit": "^5.0.5",
|
|
104
|
+
"zone.js": ">=0.11.4 <0.12.0-0 || >=0.13.0 <0.14.0-0 || >=0.14.0 <0.15.0-0"
|
|
90
105
|
},
|
|
91
106
|
"publishConfig": {
|
|
92
107
|
"access": "public"
|
|
@@ -3,5 +3,7 @@
|
|
|
3
3
|
"TELEMETRY_API_KEY": "B00QG6PtJJrJ0VVFe0H5a6bcUUShKyZM",
|
|
4
4
|
"IPDATA_API_KEY": "73dfdecdf979c18f07d50cf841bbdd9e589f237256326ac8cca23786",
|
|
5
5
|
"DATADOG_API_KEY": null,
|
|
6
|
-
"DATADOG_APP_KEY": null
|
|
6
|
+
"DATADOG_APP_KEY": null,
|
|
7
|
+
"OTEL_ENDPOINT": null,
|
|
8
|
+
"OTEL_AUTHORIZATION": null
|
|
7
9
|
}
|
|
@@ -155,6 +155,7 @@ export const initializeAppObservability = async ({
|
|
|
155
155
|
// TODO(nf): should provide capability to init Sentry earlier in booting process to capture errors during initialization.
|
|
156
156
|
|
|
157
157
|
await observability.initialize();
|
|
158
|
+
observability.startErrorLogs();
|
|
158
159
|
|
|
159
160
|
const ipData = await getIPData(config);
|
|
160
161
|
|
package/src/observability.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
import { Event, scheduleTaskInterval } from '@dxos/async';
|
|
6
6
|
import { type Client, type Config } from '@dxos/client';
|
|
7
|
-
import { type Space } from '@dxos/client-protocol';
|
|
7
|
+
import { type ClientServices, type Space } from '@dxos/client-protocol';
|
|
8
8
|
import { Context } from '@dxos/context';
|
|
9
9
|
import { invariant } from '@dxos/invariant';
|
|
10
10
|
import { log } from '@dxos/log';
|
|
@@ -15,9 +15,10 @@ import { isNode } from '@dxos/util';
|
|
|
15
15
|
import buildSecrets from './cli-observability-secrets.json';
|
|
16
16
|
import { type DatadogMetrics } from './datadog';
|
|
17
17
|
import { type IPData, getTelemetryIdentifier, mapSpaces } from './helpers';
|
|
18
|
+
import { type OtelLogs, type OtelMetrics, type OtelTraces } from './otel';
|
|
18
19
|
import { type SegmentTelemetry, type EventOptions, type PageOptions } from './segment';
|
|
19
20
|
import { type InitOptions, type captureException as SentryCaptureException } from './sentry';
|
|
20
|
-
import { SentryLogProcessor } from './sentry/sentry-log-processor';
|
|
21
|
+
import { type SentryLogProcessor } from './sentry/sentry-log-processor';
|
|
21
22
|
|
|
22
23
|
const SPACE_METRICS_MIN_INTERVAL = 1000 * 60; // 1 minute
|
|
23
24
|
const SPACE_TELEMETRY_MIN_INTERVAL = 1000 * 60 * 60; // 1 hour
|
|
@@ -33,6 +34,8 @@ export type ObservabilitySecrets = {
|
|
|
33
34
|
IPDATA_API_KEY: string | null;
|
|
34
35
|
DATADOG_API_KEY: string | null;
|
|
35
36
|
DATADOG_APP_KEY: string | null;
|
|
37
|
+
OTEL_ENDPOINT: string | null;
|
|
38
|
+
OTEL_AUTHORIZATION: string | null;
|
|
36
39
|
};
|
|
37
40
|
|
|
38
41
|
export type Mode = 'basic' | 'full' | 'disabled';
|
|
@@ -66,10 +69,14 @@ export type ObservabilityOptions = {
|
|
|
66
69
|
export class Observability {
|
|
67
70
|
// TODO(wittjosiah): Generic metrics interface.
|
|
68
71
|
private _metrics?: DatadogMetrics;
|
|
72
|
+
private _otelMetrics?: OtelMetrics;
|
|
73
|
+
private _otelTraces?: OtelTraces;
|
|
69
74
|
// TODO(wittjosiah): Generic telemetry interface.
|
|
70
75
|
private _telemetryBatchSize: number;
|
|
71
76
|
private _telemetry?: SegmentTelemetry;
|
|
72
77
|
// TODO(wittjosiah): Generic error logging interface.
|
|
78
|
+
private _sentryLogProcessor?: SentryLogProcessor;
|
|
79
|
+
private _otelLogs?: OtelLogs;
|
|
73
80
|
private _errorReportingOptions?: InitOptions;
|
|
74
81
|
private _captureException?: typeof SentryCaptureException;
|
|
75
82
|
private _captureUserFeedback?: (name: string, email: string, message: string) => Promise<void>;
|
|
@@ -135,11 +142,14 @@ export class Observability {
|
|
|
135
142
|
|
|
136
143
|
process.env.DX_ENVIRONMENT && (mergedSecrets.DX_ENVIRONMENT = process.env.DX_ENVIRONMENT);
|
|
137
144
|
process.env.DX_RELEASE && (mergedSecrets.DX_RELEASE = process.env.DX_RELEASE);
|
|
145
|
+
// TODO: prefix these with DX_?
|
|
138
146
|
process.env.SENTRY_DESTINATION && (mergedSecrets.SENTRY_DESTINATION = process.env.SENTRY_DESTINATION);
|
|
139
147
|
process.env.TELEMETRY_API_KEY && (mergedSecrets.TELEMETRY_API_KEY = process.env.TELEMETRY_API_KEY);
|
|
140
148
|
process.env.IPDATA_API_KEY && (mergedSecrets.IPDATA_API_KEY = process.env.IPDATA_API_KEY);
|
|
141
149
|
process.env.DATADOG_API_KEY && (mergedSecrets.DATADOG_API_KEY = process.env.DATADOG_API_KEY);
|
|
142
150
|
process.env.DATADOG_APP_KEY && (mergedSecrets.DATADOG_APP_KEY = process.env.DATADOG_APP_KEY);
|
|
151
|
+
process.env.DX_OTEL_ENDPOINT && (mergedSecrets.OTEL_ENDPOINT = process.env.DX_OTEL_ENDPOINT);
|
|
152
|
+
process.env.DX_OTEL_AUTHORIZATION && (mergedSecrets.OTEL_AUTHORIZATION = process.env.DX_OTEL_AUTHORIZATION);
|
|
143
153
|
|
|
144
154
|
return mergedSecrets;
|
|
145
155
|
} else {
|
|
@@ -152,6 +162,8 @@ export class Observability {
|
|
|
152
162
|
IPDATA_API_KEY: config?.get('runtime.app.env.DX_IPDATA_API_KEY'),
|
|
153
163
|
DATADOG_API_KEY: config?.get('runtime.app.env.DX_DATADOG_API_KEY'),
|
|
154
164
|
DATADOG_APP_KEY: config?.get('runtime.app.env.DX_DATADOG_APP_KEY'),
|
|
165
|
+
OTEL_ENDPOINT: config?.get('runtime.app.env.DX_OTEL_ENDPOINT'),
|
|
166
|
+
OTEL_AUTHORIZATION: config?.get('runtime.app.env.DX_OTEL_AUTHORIZATION'),
|
|
155
167
|
...secrets,
|
|
156
168
|
};
|
|
157
169
|
}
|
|
@@ -161,12 +173,16 @@ export class Observability {
|
|
|
161
173
|
await this._initMetrics();
|
|
162
174
|
await this._initTelemetry();
|
|
163
175
|
await this._initErrorLogs();
|
|
176
|
+
await this._initTraces();
|
|
164
177
|
}
|
|
165
178
|
|
|
166
179
|
async close() {
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
180
|
+
const closes: Promise<void>[] = [];
|
|
181
|
+
this._telemetry && closes.push(this._telemetry.close());
|
|
182
|
+
this._otelMetrics && closes.push(this._otelMetrics.close());
|
|
183
|
+
this._otelLogs && closes.push(this._otelLogs.close());
|
|
184
|
+
|
|
185
|
+
await Promise.all(closes);
|
|
170
186
|
await this._ctx.dispose();
|
|
171
187
|
|
|
172
188
|
// TODO(wittjosiah): Remove telemetry, etc. scripts.
|
|
@@ -203,33 +219,36 @@ export class Observability {
|
|
|
203
219
|
};
|
|
204
220
|
|
|
205
221
|
// TODO(wittjosiah): Improve privacy of telemetry identifiers. See `getTelemetryIdentifier`.
|
|
206
|
-
async setIdentityTags(
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
222
|
+
async setIdentityTags(clientServices: Partial<ClientServices>) {
|
|
223
|
+
if (clientServices.IdentityService) {
|
|
224
|
+
clientServices.IdentityService.queryIdentity().subscribe((idqr) => {
|
|
225
|
+
if (!idqr?.identity?.identityKey) {
|
|
226
|
+
log('empty response from identity service', { idqr });
|
|
227
|
+
return;
|
|
228
|
+
}
|
|
229
|
+
this.setTag('identityKey', idqr.identity.identityKey.truncate());
|
|
230
|
+
});
|
|
231
|
+
}
|
|
215
232
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
233
|
+
if (clientServices.DevicesService) {
|
|
234
|
+
clientServices.DevicesService.queryDevices().subscribe((dqr) => {
|
|
235
|
+
if (!dqr || !dqr.devices || dqr.devices.length === 0) {
|
|
236
|
+
log('empty response from device service', { device: dqr });
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
invariant(dqr, 'empty response from device service');
|
|
222
240
|
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
241
|
+
const thisDevice = dqr.devices.find((device) => device.kind === DeviceKind.CURRENT);
|
|
242
|
+
if (!thisDevice) {
|
|
243
|
+
log('no current device', { device: dqr });
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
246
|
+
this.setTag('deviceKey', thisDevice.deviceKey.truncate());
|
|
247
|
+
if (thisDevice.profile?.label) {
|
|
248
|
+
this.setTag('deviceProfile', thisDevice.profile.label);
|
|
249
|
+
}
|
|
250
|
+
});
|
|
251
|
+
}
|
|
233
252
|
}
|
|
234
253
|
|
|
235
254
|
//
|
|
@@ -255,6 +274,27 @@ export class Observability {
|
|
|
255
274
|
} else {
|
|
256
275
|
log('datadog disabled');
|
|
257
276
|
}
|
|
277
|
+
|
|
278
|
+
if (this.enabled && this._secrets.OTEL_ENDPOINT && this._secrets.OTEL_AUTHORIZATION) {
|
|
279
|
+
const { OtelMetrics } = await import('./otel');
|
|
280
|
+
this._otelMetrics = new OtelMetrics({
|
|
281
|
+
endpoint: this._secrets.OTEL_ENDPOINT,
|
|
282
|
+
authorizationHeader: this._secrets.OTEL_AUTHORIZATION,
|
|
283
|
+
serviceName: this._namespace,
|
|
284
|
+
serviceVersion: this.getTag('release')?.value ?? '0.0.0',
|
|
285
|
+
getTags: () =>
|
|
286
|
+
Object.fromEntries(
|
|
287
|
+
Array.from(this._tags)
|
|
288
|
+
.filter(([key, value]) => {
|
|
289
|
+
return value.scope === 'all' || value.scope === 'metrics';
|
|
290
|
+
})
|
|
291
|
+
.map(([key, value]) => [key, value.value]),
|
|
292
|
+
),
|
|
293
|
+
});
|
|
294
|
+
log('otel metrics enabled');
|
|
295
|
+
} else {
|
|
296
|
+
log('otel metrics disabled');
|
|
297
|
+
}
|
|
258
298
|
}
|
|
259
299
|
|
|
260
300
|
/**
|
|
@@ -264,11 +304,15 @@ export class Observability {
|
|
|
264
304
|
*/
|
|
265
305
|
gauge(name: string, value: number | any, extraTags?: any) {
|
|
266
306
|
this._metrics?.gauge(name, value, extraTags);
|
|
307
|
+
this._otelMetrics?.gauge(name, value, extraTags);
|
|
267
308
|
}
|
|
268
309
|
|
|
269
310
|
// TODO(nf): Refactor into ObservabilityExtensions.
|
|
270
311
|
|
|
271
|
-
startNetworkMetrics(
|
|
312
|
+
startNetworkMetrics(clientServices: Partial<ClientServices>) {
|
|
313
|
+
if (!clientServices.NetworkService) {
|
|
314
|
+
return;
|
|
315
|
+
}
|
|
272
316
|
// TODO(nf): support type in debounce()
|
|
273
317
|
const updateSignalMetrics = new Event<NetworkStatus>().debounce(NETWORK_METRICS_MIN_INTERVAL);
|
|
274
318
|
updateSignalMetrics.on(this._ctx, async () => {
|
|
@@ -310,7 +354,7 @@ export class Observability {
|
|
|
310
354
|
});
|
|
311
355
|
});
|
|
312
356
|
|
|
313
|
-
|
|
357
|
+
clientServices.NetworkService.queryStatus().subscribe((networkStatus) => {
|
|
314
358
|
this._lastNetworkStatus = networkStatus;
|
|
315
359
|
updateSignalMetrics.emit();
|
|
316
360
|
});
|
|
@@ -393,14 +437,20 @@ export class Observability {
|
|
|
393
437
|
scheduleTaskInterval(
|
|
394
438
|
this._ctx,
|
|
395
439
|
async () => {
|
|
396
|
-
|
|
440
|
+
if (client.services.constructor.name === 'WorkerClientServices') {
|
|
441
|
+
const memory = (window.performance as any).memory;
|
|
442
|
+
if (memory) {
|
|
443
|
+
this.gauge('dxos.client.runtime.heapTotal', memory.totalJSHeapSize);
|
|
444
|
+
this.gauge('dxos.client.runtime.heapUsed', memory.usedJSHeapSize);
|
|
445
|
+
this.gauge('dxos.client.runtime.heapSizeLimit', memory.jsHeapSizeLimit);
|
|
446
|
+
}
|
|
447
|
+
}
|
|
397
448
|
client.services.services.SystemService?.getPlatform()
|
|
398
449
|
.then((platform) => {
|
|
399
|
-
log('platform', { platform });
|
|
400
450
|
if (platform.memory) {
|
|
401
|
-
this.gauge('dxos.client.runtime.rss', platform.memory.rss);
|
|
402
|
-
this.gauge('dxos.client.runtime.heapTotal', platform.memory.heapTotal);
|
|
403
|
-
this.gauge('dxos.client.runtime.heapUsed', platform.memory.heapUsed);
|
|
451
|
+
this.gauge('dxos.client.services.runtime.rss', platform.memory.rss);
|
|
452
|
+
this.gauge('dxos.client.services.runtime.heapTotal', platform.memory.heapTotal);
|
|
453
|
+
this.gauge('dxos.client.services.runtime.heapUsed', platform.memory.heapUsed);
|
|
404
454
|
}
|
|
405
455
|
})
|
|
406
456
|
.catch((error) => log('platform error', { error }));
|
|
@@ -458,6 +508,7 @@ export class Observability {
|
|
|
458
508
|
private async _initErrorLogs() {
|
|
459
509
|
if (this._secrets.SENTRY_DESTINATION && this._mode !== 'disabled') {
|
|
460
510
|
const { captureException, captureUserFeedback, init, setTag } = await import('./sentry');
|
|
511
|
+
const { SentryLogProcessor } = await import('./sentry/sentry-log-processor');
|
|
461
512
|
this._captureException = captureException;
|
|
462
513
|
this._captureUserFeedback = captureUserFeedback;
|
|
463
514
|
|
|
@@ -468,17 +519,14 @@ export class Observability {
|
|
|
468
519
|
dest: this._secrets.SENTRY_DESTINATION,
|
|
469
520
|
options: this._errorReportingOptions,
|
|
470
521
|
});
|
|
471
|
-
|
|
472
|
-
const logProcessor = new SentryLogProcessor();
|
|
522
|
+
this._sentryLogProcessor = new SentryLogProcessor();
|
|
473
523
|
init({
|
|
474
524
|
...this._errorReportingOptions,
|
|
475
525
|
destination: this._secrets.SENTRY_DESTINATION,
|
|
476
526
|
scrubFilenames: this._mode !== 'full',
|
|
477
|
-
onError: (event) =>
|
|
527
|
+
onError: (event) => this._sentryLogProcessor!.addLogBreadcrumbsTo(event),
|
|
478
528
|
});
|
|
479
|
-
|
|
480
529
|
// TODO(nf): set platform at instantiation? needed for node.
|
|
481
|
-
log.runtimeConfig.processors.push(logProcessor.logProcessor);
|
|
482
530
|
|
|
483
531
|
// TODO(nf): is this different than passing as properties in options?
|
|
484
532
|
this._tags.forEach((v, k) => {
|
|
@@ -489,6 +537,57 @@ export class Observability {
|
|
|
489
537
|
} else {
|
|
490
538
|
log('sentry disabled');
|
|
491
539
|
}
|
|
540
|
+
|
|
541
|
+
if (this._secrets.OTEL_ENDPOINT && this._secrets.OTEL_AUTHORIZATION && this._mode !== 'disabled') {
|
|
542
|
+
const { OtelLogs } = await import('./otel');
|
|
543
|
+
this._otelLogs = new OtelLogs({
|
|
544
|
+
endpoint: this._secrets.OTEL_ENDPOINT,
|
|
545
|
+
authorizationHeader: this._secrets.OTEL_AUTHORIZATION,
|
|
546
|
+
serviceName: this._namespace,
|
|
547
|
+
serviceVersion: this.getTag('release')?.value ?? '0.0.0',
|
|
548
|
+
getTags: () =>
|
|
549
|
+
Object.fromEntries(
|
|
550
|
+
Array.from(this._tags)
|
|
551
|
+
.filter(([key, value]) => {
|
|
552
|
+
return value.scope === 'all' || value.scope === 'errors';
|
|
553
|
+
})
|
|
554
|
+
.map(([key, value]) => [key, value.value]),
|
|
555
|
+
),
|
|
556
|
+
});
|
|
557
|
+
log('otel logs enabled', { namespace: this._namespace });
|
|
558
|
+
} else {
|
|
559
|
+
log('otel logs disabled');
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
startErrorLogs() {
|
|
564
|
+
this._sentryLogProcessor && log.runtimeConfig.processors.push(this._sentryLogProcessor.logProcessor);
|
|
565
|
+
this._otelLogs && log.runtimeConfig.processors.push(this._otelLogs.logProcessor);
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
startTraces() {
|
|
569
|
+
this._otelTraces && this._otelTraces.start();
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
// TODO(nf): refactor init based on providers and their capabilities
|
|
573
|
+
private async _initTraces() {
|
|
574
|
+
if (this._secrets.OTEL_ENDPOINT && this._secrets.OTEL_AUTHORIZATION && this._mode !== 'disabled') {
|
|
575
|
+
const { OtelTraces } = await import('./otel');
|
|
576
|
+
this._otelTraces = new OtelTraces({
|
|
577
|
+
endpoint: this._secrets.OTEL_ENDPOINT,
|
|
578
|
+
authorizationHeader: this._secrets.OTEL_AUTHORIZATION,
|
|
579
|
+
serviceName: this._namespace,
|
|
580
|
+
serviceVersion: this.getTag('release')?.value ?? '0.0.0',
|
|
581
|
+
getTags: () =>
|
|
582
|
+
Object.fromEntries(
|
|
583
|
+
Array.from(this._tags)
|
|
584
|
+
.filter(([key, value]) => {
|
|
585
|
+
return value.scope === 'all' || value.scope === 'metrics';
|
|
586
|
+
})
|
|
587
|
+
.map(([key, value]) => [key, value.value]),
|
|
588
|
+
),
|
|
589
|
+
});
|
|
590
|
+
}
|
|
492
591
|
}
|
|
493
592
|
|
|
494
593
|
/**
|