@syncular/observability-sentry 0.0.1 → 0.0.2-127

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 ADDED
@@ -0,0 +1,28 @@
1
+ # @syncular/observability-sentry
2
+
3
+ Sentry adapter for Syncular telemetry (`SyncTelemetry`): logs, traces, metrics, and exceptions.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install @syncular/observability-sentry
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ```ts
14
+ import { createBrowserSentryTelemetry } from '@syncular/observability-sentry';
15
+
16
+ const telemetry = createBrowserSentryTelemetry();
17
+ ```
18
+
19
+ ## Documentation
20
+
21
+ - Observability guide: https://syncular.dev/docs/build/observability
22
+
23
+ ## Links
24
+
25
+ - GitHub: https://github.com/syncular/syncular
26
+ - Issues: https://github.com/syncular/syncular/issues
27
+
28
+ > Status: Alpha. APIs and storage layouts may change between releases.
package/dist/browser.d.ts CHANGED
@@ -1,6 +1,16 @@
1
1
  import * as Sentry from '@sentry/react';
2
- import { type SyncTelemetry } from '@syncular/core';
2
+ import { type SyncTelemetry, type SyncTelemetryAttributeValue } from '@syncular/core';
3
3
  export type BrowserSentryInitOptions = Parameters<typeof Sentry.init>[0];
4
+ export type BrowserSentryCaptureMessageLevel = Parameters<typeof Sentry.captureMessage>[1];
5
+ interface BrowserSentryCaptureMessageOptions {
6
+ level?: BrowserSentryCaptureMessageLevel;
7
+ tags?: Record<string, string>;
8
+ }
9
+ type BrowserSentryLogLevel = 'trace' | 'debug' | 'info' | 'warn' | 'error' | 'fatal';
10
+ interface BrowserSentryLogOptions {
11
+ level?: BrowserSentryLogLevel;
12
+ attributes?: Record<string, SyncTelemetryAttributeValue>;
13
+ }
4
14
  /**
5
15
  * Create a Syncular telemetry backend wired to `@sentry/react`.
6
16
  */
@@ -13,4 +23,13 @@ export declare function configureBrowserSentryTelemetry(): SyncTelemetry;
13
23
  * Initialize browser Sentry and configure Syncular telemetry.
14
24
  */
15
25
  export declare function initAndConfigureBrowserSentry(options: BrowserSentryInitOptions): SyncTelemetry;
26
+ /**
27
+ * Capture a browser message in Sentry with optional tags.
28
+ */
29
+ export declare function captureBrowserSentryMessage(message: string, options?: BrowserSentryCaptureMessageOptions): void;
30
+ /**
31
+ * Emit a browser Sentry log entry.
32
+ */
33
+ export declare function logBrowserSentryMessage(message: string, options?: BrowserSentryLogOptions): void;
34
+ export {};
16
35
  //# sourceMappingURL=browser.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../src/browser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,EAGL,KAAK,aAAa,EACnB,MAAM,gBAAgB,CAAC;AAGxB,MAAM,MAAM,wBAAwB,GAAG,UAAU,CAAC,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;AAsBzE;;GAEG;AACH,wBAAgB,4BAA4B,IAAI,aAAa,CAkD5D;AAED;;GAEG;AACH,wBAAgB,+BAA+B,IAAI,aAAa,CAI/D;AAED;;GAEG;AACH,wBAAgB,6BAA6B,CAC3C,OAAO,EAAE,wBAAwB,GAChC,aAAa,CAGf"}
1
+ {"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../src/browser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,EAGL,KAAK,aAAa,EAClB,KAAK,2BAA2B,EACjC,MAAM,gBAAgB,CAAC;AAGxB,MAAM,MAAM,wBAAwB,GAAG,UAAU,CAAC,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;AACzE,MAAM,MAAM,gCAAgC,GAAG,UAAU,CACvD,OAAO,MAAM,CAAC,cAAc,CAC7B,CAAC,CAAC,CAAC,CAAC;AAEL,UAAU,kCAAkC;IAC1C,KAAK,CAAC,EAAE,gCAAgC,CAAC;IACzC,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC/B;AAED,KAAK,qBAAqB,GACtB,OAAO,GACP,OAAO,GACP,MAAM,GACN,MAAM,GACN,OAAO,GACP,OAAO,CAAC;AAEZ,UAAU,uBAAuB;IAC/B,KAAK,CAAC,EAAE,qBAAqB,CAAC;IAC9B,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,2BAA2B,CAAC,CAAC;CAC1D;AAqDD;;GAEG;AACH,wBAAgB,4BAA4B,IAAI,aAAa,CAkD5D;AAED;;GAEG;AACH,wBAAgB,+BAA+B,IAAI,aAAa,CAI/D;AAED;;GAEG;AACH,wBAAgB,6BAA6B,CAC3C,OAAO,EAAE,wBAAwB,GAChC,aAAa,CAIf;AAuBD;;GAEG;AACH,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,kCAAkC,GAC3C,IAAI,CAYN;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,uBAAuB,GAChC,IAAI,CASN"}
package/dist/browser.js CHANGED
@@ -1,6 +1,27 @@
1
1
  import * as Sentry from '@sentry/react';
2
2
  import { configureSyncTelemetry, } from '@syncular/core';
3
3
  import { createSentrySyncTelemetry } from './shared.js';
4
+ function resolveBrowserLogMethod(level) {
5
+ switch (level) {
6
+ case 'trace':
7
+ return Sentry.logger.trace ?? Sentry.logger.debug ?? Sentry.logger.info;
8
+ case 'debug':
9
+ return Sentry.logger.debug ?? Sentry.logger.info;
10
+ case 'info':
11
+ return Sentry.logger.info;
12
+ case 'warn':
13
+ return Sentry.logger.warn ?? Sentry.logger.info;
14
+ case 'error':
15
+ return Sentry.logger.error ?? Sentry.logger.warn ?? Sentry.logger.info;
16
+ case 'fatal':
17
+ return (Sentry.logger.fatal ??
18
+ Sentry.logger.error ??
19
+ Sentry.logger.warn ??
20
+ Sentry.logger.info);
21
+ default:
22
+ return Sentry.logger.info;
23
+ }
24
+ }
4
25
  function toCountMetricOptions(options) {
5
26
  if (!options?.attributes)
6
27
  return undefined;
@@ -82,7 +103,53 @@ export function configureBrowserSentryTelemetry() {
82
103
  * Initialize browser Sentry and configure Syncular telemetry.
83
104
  */
84
105
  export function initAndConfigureBrowserSentry(options) {
85
- Sentry.init(options);
106
+ const configuredOptions = ensureBrowserTracingIntegration(options);
107
+ Sentry.init(configuredOptions);
86
108
  return configureBrowserSentryTelemetry();
87
109
  }
110
+ function ensureBrowserTracingIntegration(options) {
111
+ const integrations = options.integrations;
112
+ if (typeof integrations === 'function')
113
+ return options;
114
+ const configuredIntegrations = integrations ?? [];
115
+ const hasBrowserTracing = configuredIntegrations.some((integration) => integration.name === 'BrowserTracing');
116
+ if (hasBrowserTracing)
117
+ return options;
118
+ return {
119
+ ...options,
120
+ integrations: [
121
+ Sentry.browserTracingIntegration(),
122
+ ...configuredIntegrations,
123
+ ],
124
+ };
125
+ }
126
+ /**
127
+ * Capture a browser message in Sentry with optional tags.
128
+ */
129
+ export function captureBrowserSentryMessage(message, options) {
130
+ if (!options?.tags || Object.keys(options.tags).length === 0) {
131
+ Sentry.captureMessage(message, options?.level);
132
+ return;
133
+ }
134
+ Sentry.withScope((scope) => {
135
+ for (const [name, value] of Object.entries(options.tags ?? {})) {
136
+ scope.setTag(name, value);
137
+ }
138
+ Sentry.captureMessage(message, options?.level);
139
+ });
140
+ }
141
+ /**
142
+ * Emit a browser Sentry log entry.
143
+ */
144
+ export function logBrowserSentryMessage(message, options) {
145
+ const level = options?.level ?? 'info';
146
+ const logMethod = resolveBrowserLogMethod(level);
147
+ if (!logMethod)
148
+ return;
149
+ if (!options?.attributes || Object.keys(options.attributes).length === 0) {
150
+ logMethod(message);
151
+ return;
152
+ }
153
+ logMethod(message, options.attributes);
154
+ }
88
155
  //# sourceMappingURL=browser.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"browser.js","sourceRoot":"","sources":["../src/browser.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"browser.js","sourceRoot":"","sources":["../src/browser.ts"],"names":[],"mappings":"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"}
@@ -1,9 +1,32 @@
1
1
  import * as Sentry from '@sentry/cloudflare';
2
- import { type SyncTelemetry } from '@syncular/core';
2
+ import { type SyncTelemetry, type SyncTelemetryAttributeValue } from '@syncular/core';
3
+ export type CloudflareSentryCaptureMessageLevel = Parameters<typeof Sentry.captureMessage>[1];
4
+ interface CloudflareSentryCaptureMessageOptions {
5
+ level?: CloudflareSentryCaptureMessageLevel;
6
+ tags?: Record<string, string>;
7
+ }
8
+ type CloudflareSentryLogLevel = 'trace' | 'debug' | 'info' | 'warn' | 'error' | 'fatal';
9
+ interface CloudflareSentryLogOptions {
10
+ level?: CloudflareSentryLogLevel;
11
+ attributes?: Record<string, SyncTelemetryAttributeValue>;
12
+ }
3
13
  /**
4
14
  * Re-export Cloudflare Sentry worker wrapper.
5
15
  */
6
16
  export declare const withCloudflareSentry: typeof Sentry.withSentry;
17
+ export declare const instrumentCloudflareDurableObjectWithSentry: typeof Sentry.instrumentDurableObjectWithSentry;
18
+ export interface CloudflareSentryTraceHeaders {
19
+ sentryTrace?: string;
20
+ baggage?: string;
21
+ }
22
+ /**
23
+ * Read current trace headers from the active Cloudflare Sentry scope.
24
+ */
25
+ export declare function getCloudflareSentryTraceHeaders(traceData?: ReturnType<typeof Sentry.getTraceData>): CloudflareSentryTraceHeaders;
26
+ /**
27
+ * Clone a request and attach active Cloudflare trace headers when available.
28
+ */
29
+ export declare function attachCloudflareSentryTraceHeaders(request: Request, traceHeaders?: CloudflareSentryTraceHeaders): Request;
7
30
  /**
8
31
  * Create a Syncular telemetry backend wired to `@sentry/cloudflare`.
9
32
  */
@@ -12,4 +35,13 @@ export declare function createCloudflareSentryTelemetry(): SyncTelemetry;
12
35
  * Configure Syncular core telemetry to use the Cloudflare Sentry adapter.
13
36
  */
14
37
  export declare function configureCloudflareSentryTelemetry(): SyncTelemetry;
38
+ /**
39
+ * Capture a worker message in Sentry with optional tags.
40
+ */
41
+ export declare function captureCloudflareSentryMessage(message: string, options?: CloudflareSentryCaptureMessageOptions): void;
42
+ /**
43
+ * Emit a Cloudflare Sentry log entry.
44
+ */
45
+ export declare function logCloudflareSentryMessage(message: string, options?: CloudflareSentryLogOptions): void;
46
+ export {};
15
47
  //# sourceMappingURL=cloudflare.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"cloudflare.d.ts","sourceRoot":"","sources":["../src/cloudflare.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,oBAAoB,CAAC;AAC7C,OAAO,EAGL,KAAK,aAAa,EACnB,MAAM,gBAAgB,CAAC;AAuBxB;;GAEG;AACH,eAAO,MAAM,oBAAoB,0BAAoB,CAAC;AAEtD;;GAEG;AACH,wBAAgB,+BAA+B,IAAI,aAAa,CAkD/D;AAED;;GAEG;AACH,wBAAgB,kCAAkC,IAAI,aAAa,CAIlE"}
1
+ {"version":3,"file":"cloudflare.d.ts","sourceRoot":"","sources":["../src/cloudflare.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,oBAAoB,CAAC;AAC7C,OAAO,EAGL,KAAK,aAAa,EAClB,KAAK,2BAA2B,EACjC,MAAM,gBAAgB,CAAC;AAuBxB,MAAM,MAAM,mCAAmC,GAAG,UAAU,CAC1D,OAAO,MAAM,CAAC,cAAc,CAC7B,CAAC,CAAC,CAAC,CAAC;AAEL,UAAU,qCAAqC;IAC7C,KAAK,CAAC,EAAE,mCAAmC,CAAC;IAC5C,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC/B;AAED,KAAK,wBAAwB,GACzB,OAAO,GACP,OAAO,GACP,MAAM,GACN,MAAM,GACN,OAAO,GACP,OAAO,CAAC;AAEZ,UAAU,0BAA0B;IAClC,KAAK,CAAC,EAAE,wBAAwB,CAAC;IACjC,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,2BAA2B,CAAC,CAAC;CAC1D;AAiCD;;GAEG;AACH,eAAO,MAAM,oBAAoB,0BAAoB,CAAC;AACtD,eAAO,MAAM,2CAA2C,iDACd,CAAC;AAE3C,MAAM,WAAW,4BAA4B;IAC3C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,wBAAgB,+BAA+B,CAC7C,SAAS,GAAE,UAAU,CAAC,OAAO,MAAM,CAAC,YAAY,CAAyB,GACxE,4BAA4B,CAO9B;AAED;;GAEG;AACH,wBAAgB,kCAAkC,CAChD,OAAO,EAAE,OAAO,EAChB,YAAY,GAAE,4BAAgE,GAC7E,OAAO,CAcT;AAED;;GAEG;AACH,wBAAgB,+BAA+B,IAAI,aAAa,CAkD/D;AAED;;GAEG;AACH,wBAAgB,kCAAkC,IAAI,aAAa,CAIlE;AAED;;GAEG;AACH,wBAAgB,8BAA8B,CAC5C,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,qCAAqC,GAC9C,IAAI,CAYN;AAED;;GAEG;AACH,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,0BAA0B,GACnC,IAAI,CASN"}
@@ -18,10 +18,59 @@ function toValueMetricOptions(options) {
18
18
  unit: options.unit,
19
19
  };
20
20
  }
21
+ function resolveCloudflareLogMethod(level) {
22
+ switch (level) {
23
+ case 'trace':
24
+ return Sentry.logger.trace ?? Sentry.logger.debug ?? Sentry.logger.info;
25
+ case 'debug':
26
+ return Sentry.logger.debug ?? Sentry.logger.info;
27
+ case 'info':
28
+ return Sentry.logger.info;
29
+ case 'warn':
30
+ return Sentry.logger.warn ?? Sentry.logger.info;
31
+ case 'error':
32
+ return Sentry.logger.error ?? Sentry.logger.warn ?? Sentry.logger.info;
33
+ case 'fatal':
34
+ return (Sentry.logger.fatal ??
35
+ Sentry.logger.error ??
36
+ Sentry.logger.warn ??
37
+ Sentry.logger.info);
38
+ default:
39
+ return Sentry.logger.info;
40
+ }
41
+ }
21
42
  /**
22
43
  * Re-export Cloudflare Sentry worker wrapper.
23
44
  */
24
45
  export const withCloudflareSentry = Sentry.withSentry;
46
+ export const instrumentCloudflareDurableObjectWithSentry = Sentry.instrumentDurableObjectWithSentry;
47
+ /**
48
+ * Read current trace headers from the active Cloudflare Sentry scope.
49
+ */
50
+ export function getCloudflareSentryTraceHeaders(traceData = Sentry.getTraceData()) {
51
+ const sentryTrace = traceData['sentry-trace']?.trim();
52
+ const baggage = traceData.baggage?.trim();
53
+ return {
54
+ ...(sentryTrace ? { sentryTrace } : {}),
55
+ ...(baggage ? { baggage } : {}),
56
+ };
57
+ }
58
+ /**
59
+ * Clone a request and attach active Cloudflare trace headers when available.
60
+ */
61
+ export function attachCloudflareSentryTraceHeaders(request, traceHeaders = getCloudflareSentryTraceHeaders()) {
62
+ if (!traceHeaders.sentryTrace && !traceHeaders.baggage) {
63
+ return request;
64
+ }
65
+ const headers = new Headers(request.headers);
66
+ if (traceHeaders.sentryTrace) {
67
+ headers.set('sentry-trace', traceHeaders.sentryTrace);
68
+ }
69
+ if (traceHeaders.baggage) {
70
+ headers.set('baggage', traceHeaders.baggage);
71
+ }
72
+ return new Request(request, { headers });
73
+ }
25
74
  /**
26
75
  * Create a Syncular telemetry backend wired to `@sentry/cloudflare`.
27
76
  */
@@ -82,4 +131,33 @@ export function configureCloudflareSentryTelemetry() {
82
131
  configureSyncTelemetry(telemetry);
83
132
  return telemetry;
84
133
  }
134
+ /**
135
+ * Capture a worker message in Sentry with optional tags.
136
+ */
137
+ export function captureCloudflareSentryMessage(message, options) {
138
+ if (!options?.tags || Object.keys(options.tags).length === 0) {
139
+ Sentry.captureMessage(message, options?.level);
140
+ return;
141
+ }
142
+ Sentry.withScope((scope) => {
143
+ for (const [name, value] of Object.entries(options.tags ?? {})) {
144
+ scope.setTag(name, value);
145
+ }
146
+ Sentry.captureMessage(message, options?.level);
147
+ });
148
+ }
149
+ /**
150
+ * Emit a Cloudflare Sentry log entry.
151
+ */
152
+ export function logCloudflareSentryMessage(message, options) {
153
+ const level = options?.level ?? 'info';
154
+ const logMethod = resolveCloudflareLogMethod(level);
155
+ if (!logMethod)
156
+ return;
157
+ if (!options?.attributes || Object.keys(options.attributes).length === 0) {
158
+ logMethod(message);
159
+ return;
160
+ }
161
+ logMethod(message, options.attributes);
162
+ }
85
163
  //# sourceMappingURL=cloudflare.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"cloudflare.js","sourceRoot":"","sources":["../src/cloudflare.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cloudflare.js","sourceRoot":"","sources":["../src/cloudflare.ts"],"names":[],"mappings":"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"}
package/dist/shared.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { SyncMetricOptions, SyncSpanOptions, SyncTelemetry, SyncTelemetryAttributeValue, SyncTelemetryAttributes } from '@syncular/core';
1
+ import type { SyncMetricOptions, SyncSpanOptions, SyncTelemetry, SyncTelemetryAttributes, SyncTelemetryAttributeValue } from '@syncular/core';
2
2
  interface SentryLoggerAdapter {
3
3
  trace?(message: string, attributes?: Record<string, unknown>): void;
4
4
  debug?(message: string, attributes?: Record<string, unknown>): void;
@@ -1 +1 @@
1
- {"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../src/shared.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,iBAAiB,EAGjB,eAAe,EACf,aAAa,EACb,2BAA2B,EAC3B,uBAAuB,EAIxB,MAAM,gBAAgB,CAAC;AAExB,UAAU,mBAAmB;IAC3B,KAAK,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IACpE,KAAK,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IACpE,IAAI,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IACnE,IAAI,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IACnE,KAAK,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IACpE,KAAK,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;CACrE;AAED,UAAU,iBAAiB;IACzB,YAAY,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,2BAA2B,GAAG,IAAI,CAAC;IACtE,aAAa,CAAC,CAAC,UAAU,EAAE,uBAAuB,GAAG,IAAI,CAAC;IAC1D,SAAS,CAAC,CAAC,MAAM,EAAE,IAAI,GAAG,OAAO,GAAG,MAAM,GAAG,IAAI,CAAC;CACnD;AAED,UAAU,oBAAoB;IAC5B,KAAK,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,iBAAiB,GAAG,IAAI,CAAC;IACvE,KAAK,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,iBAAiB,GAAG,IAAI,CAAC;IACvE,YAAY,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,iBAAiB,GAAG,IAAI,CAAC;CAC/E;AAED,MAAM,WAAW,sBAAsB;IACrC,MAAM,CAAC,EAAE,mBAAmB,CAAC;IAC7B,SAAS,CAAC,CAAC,CAAC,EACV,OAAO,EAAE,eAAe,EACxB,QAAQ,EAAE,CAAC,IAAI,EAAE,iBAAiB,KAAK,CAAC,GACvC,CAAC,CAAC;IACL,OAAO,CAAC,EAAE,oBAAoB,CAAC;IAC/B,gBAAgB,CAAC,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAAC;CACzC;AAgFD;;GAEG;AACH,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,sBAAsB,GAC9B,aAAa,CAyBf"}
1
+ {"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../src/shared.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,iBAAiB,EAGjB,eAAe,EACf,aAAa,EACb,uBAAuB,EACvB,2BAA2B,EAI5B,MAAM,gBAAgB,CAAC;AAExB,UAAU,mBAAmB;IAC3B,KAAK,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IACpE,KAAK,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IACpE,IAAI,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IACnE,IAAI,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IACnE,KAAK,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IACpE,KAAK,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;CACrE;AAED,UAAU,iBAAiB;IACzB,YAAY,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,2BAA2B,GAAG,IAAI,CAAC;IACtE,aAAa,CAAC,CAAC,UAAU,EAAE,uBAAuB,GAAG,IAAI,CAAC;IAC1D,SAAS,CAAC,CAAC,MAAM,EAAE,IAAI,GAAG,OAAO,GAAG,MAAM,GAAG,IAAI,CAAC;CACnD;AAED,UAAU,oBAAoB;IAC5B,KAAK,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,iBAAiB,GAAG,IAAI,CAAC;IACvE,KAAK,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,iBAAiB,GAAG,IAAI,CAAC;IACvE,YAAY,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,iBAAiB,GAAG,IAAI,CAAC;CAC/E;AAED,MAAM,WAAW,sBAAsB;IACrC,MAAM,CAAC,EAAE,mBAAmB,CAAC;IAC7B,SAAS,CAAC,CAAC,CAAC,EACV,OAAO,EAAE,eAAe,EACxB,QAAQ,EAAE,CAAC,IAAI,EAAE,iBAAiB,KAAK,CAAC,GACvC,CAAC,CAAC;IACL,OAAO,CAAC,EAAE,oBAAoB,CAAC;IAC/B,gBAAgB,CAAC,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAAC;CACzC;AAyHD;;GAEG;AACH,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,sBAAsB,GAC9B,aAAa,CA+Bf"}
package/dist/shared.js CHANGED
@@ -47,6 +47,44 @@ function toSpan(span) {
47
47
  },
48
48
  };
49
49
  }
50
+ function toLogAttributeValue(value) {
51
+ if (typeof value === 'string')
52
+ return value;
53
+ if (typeof value === 'number') {
54
+ return Number.isFinite(value) ? value : undefined;
55
+ }
56
+ if (typeof value === 'boolean')
57
+ return value;
58
+ if (typeof value === 'bigint') {
59
+ const asNumber = Number(value);
60
+ if (Number.isFinite(asNumber))
61
+ return asNumber;
62
+ return value.toString();
63
+ }
64
+ if (value instanceof Date)
65
+ return value.toISOString();
66
+ if (value === null || value === undefined)
67
+ return undefined;
68
+ if (Array.isArray(value) || typeof value === 'object') {
69
+ try {
70
+ return JSON.stringify(value);
71
+ }
72
+ catch {
73
+ return String(value);
74
+ }
75
+ }
76
+ return String(value);
77
+ }
78
+ function sanitizeLogAttributes(attributes) {
79
+ const sanitized = {};
80
+ for (const [name, value] of Object.entries(attributes)) {
81
+ const normalized = toLogAttributeValue(value);
82
+ if (normalized !== undefined) {
83
+ sanitized[name] = normalized;
84
+ }
85
+ }
86
+ return Object.keys(sanitized).length > 0 ? sanitized : null;
87
+ }
50
88
  function createTracer(adapter) {
51
89
  return {
52
90
  startSpan(options, callback) {
@@ -80,11 +118,12 @@ export function createSentrySyncTelemetry(adapter) {
80
118
  const logMethod = resolveLogMethod(adapter.logger, level);
81
119
  if (!logMethod)
82
120
  return;
83
- if (Object.keys(attributes).length === 0) {
121
+ const sanitizedAttributes = sanitizeLogAttributes(attributes);
122
+ if (!sanitizedAttributes) {
84
123
  logMethod(message);
85
124
  return;
86
125
  }
87
- logMethod(message, attributes);
126
+ logMethod(message, sanitizedAttributes);
88
127
  },
89
128
  tracer: createTracer(adapter),
90
129
  metrics: createMetrics(adapter),
@@ -96,7 +135,12 @@ export function createSentrySyncTelemetry(adapter) {
96
135
  resolveLogMethod(adapter.logger, 'info');
97
136
  if (!logMethod)
98
137
  return;
99
- logMethod('sync.exception.context', context);
138
+ const sanitizedContext = sanitizeLogAttributes(context);
139
+ if (!sanitizedContext) {
140
+ logMethod('sync.exception.context');
141
+ return;
142
+ }
143
+ logMethod('sync.exception.context', sanitizedContext);
100
144
  },
101
145
  };
102
146
  }
@@ -1 +1 @@
1
- {"version":3,"file":"shared.js","sourceRoot":"","sources":["../src/shared.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"shared.js","sourceRoot":"","sources":["../src/shared.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@syncular/observability-sentry",
3
- "version": "0.0.1",
3
+ "version": "0.0.2-127",
4
4
  "description": "Sentry adapters for Syncular telemetry",
5
5
  "license": "MIT",
6
6
  "author": "Benjamin Kniffler",
@@ -43,7 +43,7 @@
43
43
  "dependencies": {
44
44
  "@sentry/cloudflare": "^10.38.0",
45
45
  "@sentry/react": "^10.38.0",
46
- "@syncular/core": "0.0.1"
46
+ "@syncular/core": "0.0.2-127"
47
47
  },
48
48
  "devDependencies": {
49
49
  "@syncular/config": "0.0.0"
package/src/browser.ts CHANGED
@@ -3,6 +3,7 @@ import {
3
3
  configureSyncTelemetry,
4
4
  type SyncMetricOptions,
5
5
  type SyncTelemetry,
6
+ type SyncTelemetryAttributeValue,
6
7
  } from '@syncular/core';
7
8
  import { createSentrySyncTelemetry } from './shared';
8
9
 
@@ -16,6 +17,50 @@ interface BrowserSentryCaptureMessageOptions {
16
17
  tags?: Record<string, string>;
17
18
  }
18
19
 
20
+ type BrowserSentryLogLevel =
21
+ | 'trace'
22
+ | 'debug'
23
+ | 'info'
24
+ | 'warn'
25
+ | 'error'
26
+ | 'fatal';
27
+
28
+ interface BrowserSentryLogOptions {
29
+ level?: BrowserSentryLogLevel;
30
+ attributes?: Record<string, SyncTelemetryAttributeValue>;
31
+ }
32
+
33
+ function resolveBrowserLogMethod(
34
+ level: BrowserSentryLogLevel
35
+ ):
36
+ | ((
37
+ message: string,
38
+ attributes?: Record<string, SyncTelemetryAttributeValue>
39
+ ) => void)
40
+ | null {
41
+ switch (level) {
42
+ case 'trace':
43
+ return Sentry.logger.trace ?? Sentry.logger.debug ?? Sentry.logger.info;
44
+ case 'debug':
45
+ return Sentry.logger.debug ?? Sentry.logger.info;
46
+ case 'info':
47
+ return Sentry.logger.info;
48
+ case 'warn':
49
+ return Sentry.logger.warn ?? Sentry.logger.info;
50
+ case 'error':
51
+ return Sentry.logger.error ?? Sentry.logger.warn ?? Sentry.logger.info;
52
+ case 'fatal':
53
+ return (
54
+ Sentry.logger.fatal ??
55
+ Sentry.logger.error ??
56
+ Sentry.logger.warn ??
57
+ Sentry.logger.info
58
+ );
59
+ default:
60
+ return Sentry.logger.info;
61
+ }
62
+ }
63
+
19
64
  function toCountMetricOptions(
20
65
  options?: SyncMetricOptions
21
66
  ): Parameters<typeof Sentry.metrics.count>[2] | undefined {
@@ -106,10 +151,32 @@ export function configureBrowserSentryTelemetry(): SyncTelemetry {
106
151
  export function initAndConfigureBrowserSentry(
107
152
  options: BrowserSentryInitOptions
108
153
  ): SyncTelemetry {
109
- Sentry.init(options);
154
+ const configuredOptions = ensureBrowserTracingIntegration(options);
155
+ Sentry.init(configuredOptions);
110
156
  return configureBrowserSentryTelemetry();
111
157
  }
112
158
 
159
+ function ensureBrowserTracingIntegration(
160
+ options: BrowserSentryInitOptions
161
+ ): BrowserSentryInitOptions {
162
+ const integrations = options.integrations;
163
+ if (typeof integrations === 'function') return options;
164
+
165
+ const configuredIntegrations = integrations ?? [];
166
+ const hasBrowserTracing = configuredIntegrations.some(
167
+ (integration) => integration.name === 'BrowserTracing'
168
+ );
169
+ if (hasBrowserTracing) return options;
170
+
171
+ return {
172
+ ...options,
173
+ integrations: [
174
+ Sentry.browserTracingIntegration(),
175
+ ...configuredIntegrations,
176
+ ],
177
+ };
178
+ }
179
+
113
180
  /**
114
181
  * Capture a browser message in Sentry with optional tags.
115
182
  */
@@ -129,3 +196,20 @@ export function captureBrowserSentryMessage(
129
196
  Sentry.captureMessage(message, options?.level);
130
197
  });
131
198
  }
199
+
200
+ /**
201
+ * Emit a browser Sentry log entry.
202
+ */
203
+ export function logBrowserSentryMessage(
204
+ message: string,
205
+ options?: BrowserSentryLogOptions
206
+ ): void {
207
+ const level = options?.level ?? 'info';
208
+ const logMethod = resolveBrowserLogMethod(level);
209
+ if (!logMethod) return;
210
+ if (!options?.attributes || Object.keys(options.attributes).length === 0) {
211
+ logMethod(message);
212
+ return;
213
+ }
214
+ logMethod(message, options.attributes);
215
+ }
@@ -0,0 +1,49 @@
1
+ import { describe, expect, test } from 'bun:test';
2
+ import {
3
+ attachCloudflareSentryTraceHeaders,
4
+ getCloudflareSentryTraceHeaders,
5
+ } from './cloudflare';
6
+
7
+ describe('cloudflare tracing helpers', () => {
8
+ test('extracts trace headers from sentry trace data', () => {
9
+ expect(
10
+ getCloudflareSentryTraceHeaders({
11
+ 'sentry-trace': 'trace-id-span-id-1',
12
+ baggage: 'sample_rate=1',
13
+ })
14
+ ).toEqual({
15
+ sentryTrace: 'trace-id-span-id-1',
16
+ baggage: 'sample_rate=1',
17
+ });
18
+ });
19
+
20
+ test('returns original request when trace headers are missing', () => {
21
+ const request = new Request('https://example.com/api/sync', {
22
+ method: 'POST',
23
+ headers: { 'x-custom': '1' },
24
+ body: '{}',
25
+ });
26
+
27
+ const result = attachCloudflareSentryTraceHeaders(request, {});
28
+ expect(result).toBe(request);
29
+ });
30
+
31
+ test('adds sentry trace headers to cloned request', async () => {
32
+ const request = new Request('https://example.com/api/sync', {
33
+ method: 'POST',
34
+ headers: { 'x-custom': '1' },
35
+ body: '{"ok":true}',
36
+ });
37
+
38
+ const result = attachCloudflareSentryTraceHeaders(request, {
39
+ sentryTrace: 'trace-id-span-id-1',
40
+ baggage: 'sample_rate=1',
41
+ });
42
+
43
+ expect(result).not.toBe(request);
44
+ expect(result.headers.get('x-custom')).toBe('1');
45
+ expect(result.headers.get('sentry-trace')).toBe('trace-id-span-id-1');
46
+ expect(result.headers.get('baggage')).toBe('sample_rate=1');
47
+ expect(await result.text()).toBe('{"ok":true}');
48
+ });
49
+ });
package/src/cloudflare.ts CHANGED
@@ -3,6 +3,7 @@ import {
3
3
  configureSyncTelemetry,
4
4
  type SyncMetricOptions,
5
5
  type SyncTelemetry,
6
+ type SyncTelemetryAttributeValue,
6
7
  } from '@syncular/core';
7
8
  import { createSentrySyncTelemetry } from './shared';
8
9
 
@@ -35,10 +36,97 @@ interface CloudflareSentryCaptureMessageOptions {
35
36
  tags?: Record<string, string>;
36
37
  }
37
38
 
39
+ type CloudflareSentryLogLevel =
40
+ | 'trace'
41
+ | 'debug'
42
+ | 'info'
43
+ | 'warn'
44
+ | 'error'
45
+ | 'fatal';
46
+
47
+ interface CloudflareSentryLogOptions {
48
+ level?: CloudflareSentryLogLevel;
49
+ attributes?: Record<string, SyncTelemetryAttributeValue>;
50
+ }
51
+
52
+ function resolveCloudflareLogMethod(
53
+ level: CloudflareSentryLogLevel
54
+ ):
55
+ | ((
56
+ message: string,
57
+ attributes?: Record<string, SyncTelemetryAttributeValue>
58
+ ) => void)
59
+ | null {
60
+ switch (level) {
61
+ case 'trace':
62
+ return Sentry.logger.trace ?? Sentry.logger.debug ?? Sentry.logger.info;
63
+ case 'debug':
64
+ return Sentry.logger.debug ?? Sentry.logger.info;
65
+ case 'info':
66
+ return Sentry.logger.info;
67
+ case 'warn':
68
+ return Sentry.logger.warn ?? Sentry.logger.info;
69
+ case 'error':
70
+ return Sentry.logger.error ?? Sentry.logger.warn ?? Sentry.logger.info;
71
+ case 'fatal':
72
+ return (
73
+ Sentry.logger.fatal ??
74
+ Sentry.logger.error ??
75
+ Sentry.logger.warn ??
76
+ Sentry.logger.info
77
+ );
78
+ default:
79
+ return Sentry.logger.info;
80
+ }
81
+ }
82
+
38
83
  /**
39
84
  * Re-export Cloudflare Sentry worker wrapper.
40
85
  */
41
86
  export const withCloudflareSentry = Sentry.withSentry;
87
+ export const instrumentCloudflareDurableObjectWithSentry =
88
+ Sentry.instrumentDurableObjectWithSentry;
89
+
90
+ export interface CloudflareSentryTraceHeaders {
91
+ sentryTrace?: string;
92
+ baggage?: string;
93
+ }
94
+
95
+ /**
96
+ * Read current trace headers from the active Cloudflare Sentry scope.
97
+ */
98
+ export function getCloudflareSentryTraceHeaders(
99
+ traceData: ReturnType<typeof Sentry.getTraceData> = Sentry.getTraceData()
100
+ ): CloudflareSentryTraceHeaders {
101
+ const sentryTrace = traceData['sentry-trace']?.trim();
102
+ const baggage = traceData.baggage?.trim();
103
+ return {
104
+ ...(sentryTrace ? { sentryTrace } : {}),
105
+ ...(baggage ? { baggage } : {}),
106
+ };
107
+ }
108
+
109
+ /**
110
+ * Clone a request and attach active Cloudflare trace headers when available.
111
+ */
112
+ export function attachCloudflareSentryTraceHeaders(
113
+ request: Request,
114
+ traceHeaders: CloudflareSentryTraceHeaders = getCloudflareSentryTraceHeaders()
115
+ ): Request {
116
+ if (!traceHeaders.sentryTrace && !traceHeaders.baggage) {
117
+ return request;
118
+ }
119
+
120
+ const headers = new Headers(request.headers);
121
+ if (traceHeaders.sentryTrace) {
122
+ headers.set('sentry-trace', traceHeaders.sentryTrace);
123
+ }
124
+ if (traceHeaders.baggage) {
125
+ headers.set('baggage', traceHeaders.baggage);
126
+ }
127
+
128
+ return new Request(request, { headers });
129
+ }
42
130
 
43
131
  /**
44
132
  * Create a Syncular telemetry backend wired to `@sentry/cloudflare`.
@@ -123,3 +211,20 @@ export function captureCloudflareSentryMessage(
123
211
  Sentry.captureMessage(message, options?.level);
124
212
  });
125
213
  }
214
+
215
+ /**
216
+ * Emit a Cloudflare Sentry log entry.
217
+ */
218
+ export function logCloudflareSentryMessage(
219
+ message: string,
220
+ options?: CloudflareSentryLogOptions
221
+ ): void {
222
+ const level = options?.level ?? 'info';
223
+ const logMethod = resolveCloudflareLogMethod(level);
224
+ if (!logMethod) return;
225
+ if (!options?.attributes || Object.keys(options.attributes).length === 0) {
226
+ logMethod(message);
227
+ return;
228
+ }
229
+ logMethod(message, options.attributes);
230
+ }
@@ -101,4 +101,45 @@ describe('createSentrySyncTelemetry', () => {
101
101
  attributes: { requestId: 'r1' },
102
102
  });
103
103
  });
104
+
105
+ test('sanitizes non-primitive log attributes', () => {
106
+ const logs: Array<{
107
+ level: string;
108
+ message: string;
109
+ attributes?: Record<string, unknown>;
110
+ }> = [];
111
+
112
+ const telemetry = createSentrySyncTelemetry({
113
+ logger: {
114
+ info(message, attributes) {
115
+ logs.push({ level: 'info', message, attributes });
116
+ },
117
+ },
118
+ });
119
+
120
+ telemetry.log({
121
+ event: 'sync.attributes',
122
+ id: 'abc',
123
+ nested: { ok: true },
124
+ values: [1, 2, 3],
125
+ enabled: true,
126
+ count: 3,
127
+ ignored: undefined,
128
+ nonFinite: Number.POSITIVE_INFINITY,
129
+ });
130
+
131
+ expect(logs).toEqual([
132
+ {
133
+ level: 'info',
134
+ message: 'sync.attributes',
135
+ attributes: {
136
+ id: 'abc',
137
+ nested: '{"ok":true}',
138
+ values: '[1,2,3]',
139
+ enabled: true,
140
+ count: 3,
141
+ },
142
+ },
143
+ ]);
144
+ });
104
145
  });
package/src/shared.ts CHANGED
@@ -97,6 +97,47 @@ function toSpan(span: SentrySpanAdapter): SyncSpan {
97
97
  };
98
98
  }
99
99
 
100
+ function toLogAttributeValue(
101
+ value: unknown
102
+ ): SyncTelemetryAttributeValue | undefined {
103
+ if (typeof value === 'string') return value;
104
+ if (typeof value === 'number') {
105
+ return Number.isFinite(value) ? value : undefined;
106
+ }
107
+ if (typeof value === 'boolean') return value;
108
+ if (typeof value === 'bigint') {
109
+ const asNumber = Number(value);
110
+ if (Number.isFinite(asNumber)) return asNumber;
111
+ return value.toString();
112
+ }
113
+ if (value instanceof Date) return value.toISOString();
114
+ if (value === null || value === undefined) return undefined;
115
+
116
+ if (Array.isArray(value) || typeof value === 'object') {
117
+ try {
118
+ return JSON.stringify(value);
119
+ } catch {
120
+ return String(value);
121
+ }
122
+ }
123
+
124
+ return String(value);
125
+ }
126
+
127
+ function sanitizeLogAttributes(
128
+ attributes: Record<string, unknown>
129
+ ): Record<string, SyncTelemetryAttributeValue> | null {
130
+ const sanitized: Record<string, SyncTelemetryAttributeValue> = {};
131
+ for (const [name, value] of Object.entries(attributes)) {
132
+ const normalized = toLogAttributeValue(value);
133
+ if (normalized !== undefined) {
134
+ sanitized[name] = normalized;
135
+ }
136
+ }
137
+
138
+ return Object.keys(sanitized).length > 0 ? sanitized : null;
139
+ }
140
+
100
141
  function createTracer(adapter: SentryTelemetryAdapter): SyncTracer {
101
142
  return {
102
143
  startSpan<T>(options: SyncSpanOptions, callback: (span: SyncSpan) => T): T {
@@ -132,11 +173,12 @@ export function createSentrySyncTelemetry(
132
173
  const { event: message, ...attributes } = event;
133
174
  const logMethod = resolveLogMethod(adapter.logger, level);
134
175
  if (!logMethod) return;
135
- if (Object.keys(attributes).length === 0) {
176
+ const sanitizedAttributes = sanitizeLogAttributes(attributes);
177
+ if (!sanitizedAttributes) {
136
178
  logMethod(message);
137
179
  return;
138
180
  }
139
- logMethod(message, attributes);
181
+ logMethod(message, sanitizedAttributes);
140
182
  },
141
183
  tracer: createTracer(adapter),
142
184
  metrics: createMetrics(adapter),
@@ -147,7 +189,12 @@ export function createSentrySyncTelemetry(
147
189
  resolveLogMethod(adapter.logger, 'error') ??
148
190
  resolveLogMethod(adapter.logger, 'info');
149
191
  if (!logMethod) return;
150
- logMethod('sync.exception.context', context);
192
+ const sanitizedContext = sanitizeLogAttributes(context);
193
+ if (!sanitizedContext) {
194
+ logMethod('sync.exception.context');
195
+ return;
196
+ }
197
+ logMethod('sync.exception.context', sanitizedContext);
151
198
  },
152
199
  };
153
200
  }