@dxos/observability 0.10.0 → 0.11.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.
Files changed (60) hide show
  1. package/dist/lib/chunk-log-processor.mjs +28 -0
  2. package/dist/lib/chunk-log-processor.mjs.map +1 -0
  3. package/dist/lib/chunk-logs.mjs +89 -0
  4. package/dist/lib/chunk-logs.mjs.map +1 -0
  5. package/dist/lib/chunk-metrics.mjs +118 -0
  6. package/dist/lib/chunk-metrics.mjs.map +1 -0
  7. package/dist/lib/chunk-otel.mjs +20 -0
  8. package/dist/lib/chunk-otel.mjs.map +1 -0
  9. package/dist/lib/chunk-traces-browser.mjs +145 -0
  10. package/dist/lib/chunk-traces-browser.mjs.map +1 -0
  11. package/dist/lib/index.mjs +977 -0
  12. package/dist/lib/index.mjs.map +1 -0
  13. package/dist/types/src/cli-observability-secrets.json +2 -2
  14. package/dist/types/src/extensions/otel/logs.d.ts +1 -0
  15. package/dist/types/src/extensions/otel/logs.d.ts.map +1 -1
  16. package/dist/types/src/extensions/otel/logs.js +11 -4
  17. package/dist/types/src/extensions/otel/logs.js.map +1 -1
  18. package/dist/types/src/extensions/otel/logs.test.d.ts +2 -0
  19. package/dist/types/src/extensions/otel/logs.test.d.ts.map +1 -0
  20. package/dist/types/src/extensions/otel/logs.test.js +33 -0
  21. package/dist/types/src/extensions/otel/logs.test.js.map +1 -0
  22. package/dist/types/src/extensions/posthog/extension.d.ts.map +1 -1
  23. package/dist/types/src/extensions/posthog/extension.js +4 -0
  24. package/dist/types/src/extensions/posthog/extension.js.map +1 -1
  25. package/dist/types/tsconfig.tsbuildinfo +1 -1
  26. package/package.json +31 -31
  27. package/src/cli-observability-secrets.json +2 -2
  28. package/src/extensions/otel/logs.test.ts +39 -0
  29. package/src/extensions/otel/logs.ts +11 -4
  30. package/src/extensions/posthog/extension.ts +4 -0
  31. package/dist/lib/browser/chunk-J5LGTIGS.mjs +0 -10
  32. package/dist/lib/browser/chunk-J5LGTIGS.mjs.map +0 -7
  33. package/dist/lib/browser/chunk-PSFTIG54.mjs +0 -20
  34. package/dist/lib/browser/chunk-PSFTIG54.mjs.map +0 -7
  35. package/dist/lib/browser/index.mjs +0 -1015
  36. package/dist/lib/browser/index.mjs.map +0 -7
  37. package/dist/lib/browser/log-processor-MZCTEVJC.mjs +0 -46
  38. package/dist/lib/browser/log-processor-MZCTEVJC.mjs.map +0 -7
  39. package/dist/lib/browser/logs-UTNIFYHF.mjs +0 -116
  40. package/dist/lib/browser/logs-UTNIFYHF.mjs.map +0 -7
  41. package/dist/lib/browser/meta.json +0 -1
  42. package/dist/lib/browser/metrics-PRGSYAZJ.mjs +0 -116
  43. package/dist/lib/browser/metrics-PRGSYAZJ.mjs.map +0 -7
  44. package/dist/lib/browser/traces-browser-H4NCYCVZ.mjs +0 -154
  45. package/dist/lib/browser/traces-browser-H4NCYCVZ.mjs.map +0 -7
  46. package/dist/lib/node-esm/chunk-EDDZWPYV.mjs +0 -22
  47. package/dist/lib/node-esm/chunk-EDDZWPYV.mjs.map +0 -7
  48. package/dist/lib/node-esm/chunk-HSLMI22Q.mjs +0 -11
  49. package/dist/lib/node-esm/chunk-HSLMI22Q.mjs.map +0 -7
  50. package/dist/lib/node-esm/index.mjs +0 -1021
  51. package/dist/lib/node-esm/index.mjs.map +0 -7
  52. package/dist/lib/node-esm/log-processor-GA24XTJF.mjs +0 -47
  53. package/dist/lib/node-esm/log-processor-GA24XTJF.mjs.map +0 -7
  54. package/dist/lib/node-esm/logs-ARJUVN3T.mjs +0 -117
  55. package/dist/lib/node-esm/logs-ARJUVN3T.mjs.map +0 -7
  56. package/dist/lib/node-esm/meta.json +0 -1
  57. package/dist/lib/node-esm/metrics-DREJOOAC.mjs +0 -117
  58. package/dist/lib/node-esm/metrics-DREJOOAC.mjs.map +0 -7
  59. package/dist/lib/node-esm/traces-74F7JUKF.mjs +0 -125
  60. package/dist/lib/node-esm/traces-74F7JUKF.mjs.map +0 -7
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dxos/observability",
3
- "version": "0.10.0",
3
+ "version": "0.11.0",
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",
@@ -14,9 +14,9 @@
14
14
  "type": "module",
15
15
  "exports": {
16
16
  ".": {
17
+ "source": "./src/index.ts",
17
18
  "types": "./dist/types/src/index.d.ts",
18
- "browser": "./dist/lib/browser/index.mjs",
19
- "node": "./dist/lib/node-esm/index.mjs"
19
+ "import": "./dist/lib/index.mjs"
20
20
  }
21
21
  },
22
22
  "browser": {
@@ -30,44 +30,44 @@
30
30
  ],
31
31
  "dependencies": {
32
32
  "@opentelemetry/api": "^1.9.1",
33
- "@opentelemetry/api-logs": "^0.219.0",
34
- "@opentelemetry/auto-instrumentations-web": "^0.64.0",
35
- "@opentelemetry/core": "^2.8.0",
36
- "@opentelemetry/exporter-logs-otlp-http": "^0.219.0",
37
- "@opentelemetry/exporter-metrics-otlp-http": "^0.219.0",
38
- "@opentelemetry/exporter-trace-otlp-http": "^0.219.0",
39
- "@opentelemetry/instrumentation": "^0.219.0",
40
- "@opentelemetry/resources": "^2.8.0",
41
- "@opentelemetry/sdk-logs": "^0.219.0",
42
- "@opentelemetry/sdk-metrics": "^2.8.0",
43
- "@opentelemetry/sdk-trace-base": "^2.8.0",
44
- "@opentelemetry/sdk-trace-web": "^2.8.0",
45
- "@opentelemetry/semantic-conventions": "^1.41.1",
33
+ "@opentelemetry/api-logs": "^0.221.0",
34
+ "@opentelemetry/auto-instrumentations-web": "^0.66.0",
35
+ "@opentelemetry/core": "^2.10.0",
36
+ "@opentelemetry/exporter-logs-otlp-http": "^0.221.0",
37
+ "@opentelemetry/exporter-metrics-otlp-http": "^0.221.0",
38
+ "@opentelemetry/exporter-trace-otlp-http": "^0.221.0",
39
+ "@opentelemetry/instrumentation": "^0.221.0",
40
+ "@opentelemetry/resources": "^2.10.0",
41
+ "@opentelemetry/sdk-logs": "^0.221.0",
42
+ "@opentelemetry/sdk-metrics": "^2.10.0",
43
+ "@opentelemetry/sdk-trace-base": "^2.10.0",
44
+ "@opentelemetry/sdk-trace-web": "^2.10.0",
45
+ "@opentelemetry/semantic-conventions": "^1.43.0",
46
46
  "js-yaml": "4.1.1",
47
47
  "localforage": "^1.10.0",
48
48
  "posthog-js": "^1.353.0",
49
49
  "uuid": "^9.0.0",
50
50
  "zone.js": "^0.15.0",
51
- "@dxos/async": "0.10.0",
52
- "@dxos/config": "0.10.0",
53
- "@dxos/client-services": "0.10.0",
54
- "@dxos/client": "0.10.0",
55
- "@dxos/context": "0.10.0",
56
- "@dxos/invariant": "0.10.0",
57
- "@dxos/log": "0.10.0",
58
- "@dxos/log-store-idb": "0.10.0",
59
- "@dxos/util": "0.10.0",
60
- "@dxos/tracing": "0.10.0",
61
- "@dxos/network-manager": "0.10.0",
62
- "@dxos/node-std": "0.10.0",
63
- "@dxos/protocols": "0.10.0"
51
+ "@dxos/client": "0.11.0",
52
+ "@dxos/client-services": "0.11.0",
53
+ "@dxos/async": "0.11.0",
54
+ "@dxos/config": "0.11.0",
55
+ "@dxos/context": "0.11.0",
56
+ "@dxos/invariant": "0.11.0",
57
+ "@dxos/log": "0.11.0",
58
+ "@dxos/log-store-idb": "0.11.0",
59
+ "@dxos/node-std": "0.11.0",
60
+ "@dxos/network-manager": "0.11.0",
61
+ "@dxos/tracing": "0.11.0",
62
+ "@dxos/protocols": "0.11.0",
63
+ "@dxos/util": "0.11.0"
64
64
  },
65
65
  "devDependencies": {
66
66
  "@effect/platform": "0.96.2",
67
67
  "@types/debug": "^4.1.10",
68
68
  "@types/js-yaml": "^4.0.5",
69
- "@dxos/effect": "0.10.0",
70
- "@dxos/messaging": "0.10.0"
69
+ "@dxos/effect": "0.11.0",
70
+ "@dxos/messaging": "0.11.0"
71
71
  },
72
72
  "peerDependencies": {
73
73
  "@effect/platform": "0.96.2",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "POSTHOG_API_KEY": null,
3
- "IPDATA_API_KEY": "73dfdecdf979c18f07d50cf841bbdd9e589f237256326ac8cca23786",
4
- "OTEL_ENDPOINT": "/api/otel",
3
+ "IPDATA_API_KEY": null,
4
+ "OTEL_ENDPOINT": null,
5
5
  "OTEL_HEADERS": null
6
6
  }
@@ -0,0 +1,39 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ import { describe, test } from 'vitest';
6
+
7
+ import { stringifyValues } from './logs';
8
+
9
+ describe('stringifyValues', () => {
10
+ test('serializes errors via stack', ({ expect }) => {
11
+ const error = new Error('upload exploded');
12
+ const result = stringifyValues({ error }, 'ctx_');
13
+ expect(result.ctx_error).toContain('upload exploded');
14
+ });
15
+
16
+ test('falls back to name and message when stack is absent', ({ expect }) => {
17
+ const error = new Error('no stack here');
18
+ error.stack = undefined;
19
+ expect(stringifyValues({ error })).toEqual({ error: 'Error: no stack here' });
20
+ });
21
+
22
+ test('serializes errors nested past the flatten depth', ({ expect }) => {
23
+ const result = stringifyValues({ outer: { inner: { error: new Error('deep') } } });
24
+ expect(Object.values(result).join()).toContain('deep');
25
+ });
26
+
27
+ test('flattens plain objects and stringifies arrays', ({ expect }) => {
28
+ expect(stringifyValues({ status: 502, nested: { count: 1 }, list: [1, 2] })).toEqual({
29
+ status: '502',
30
+ nested_count: '1',
31
+ list: '[1,2]',
32
+ });
33
+ });
34
+
35
+ test('skips undefined values and handles a missing object', ({ expect }) => {
36
+ expect(stringifyValues({ present: 'yes', absent: undefined })).toEqual({ present: 'yes' });
37
+ expect(stringifyValues(undefined)).toEqual({});
38
+ });
39
+ });
@@ -41,7 +41,7 @@ export class OtelLogs {
41
41
  });
42
42
  this._loggerProvider = new LoggerProvider({
43
43
  resource: this.options.resource,
44
- processors: [new BatchLogRecordProcessor(logExporter)],
44
+ processors: [new BatchLogRecordProcessor({ exporter: logExporter })],
45
45
  });
46
46
  }
47
47
 
@@ -101,16 +101,19 @@ const convertLevel = (level: LogLevel): SeverityNumber => {
101
101
  }
102
102
  };
103
103
 
104
+ const errorToString = (error: Error): string => error.stack ?? `${error.name}: ${error.message}`;
105
+
104
106
  const safeStringify = (value: unknown): string => {
105
107
  try {
106
- return JSON.stringify(value);
108
+ // Replace errors as they are encountered; `JSON.stringify` alone renders them as `{}`.
109
+ return JSON.stringify(value, (_key, nested) => (nested instanceof Error ? errorToString(nested) : nested));
107
110
  } catch {
108
111
  return '[Circular]';
109
112
  }
110
113
  };
111
114
 
112
115
  // TODO(wittjosiah): Reconcile logging utils w/ EDGE.
113
- const stringifyValues = (object: object | undefined, keyPrefix?: string, depth: number = 1) => {
116
+ export const stringifyValues = (object: object | undefined, keyPrefix?: string, depth: number = 1) => {
114
117
  if (!object) {
115
118
  return {};
116
119
  }
@@ -121,7 +124,11 @@ const stringifyValues = (object: object | undefined, keyPrefix?: string, depth:
121
124
  }
122
125
  const newKey = keyPrefix ? `${keyPrefix}${key}` : key;
123
126
  if (typeof value === 'object') {
124
- if (!value || Array.isArray(value) || depth > FLATTEN_DEPTH) {
127
+ if (value instanceof Error) {
128
+ // `message`/`stack` are non-enumerable, so the flatten path below would silently
129
+ // reduce a logged error to nothing.
130
+ result[newKey] = errorToString(value);
131
+ } else if (!value || Array.isArray(value) || depth > FLATTEN_DEPTH) {
125
132
  result[newKey] = safeStringify(value);
126
133
  } else {
127
134
  const flattened = stringifyValues(value, `${newKey}_`, depth + 1);
@@ -104,6 +104,8 @@ export const extensions: (options: ExtensionsOptions) => Effect.Effect<Extension
104
104
  api_host,
105
105
  mask_all_text: true,
106
106
  capture_exceptions: true,
107
+ // Cookies stay scoped to the exact host; the cross-subdomain dmn_chk_* probe fails on public-suffix hosts (e.g. *.pages.dev) and spams the console.
108
+ cross_subdomain_cookie: false,
107
109
  ...posthogConfig,
108
110
  });
109
111
  if (release || environment) {
@@ -181,6 +183,8 @@ export const extensions: (options: ExtensionsOptions) => Effect.Effect<Extension
181
183
  $survey_id: survey.id,
182
184
  $survey_questions: [{ id: question.id, question: question.question }],
183
185
  [`$survey_response_${question.id}`]: form.message,
186
+ // Survey destinations (Slack/webhook notifications) filter on `$survey_completed = true`, so responses without it are dropped.
187
+ $survey_completed: true,
184
188
  debug_log_dump_key: debugLogDumpKey,
185
189
  });
186
190
  resolve(result?.uuid);
@@ -1,10 +0,0 @@
1
- var __defProp = Object.defineProperty;
2
- var __export = (target, all) => {
3
- for (var name in all)
4
- __defProp(target, name, { get: all[name], enumerable: true });
5
- };
6
-
7
- export {
8
- __export
9
- };
10
- //# sourceMappingURL=chunk-J5LGTIGS.mjs.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": [],
4
- "sourcesContent": [],
5
- "mappings": "",
6
- "names": []
7
- }
@@ -1,20 +0,0 @@
1
- // src/extensions/otel/otel.ts
2
- import { DiagConsoleLogger, DiagLogLevel, diag } from "@opentelemetry/api";
3
- var setDiagLogger = (level) => {
4
- const logLevel = DiagLogLevel[level];
5
- if (logLevel) {
6
- diag.setLogger(new DiagConsoleLogger(), logLevel);
7
- }
8
- };
9
- var resolveOtlpUrl = (url) => {
10
- if (typeof window !== "undefined" && url.startsWith("/")) {
11
- return new URL(url, window.location.origin).toString();
12
- }
13
- return url;
14
- };
15
-
16
- export {
17
- setDiagLogger,
18
- resolveOtlpUrl
19
- };
20
- //# sourceMappingURL=chunk-PSFTIG54.mjs.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../src/extensions/otel/otel.ts"],
4
- "sourcesContent": ["//\n// Copyright 2024 DXOS.org\n//\n\nimport { DiagConsoleLogger, DiagLogLevel, diag } from '@opentelemetry/api';\nimport { type Resource } from '@opentelemetry/resources';\n\nexport type OtelOptions = {\n endpoint: string;\n headers: Record<string, string>;\n resource: Resource;\n getTags: () => { [key: string]: string };\n consoleDiagLogLevel?: string;\n};\n\nexport const setDiagLogger = (level?: string) => {\n const logLevel = DiagLogLevel[level as keyof typeof DiagLogLevel];\n if (logLevel) {\n diag.setLogger(new DiagConsoleLogger(), logLevel);\n }\n};\n\n/**\n * Resolve a possibly-relative OTLP exporter URL to an absolute URL.\n * The OpenTelemetry browser HTTP exporter validates user-provided URLs with `new URL(url)`,\n * which throws on relative paths like `/api/otel/v1/logs`. In a browser context we resolve\n * against `window.location.origin`; outside the browser we return the input unchanged.\n */\nexport const resolveOtlpUrl = (url: string): string => {\n if (typeof window !== 'undefined' && url.startsWith('/')) {\n return new URL(url, window.location.origin).toString();\n }\n return url;\n};\n"],
5
- "mappings": ";AAIA,SAASA,mBAAmBC,cAAcC,YAAY;AAW/C,IAAMC,gBAAgB,CAACC,UAAAA;AAC5B,QAAMC,WAAWJ,aAAaG,KAAAA;AAC9B,MAAIC,UAAU;AACZH,SAAKI,UAAU,IAAIN,kBAAAA,GAAqBK,QAAAA;EAC1C;AACF;AAQO,IAAME,iBAAiB,CAACC,QAAAA;AAC7B,MAAI,OAAOC,WAAW,eAAeD,IAAIE,WAAW,GAAA,GAAM;AACxD,WAAO,IAAIC,IAAIH,KAAKC,OAAOG,SAASC,MAAM,EAAEC,SAAQ;EACtD;AACA,SAAON;AACT;",
6
- "names": ["DiagConsoleLogger", "DiagLogLevel", "diag", "setDiagLogger", "level", "logLevel", "setLogger", "resolveOtlpUrl", "url", "window", "startsWith", "URL", "location", "origin", "toString"]
7
- }