@raccoon.ninja/otel-react 1.0.0 → 1.1.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/README.md +15 -14
- package/dist/index.cjs +17 -10
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +14 -1
- package/dist/index.d.ts +14 -1
- package/dist/index.mjs +17 -10
- package/dist/index.mjs.map +1 -1
- package/dist/native/index.cjs +8 -6
- package/dist/native/index.cjs.map +1 -1
- package/dist/native/index.d.mts +11 -0
- package/dist/native/index.d.ts +11 -0
- package/dist/native/index.mjs +8 -6
- package/dist/native/index.mjs.map +1 -1
- package/dist/nextjs/index.cjs +5 -3
- package/dist/nextjs/index.cjs.map +1 -1
- package/dist/nextjs/index.d.mts +11 -0
- package/dist/nextjs/index.d.ts +11 -0
- package/dist/nextjs/index.mjs +5 -3
- package/dist/nextjs/index.mjs.map +1 -1
- package/package.json +33 -33
package/README.md
CHANGED
|
@@ -53,20 +53,21 @@ All telemetry is sent to `http://localhost:4318` by default (the standard OTLP H
|
|
|
53
53
|
|
|
54
54
|
### OtelProvider Props
|
|
55
55
|
|
|
56
|
-
| Prop
|
|
57
|
-
|
|
|
58
|
-
| `serviceName`
|
|
59
|
-
| `endpoint`
|
|
60
|
-
| `serviceVersion`
|
|
61
|
-
| `environment`
|
|
62
|
-
| `headers`
|
|
63
|
-
| `exportTimeout`
|
|
64
|
-
| `ignoreUrls`
|
|
65
|
-
| `
|
|
66
|
-
| `
|
|
67
|
-
| `
|
|
68
|
-
| `
|
|
69
|
-
| `
|
|
56
|
+
| Prop | Type | Default | Description |
|
|
57
|
+
| ------------------------------ | ------------------------ | ----------------------- | --------------------------------------------------------------- |
|
|
58
|
+
| `serviceName` | `string` | **(required)** | Sets the `service.name` resource attribute |
|
|
59
|
+
| `endpoint` | `string` | `http://localhost:4318` | OTLP HTTP collector endpoint |
|
|
60
|
+
| `serviceVersion` | `string` | -- | Sets `service.version` resource attribute |
|
|
61
|
+
| `environment` | `string` | -- | Sets `deployment.environment` resource attribute |
|
|
62
|
+
| `headers` | `Record<string, string>` | -- | Custom headers for OTLP requests (e.g., auth tokens) |
|
|
63
|
+
| `exportTimeout` | `number` | `30000` | Export timeout in milliseconds |
|
|
64
|
+
| `ignoreUrls` | `(string \| RegExp)[]` | -- | URLs to exclude from fetch/XHR instrumentation |
|
|
65
|
+
| `propagateTraceHeaderCorsUrls` | `(string \| RegExp)[]` | `[]` | Cross-origin URLs that should receive W3C Trace Context headers |
|
|
66
|
+
| `instrumentations` | `InstrumentationConfig` | all enabled | Enable/disable specific auto-instrumentations |
|
|
67
|
+
| `resourceAttributes` | `Record<string, string>` | -- | Additional OTel resource attributes |
|
|
68
|
+
| `extensions` | `OtelExtension[]` | -- | Opt-in extensions (e.g., `withReactRouter()`) |
|
|
69
|
+
| `configureTracing` | `(provider) => void` | -- | Escape hatch to configure the TracerProvider |
|
|
70
|
+
| `configureExporter` | `(exporter) => void` | -- | Escape hatch to configure the OTLP exporter |
|
|
70
71
|
|
|
71
72
|
### Pointing to a Collector
|
|
72
73
|
|
package/dist/index.cjs
CHANGED
|
@@ -66,7 +66,7 @@ function validateOptions(options) {
|
|
|
66
66
|
}
|
|
67
67
|
}
|
|
68
68
|
var SDK_NAME = "@raccoon.ninja/otel-react";
|
|
69
|
-
var SDK_VERSION = "1.
|
|
69
|
+
var SDK_VERSION = "1.1.0";
|
|
70
70
|
function buildResource(options) {
|
|
71
71
|
const attributes = {
|
|
72
72
|
[semanticConventions.ATTR_SERVICE_NAME]: options.serviceName,
|
|
@@ -121,8 +121,10 @@ function createLoggerProvider(options, resource) {
|
|
|
121
121
|
headers: options.headers,
|
|
122
122
|
timeoutMillis: timeout
|
|
123
123
|
});
|
|
124
|
-
const provider = new sdkLogs.LoggerProvider({
|
|
125
|
-
|
|
124
|
+
const provider = new sdkLogs.LoggerProvider({
|
|
125
|
+
resource,
|
|
126
|
+
processors: [new sdkLogs.BatchLogRecordProcessor(exporter)]
|
|
127
|
+
});
|
|
126
128
|
apiLogs.logs.setGlobalLoggerProvider(provider);
|
|
127
129
|
return provider;
|
|
128
130
|
}
|
|
@@ -151,17 +153,20 @@ function registerAutoInstrumentations(options) {
|
|
|
151
153
|
const config = resolveInstrumentations(options);
|
|
152
154
|
const ignoreUrls = options.ignoreUrls ?? [];
|
|
153
155
|
const instrumentations = [];
|
|
156
|
+
const propagateTraceHeaderCorsUrls = options.propagateTraceHeaderCorsUrls ?? [];
|
|
154
157
|
if (config.fetch) {
|
|
155
158
|
instrumentations.push(
|
|
156
159
|
new instrumentationFetch.FetchInstrumentation({
|
|
157
|
-
ignoreUrls
|
|
160
|
+
ignoreUrls,
|
|
161
|
+
propagateTraceHeaderCorsUrls
|
|
158
162
|
})
|
|
159
163
|
);
|
|
160
164
|
}
|
|
161
165
|
if (config.xhr) {
|
|
162
166
|
instrumentations.push(
|
|
163
167
|
new instrumentationXmlHttpRequest.XMLHttpRequestInstrumentation({
|
|
164
|
-
ignoreUrls
|
|
168
|
+
ignoreUrls,
|
|
169
|
+
propagateTraceHeaderCorsUrls
|
|
165
170
|
})
|
|
166
171
|
);
|
|
167
172
|
}
|
|
@@ -177,7 +182,7 @@ function registerAutoInstrumentations(options) {
|
|
|
177
182
|
}
|
|
178
183
|
var METER_NAME = "@raccoon.ninja/otel-react/web-vitals";
|
|
179
184
|
function startWebVitalsCollection() {
|
|
180
|
-
const meter = api.metrics.getMeter(METER_NAME, "1.
|
|
185
|
+
const meter = api.metrics.getMeter(METER_NAME, "1.1.0");
|
|
181
186
|
const lcpHistogram = meter.createHistogram("web_vitals.lcp", {
|
|
182
187
|
description: "Largest Contentful Paint",
|
|
183
188
|
unit: "ms"
|
|
@@ -299,7 +304,7 @@ function initOtel(options) {
|
|
|
299
304
|
ext({ tracerProvider });
|
|
300
305
|
}
|
|
301
306
|
}
|
|
302
|
-
const logger = loggerProvider.getLogger("@raccoon.ninja/otel-react", "1.
|
|
307
|
+
const logger = loggerProvider.getLogger("@raccoon.ninja/otel-react", "1.1.0");
|
|
303
308
|
logger.emit({
|
|
304
309
|
severityNumber: apiLogs.SeverityNumber.INFO,
|
|
305
310
|
severityText: "INFO",
|
|
@@ -327,6 +332,7 @@ function OtelProvider({
|
|
|
327
332
|
headers,
|
|
328
333
|
exportTimeout,
|
|
329
334
|
ignoreUrls,
|
|
335
|
+
propagateTraceHeaderCorsUrls,
|
|
330
336
|
configureTracing,
|
|
331
337
|
configureExporter,
|
|
332
338
|
extensions
|
|
@@ -343,6 +349,7 @@ function OtelProvider({
|
|
|
343
349
|
headers,
|
|
344
350
|
exportTimeout,
|
|
345
351
|
ignoreUrls,
|
|
352
|
+
propagateTraceHeaderCorsUrls,
|
|
346
353
|
configureTracing,
|
|
347
354
|
configureExporter,
|
|
348
355
|
extensions
|
|
@@ -366,7 +373,7 @@ var TracedErrorBoundary = class extends react.Component {
|
|
|
366
373
|
return { hasError: true, error };
|
|
367
374
|
}
|
|
368
375
|
componentDidCatch(error, errorInfo) {
|
|
369
|
-
const tracer = api.trace.getTracer(TRACER_NAME, "1.
|
|
376
|
+
const tracer = api.trace.getTracer(TRACER_NAME, "1.1.0");
|
|
370
377
|
const span = tracer.startSpan("error-boundary.catch");
|
|
371
378
|
span.setStatus({ code: api.SpanStatusCode.ERROR, message: error.message });
|
|
372
379
|
span.setAttribute("error.type", error.name);
|
|
@@ -380,7 +387,7 @@ var TracedErrorBoundary = class extends react.Component {
|
|
|
380
387
|
span.recordException(error);
|
|
381
388
|
span.end();
|
|
382
389
|
try {
|
|
383
|
-
const logger = apiLogs.logs.getLogger(LOGGER_NAME, "1.
|
|
390
|
+
const logger = apiLogs.logs.getLogger(LOGGER_NAME, "1.1.0");
|
|
384
391
|
logger.emit({
|
|
385
392
|
severityNumber: apiLogs.SeverityNumber.ERROR,
|
|
386
393
|
severityText: "ERROR",
|
|
@@ -417,7 +424,7 @@ function useTracer(name, version) {
|
|
|
417
424
|
var TRACER_NAME2 = "@raccoon.ninja/otel-react/router";
|
|
418
425
|
function withReactRouter() {
|
|
419
426
|
return (_context) => {
|
|
420
|
-
api.trace.getTracer(TRACER_NAME2, "1.
|
|
427
|
+
api.trace.getTracer(TRACER_NAME2, "1.1.0");
|
|
421
428
|
};
|
|
422
429
|
}
|
|
423
430
|
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/core/options.ts","../src/core/resource.ts","../src/providers/tracer.ts","../src/providers/logger.ts","../src/providers/meter.ts","../src/instrumentations/auto.ts","../src/instrumentations/web-vitals.ts","../src/core/shutdown.ts","../src/core/init.ts","../src/components/OtelProvider.tsx","../src/components/TracedErrorBoundary.tsx","../src/hooks/useTracer.ts","../src/instrumentations/router.ts"],"names":["ATTR_SERVICE_NAME","ATTR_SERVICE_VERSION","SEMRESATTRS_DEPLOYMENT_ENVIRONMENT","resourceFromAttributes","OTLPTraceExporter","WebTracerProvider","BatchSpanProcessor","OTLPLogExporter","LoggerProvider","BatchLogRecordProcessor","logs","OTLPMetricExporter","MeterProvider","PeriodicExportingMetricReader","metrics","FetchInstrumentation","XMLHttpRequestInstrumentation","DocumentLoadInstrumentation","UserInteractionInstrumentation","registerInstrumentations","SeverityNumber","useRef","useEffect","Component","trace","SpanStatusCode","useMemo","TRACER_NAME"],"mappings":"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","file":"index.cjs","sourcesContent":["import type { WebTracerProvider } from '@opentelemetry/sdk-trace-web';\nimport type { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';\n\n/** Configuration for enabling/disabling specific auto-instrumentations. */\nexport interface InstrumentationConfig {\n /** Auto-instrument fetch() calls. Default: true */\n fetch?: boolean;\n /** Auto-instrument XMLHttpRequest. Default: true */\n xhr?: boolean;\n /** Document load timing spans. Default: true */\n documentLoad?: boolean;\n /** Click/input interaction spans. Default: true */\n userInteraction?: boolean;\n /** LCP, CLS, INP, TTFB, FCP metrics. Default: true */\n webVitals?: boolean;\n}\n\n/** Extension function type for opt-in instrumentations (e.g., withReactRouter). */\nexport type OtelExtension = (context: ExtensionContext) => void;\n\n/** Context provided to extension functions during initialization. */\nexport interface ExtensionContext {\n tracerProvider: WebTracerProvider;\n}\n\n/** Configuration options for initOtel(). */\nexport interface OtelOptions {\n /** Required. Sets the service.name resource attribute. */\n serviceName: string;\n\n /** OTLP HTTP endpoint. Default: 'http://localhost:4318' */\n endpoint?: string;\n\n /** Additional OTel resource attributes. */\n resourceAttributes?: Record<string, string>;\n\n /** Service version. Sets service.version resource attribute. */\n serviceVersion?: string;\n\n /** Deployment environment. Sets deployment.environment resource attribute. */\n environment?: string;\n\n /** Enable/disable specific auto-instrumentations. All enabled by default. */\n instrumentations?: InstrumentationConfig;\n\n /** Escape hatch: configure the TracerProvider before it's registered. */\n configureTracing?: (provider: WebTracerProvider) => void;\n\n /** Escape hatch: configure the OTLP exporter. */\n configureExporter?: (exporter: OTLPTraceExporter) => void;\n\n /** Custom headers sent with OTLP export requests (e.g., auth tokens). */\n headers?: Record<string, string>;\n\n /** Export timeout in milliseconds. Default: 30000 */\n exportTimeout?: number;\n\n /**\n * URLs to exclude from fetch/XHR instrumentation.\n * Supports string patterns or RegExp.\n */\n ignoreUrls?: Array<string | RegExp>;\n\n /** Extension functions for opt-in instrumentations. */\n extensions?: OtelExtension[];\n}\n\n/** Handle returned from initOtel() for lifecycle management. */\nexport interface OtelHandle {\n /** Flush all pending telemetry and shut down providers. */\n shutdown: () => Promise<void>;\n}\n\nconst DEFAULT_ENDPOINT = 'http://localhost:4318';\nconst DEFAULT_EXPORT_TIMEOUT = 30000;\n\nexport function resolveEndpoint(options: OtelOptions): string {\n return options.endpoint ?? DEFAULT_ENDPOINT;\n}\n\nexport function resolveExportTimeout(options: OtelOptions): number {\n return options.exportTimeout ?? DEFAULT_EXPORT_TIMEOUT;\n}\n\nexport function resolveInstrumentations(options: OtelOptions): Required<InstrumentationConfig> {\n return {\n fetch: options.instrumentations?.fetch ?? true,\n xhr: options.instrumentations?.xhr ?? true,\n documentLoad: options.instrumentations?.documentLoad ?? true,\n userInteraction: options.instrumentations?.userInteraction ?? true,\n webVitals: options.instrumentations?.webVitals ?? true,\n };\n}\n\nexport function validateOptions(options: OtelOptions): void {\n if (!options.serviceName || typeof options.serviceName !== 'string') {\n throw new Error(\n '[@raccoon.ninja/otel-react] serviceName is required and must be a non-empty string.',\n );\n }\n\n if (options.serviceName.trim() !== options.serviceName) {\n throw new Error(\n '[@raccoon.ninja/otel-react] serviceName must not have leading or trailing whitespace.',\n );\n }\n\n if (options.endpoint !== undefined) {\n if (typeof options.endpoint !== 'string' || options.endpoint.trim() === '') {\n throw new Error(\n '[@raccoon.ninja/otel-react] endpoint must be a non-empty string when provided.',\n );\n }\n }\n\n if (options.exportTimeout !== undefined) {\n if (typeof options.exportTimeout !== 'number' || options.exportTimeout <= 0) {\n throw new Error(\n '[@raccoon.ninja/otel-react] exportTimeout must be a positive number when provided.',\n );\n }\n }\n}\n","import { resourceFromAttributes } from '@opentelemetry/resources';\nimport {\n ATTR_SERVICE_NAME,\n ATTR_SERVICE_VERSION,\n SEMRESATTRS_DEPLOYMENT_ENVIRONMENT,\n} from '@opentelemetry/semantic-conventions';\nimport type { OtelOptions } from './options';\n\nconst SDK_NAME = '@raccoon.ninja/otel-react';\nconst SDK_VERSION = '1.0.0';\n\nexport function buildResource(options: OtelOptions) {\n const attributes: Record<string, string> = {\n [ATTR_SERVICE_NAME]: options.serviceName,\n 'telemetry.sdk.name': SDK_NAME,\n 'telemetry.sdk.version': SDK_VERSION,\n 'telemetry.sdk.language': 'webjs',\n };\n\n if (options.serviceVersion) {\n attributes[ATTR_SERVICE_VERSION] = options.serviceVersion;\n }\n\n if (options.environment) {\n attributes[SEMRESATTRS_DEPLOYMENT_ENVIRONMENT] = options.environment;\n }\n\n if (typeof navigator !== 'undefined') {\n if (navigator.language) {\n attributes['browser.language'] = navigator.language;\n }\n if (navigator.userAgent) {\n attributes['browser.user_agent'] = navigator.userAgent;\n }\n if (navigator.platform) {\n attributes['browser.platform'] = navigator.platform;\n }\n }\n\n if (options.resourceAttributes) {\n Object.assign(attributes, options.resourceAttributes);\n }\n\n return resourceFromAttributes(attributes);\n}\n","import { WebTracerProvider } from '@opentelemetry/sdk-trace-web';\nimport { BatchSpanProcessor } from '@opentelemetry/sdk-trace-base';\nimport { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';\nimport type { Resource } from '@opentelemetry/resources';\nimport type { OtelOptions } from '../core/options';\nimport { resolveEndpoint, resolveExportTimeout } from '../core/options';\n\nexport interface TracerSetupResult {\n provider: WebTracerProvider;\n exporter: OTLPTraceExporter;\n}\n\nexport function createTracerProvider(options: OtelOptions, resource: Resource): TracerSetupResult {\n const endpoint = resolveEndpoint(options);\n const timeout = resolveExportTimeout(options);\n\n const exporter = new OTLPTraceExporter({\n url: `${endpoint}/v1/traces`,\n headers: options.headers,\n timeoutMillis: timeout,\n });\n\n options.configureExporter?.(exporter);\n\n const provider = new WebTracerProvider({\n resource,\n spanProcessors: [new BatchSpanProcessor(exporter)],\n });\n\n options.configureTracing?.(provider);\n\n provider.register();\n\n return { provider, exporter };\n}\n","import { LoggerProvider, BatchLogRecordProcessor } from '@opentelemetry/sdk-logs';\nimport { OTLPLogExporter } from '@opentelemetry/exporter-logs-otlp-http';\nimport { logs } from '@opentelemetry/api-logs';\nimport type { Resource } from '@opentelemetry/resources';\nimport type { OtelOptions } from '../core/options';\nimport { resolveEndpoint, resolveExportTimeout } from '../core/options';\n\nexport function createLoggerProvider(options: OtelOptions, resource: Resource): LoggerProvider {\n const endpoint = resolveEndpoint(options);\n const timeout = resolveExportTimeout(options);\n\n const exporter = new OTLPLogExporter({\n url: `${endpoint}/v1/logs`,\n headers: options.headers,\n timeoutMillis: timeout,\n });\n\n const provider = new LoggerProvider({ resource });\n provider.addLogRecordProcessor(new BatchLogRecordProcessor(exporter));\n\n logs.setGlobalLoggerProvider(provider);\n\n return provider;\n}\n","import { MeterProvider, PeriodicExportingMetricReader } from '@opentelemetry/sdk-metrics';\nimport { OTLPMetricExporter } from '@opentelemetry/exporter-metrics-otlp-http';\nimport { metrics } from '@opentelemetry/api';\nimport type { Resource } from '@opentelemetry/resources';\nimport type { OtelOptions } from '../core/options';\nimport { resolveEndpoint, resolveExportTimeout } from '../core/options';\n\nconst METRIC_EXPORT_INTERVAL_MS = 30_000;\n\nexport function createMeterProvider(options: OtelOptions, resource: Resource): MeterProvider {\n const endpoint = resolveEndpoint(options);\n const timeout = resolveExportTimeout(options);\n\n const exporter = new OTLPMetricExporter({\n url: `${endpoint}/v1/metrics`,\n headers: options.headers,\n timeoutMillis: timeout,\n });\n\n const provider = new MeterProvider({\n resource,\n readers: [\n new PeriodicExportingMetricReader({\n exporter,\n exportIntervalMillis: METRIC_EXPORT_INTERVAL_MS,\n }),\n ],\n });\n\n metrics.setGlobalMeterProvider(provider);\n\n return provider;\n}\n","import { registerInstrumentations } from '@opentelemetry/instrumentation';\nimport { FetchInstrumentation } from '@opentelemetry/instrumentation-fetch';\nimport { XMLHttpRequestInstrumentation } from '@opentelemetry/instrumentation-xml-http-request';\nimport { DocumentLoadInstrumentation } from '@opentelemetry/instrumentation-document-load';\nimport { UserInteractionInstrumentation } from '@opentelemetry/instrumentation-user-interaction';\nimport type { InstrumentationConfig, OtelOptions } from '../core/options';\nimport { resolveInstrumentations } from '../core/options';\n\nexport function registerAutoInstrumentations(options: OtelOptions): void {\n const config: Required<InstrumentationConfig> = resolveInstrumentations(options);\n const ignoreUrls = options.ignoreUrls ?? [];\n\n const instrumentations = [];\n\n if (config.fetch) {\n instrumentations.push(\n new FetchInstrumentation({\n ignoreUrls,\n }),\n );\n }\n\n if (config.xhr) {\n instrumentations.push(\n new XMLHttpRequestInstrumentation({\n ignoreUrls,\n }),\n );\n }\n\n if (config.documentLoad) {\n instrumentations.push(new DocumentLoadInstrumentation());\n }\n\n if (config.userInteraction) {\n instrumentations.push(new UserInteractionInstrumentation());\n }\n\n if (instrumentations.length > 0) {\n registerInstrumentations({ instrumentations });\n }\n}\n","import { metrics } from '@opentelemetry/api';\nimport type { Metric } from 'web-vitals';\n\nconst METER_NAME = '@raccoon.ninja/otel-react/web-vitals';\n\nexport function startWebVitalsCollection(): void {\n const meter = metrics.getMeter(METER_NAME, '1.0.0');\n\n const lcpHistogram = meter.createHistogram('web_vitals.lcp', {\n description: 'Largest Contentful Paint',\n unit: 'ms',\n });\n\n const clsHistogram = meter.createHistogram('web_vitals.cls', {\n description: 'Cumulative Layout Shift',\n unit: '',\n });\n\n const inpHistogram = meter.createHistogram('web_vitals.inp', {\n description: 'Interaction to Next Paint',\n unit: 'ms',\n });\n\n const ttfbHistogram = meter.createHistogram('web_vitals.ttfb', {\n description: 'Time to First Byte',\n unit: 'ms',\n });\n\n const fcpHistogram = meter.createHistogram('web_vitals.fcp', {\n description: 'First Contentful Paint',\n unit: 'ms',\n });\n\n const recordMetric = (histogram: ReturnType<typeof meter.createHistogram>) => {\n return (metric: Metric) => {\n const attrs: Record<string, string> = {\n 'web_vitals.rating': metric.rating,\n };\n\n if (typeof window !== 'undefined' && window.location) {\n attrs['page.url'] = window.location.pathname;\n }\n\n histogram.record(metric.value, attrs);\n };\n };\n\n // Dynamic import to enable tree-shaking when web-vitals is not used\n import('web-vitals').then(({ onLCP, onCLS, onINP, onTTFB, onFCP }) => {\n onLCP(recordMetric(lcpHistogram));\n onCLS(recordMetric(clsHistogram));\n onINP(recordMetric(inpHistogram));\n onTTFB(recordMetric(ttfbHistogram));\n onFCP(recordMetric(fcpHistogram));\n });\n}\n","import type { WebTracerProvider } from '@opentelemetry/sdk-trace-web';\nimport type { LoggerProvider } from '@opentelemetry/sdk-logs';\nimport type { MeterProvider } from '@opentelemetry/sdk-metrics';\n\nexport interface ShutdownTargets {\n tracerProvider: WebTracerProvider;\n loggerProvider: LoggerProvider;\n meterProvider: MeterProvider;\n}\n\nlet shutdownTargets: ShutdownTargets | null = null;\nlet visibilityHandler: (() => void) | null = null;\nlet beforeUnloadHandler: (() => void) | null = null;\n\nexport function registerShutdownTargets(targets: ShutdownTargets): void {\n shutdownTargets = targets;\n\n visibilityHandler = () => {\n if (document.visibilityState === 'hidden') {\n flushAll();\n }\n };\n\n beforeUnloadHandler = () => {\n flushAll();\n };\n\n if (typeof document !== 'undefined') {\n document.addEventListener('visibilitychange', visibilityHandler);\n }\n if (typeof window !== 'undefined') {\n window.addEventListener('beforeunload', beforeUnloadHandler);\n }\n}\n\nfunction flushAll(): void {\n if (!shutdownTargets) return;\n\n try {\n shutdownTargets.tracerProvider.forceFlush();\n shutdownTargets.loggerProvider.forceFlush();\n shutdownTargets.meterProvider.forceFlush();\n } catch {\n // Flush is best-effort during page unload\n }\n}\n\nexport async function shutdown(): Promise<void> {\n if (!shutdownTargets) return;\n\n if (typeof document !== 'undefined' && visibilityHandler) {\n document.removeEventListener('visibilitychange', visibilityHandler);\n }\n if (typeof window !== 'undefined' && beforeUnloadHandler) {\n window.removeEventListener('beforeunload', beforeUnloadHandler);\n }\n\n try {\n await Promise.all([\n shutdownTargets.tracerProvider.forceFlush(),\n shutdownTargets.loggerProvider.forceFlush(),\n shutdownTargets.meterProvider.forceFlush(),\n ]);\n\n await Promise.all([\n shutdownTargets.tracerProvider.shutdown(),\n shutdownTargets.loggerProvider.shutdown(),\n shutdownTargets.meterProvider.shutdown(),\n ]);\n } finally {\n shutdownTargets = null;\n visibilityHandler = null;\n beforeUnloadHandler = null;\n }\n}\n","import { SeverityNumber } from '@opentelemetry/api-logs';\nimport type { OtelOptions, OtelHandle } from './options';\nimport { validateOptions, resolveInstrumentations } from './options';\nimport { buildResource } from './resource';\nimport { createTracerProvider } from '../providers/tracer';\nimport { createLoggerProvider } from '../providers/logger';\nimport { createMeterProvider } from '../providers/meter';\nimport { registerAutoInstrumentations } from '../instrumentations/auto';\nimport { startWebVitalsCollection } from '../instrumentations/web-vitals';\nimport { registerShutdownTargets, shutdown } from './shutdown';\n\nlet initialized = false;\n\nexport function initOtel(options: OtelOptions): OtelHandle {\n if (initialized) {\n console.warn(\n '[@raccoon.ninja/otel-react] initOtel() has already been called. Skipping re-initialization.',\n );\n return { shutdown };\n }\n\n validateOptions(options);\n\n const resource = buildResource(options);\n const { provider: tracerProvider } = createTracerProvider(options, resource);\n const loggerProvider = createLoggerProvider(options, resource);\n const meterProvider = createMeterProvider(options, resource);\n\n registerAutoInstrumentations(options);\n\n const instrumentationConfig = resolveInstrumentations(options);\n if (instrumentationConfig.webVitals) {\n startWebVitalsCollection();\n }\n\n registerShutdownTargets({ tracerProvider, loggerProvider, meterProvider });\n\n // Run extensions\n if (options.extensions) {\n for (const ext of options.extensions) {\n ext({ tracerProvider });\n }\n }\n\n // Log initialization success\n const logger = loggerProvider.getLogger('@raccoon.ninja/otel-react', '1.0.0');\n logger.emit({\n severityNumber: SeverityNumber.INFO,\n severityText: 'INFO',\n body: `OpenTelemetry initialized for service \"${options.serviceName}\"`,\n attributes: {\n 'otel.service_name': options.serviceName,\n },\n });\n\n initialized = true;\n\n return {\n shutdown: async () => {\n await shutdown();\n initialized = false;\n },\n };\n}\n\n/** Reset initialization state (for testing). */\nexport function _resetInitState(): void {\n initialized = false;\n}\n","import { useEffect, useRef, type ReactNode } from 'react';\nimport { initOtel } from '../core/init';\nimport type { OtelOptions, OtelHandle, OtelExtension } from '../core/options';\n\n/** Props for the OtelProvider component. */\nexport interface OtelProviderProps {\n /** Required. Sets the service.name resource attribute. */\n serviceName: string;\n /** OTLP HTTP endpoint. Default: 'http://localhost:4318' */\n endpoint?: string;\n /** Additional OTel resource attributes. */\n resourceAttributes?: Record<string, string>;\n /** Service version. */\n serviceVersion?: string;\n /** Deployment environment. */\n environment?: string;\n /** Enable/disable specific auto-instrumentations. */\n instrumentations?: OtelOptions['instrumentations'];\n /** Custom headers sent with OTLP export requests. */\n headers?: Record<string, string>;\n /** Export timeout in milliseconds. */\n exportTimeout?: number;\n /** URLs to exclude from fetch/XHR instrumentation. */\n ignoreUrls?: Array<string | RegExp>;\n /** Escape hatch: configure the TracerProvider. */\n configureTracing?: OtelOptions['configureTracing'];\n /** Escape hatch: configure the OTLP exporter. */\n configureExporter?: OtelOptions['configureExporter'];\n /** Extension functions for opt-in instrumentations. */\n extensions?: OtelExtension[];\n /** React children to render. */\n children: ReactNode;\n}\n\n/**\n * React Provider component that initializes OpenTelemetry on mount\n * and flushes/shuts down on unmount.\n *\n * @example\n * ```tsx\n * import { OtelProvider } from '@raccoon.ninja/otel-react';\n *\n * function App() {\n * return (\n * <OtelProvider serviceName=\"my-app\">\n * <RestOfTheApp />\n * </OtelProvider>\n * );\n * }\n * ```\n */\nexport function OtelProvider({\n children,\n serviceName,\n endpoint,\n resourceAttributes,\n serviceVersion,\n environment,\n instrumentations,\n headers,\n exportTimeout,\n ignoreUrls,\n configureTracing,\n configureExporter,\n extensions,\n}: OtelProviderProps) {\n const handleRef = useRef<OtelHandle | null>(null);\n\n useEffect(() => {\n const handle = initOtel({\n serviceName,\n endpoint,\n resourceAttributes,\n serviceVersion,\n environment,\n instrumentations,\n headers,\n exportTimeout,\n ignoreUrls,\n configureTracing,\n configureExporter,\n extensions,\n });\n\n handleRef.current = handle;\n\n return () => {\n handleRef.current?.shutdown();\n handleRef.current = null;\n };\n // We intentionally only run this on mount/unmount.\n // Config changes require remounting the provider.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n return <>{children}</>;\n}\n","import { Component, type ReactNode, type ErrorInfo } from 'react';\nimport { trace, SpanStatusCode } from '@opentelemetry/api';\nimport { SeverityNumber } from '@opentelemetry/api-logs';\nimport { logs } from '@opentelemetry/api-logs';\n\nconst TRACER_NAME = '@raccoon.ninja/otel-react/error-boundary';\nconst LOGGER_NAME = '@raccoon.ninja/otel-react/error-boundary';\n\n/** Props for the TracedErrorBoundary component. */\nexport interface TracedErrorBoundaryProps {\n /** Fallback UI to render when an error is caught. */\n fallback: ReactNode | ((error: Error, reset: () => void) => ReactNode);\n /** Optional callback when an error is caught. */\n onError?: (error: Error, errorInfo: ErrorInfo) => void;\n /** Children to render. */\n children: ReactNode;\n}\n\ninterface TracedErrorBoundaryState {\n hasError: boolean;\n error: Error | null;\n}\n\n/**\n * Error boundary that records caught errors as OpenTelemetry spans and logs.\n *\n * @example\n * ```tsx\n * import { TracedErrorBoundary } from '@raccoon.ninja/otel-react';\n *\n * <TracedErrorBoundary fallback={<ErrorPage />}>\n * <RiskyComponent />\n * </TracedErrorBoundary>\n * ```\n */\nexport class TracedErrorBoundary extends Component<\n TracedErrorBoundaryProps,\n TracedErrorBoundaryState\n> {\n constructor(props: TracedErrorBoundaryProps) {\n super(props);\n this.state = { hasError: false, error: null };\n }\n\n static getDerivedStateFromError(error: Error): TracedErrorBoundaryState {\n return { hasError: true, error };\n }\n\n componentDidCatch(error: Error, errorInfo: ErrorInfo): void {\n const tracer = trace.getTracer(TRACER_NAME, '1.0.0');\n const span = tracer.startSpan('error-boundary.catch');\n\n span.setStatus({ code: SpanStatusCode.ERROR, message: error.message });\n span.setAttribute('error.type', error.name);\n span.setAttribute('error.message', error.message);\n\n if (error.stack) {\n span.setAttribute('error.stack', error.stack);\n }\n if (errorInfo.componentStack) {\n span.setAttribute('error.component_stack', errorInfo.componentStack);\n }\n\n span.recordException(error);\n span.end();\n\n // Also emit as a log record\n try {\n const logger = logs.getLogger(LOGGER_NAME, '1.0.0');\n logger.emit({\n severityNumber: SeverityNumber.ERROR,\n severityText: 'ERROR',\n body: `Unhandled error: ${error.message}`,\n attributes: {\n 'error.type': error.name,\n 'error.message': error.message,\n ...(error.stack ? { 'error.stack': error.stack } : {}),\n ...(errorInfo.componentStack\n ? { 'error.component_stack': errorInfo.componentStack }\n : {}),\n },\n });\n } catch {\n // Logging is best-effort\n }\n\n this.props.onError?.(error, errorInfo);\n }\n\n private reset = () => {\n this.setState({ hasError: false, error: null });\n };\n\n render() {\n if (this.state.hasError && this.state.error) {\n const { fallback } = this.props;\n if (typeof fallback === 'function') {\n return fallback(this.state.error, this.reset);\n }\n return fallback;\n }\n\n return this.props.children;\n }\n}\n","import { useMemo } from 'react';\nimport { trace, type Tracer } from '@opentelemetry/api';\n\nconst DEFAULT_TRACER_NAME = '@raccoon.ninja/otel-react/custom';\n\n/**\n * Hook to get an OpenTelemetry Tracer for creating custom spans.\n *\n * @param name - Optional tracer name. Defaults to '@raccoon.ninja/otel-react/custom'.\n * @param version - Optional tracer version.\n * @returns An OTel Tracer instance.\n *\n * @example\n * ```tsx\n * function MyComponent() {\n * const tracer = useTracer();\n *\n * const handleClick = () => {\n * const span = tracer.startSpan('button-click');\n * // ... do work ...\n * span.end();\n * };\n * }\n * ```\n */\nexport function useTracer(name?: string, version?: string): Tracer {\n return useMemo(() => trace.getTracer(name ?? DEFAULT_TRACER_NAME, version), [name, version]);\n}\n","import { trace } from '@opentelemetry/api';\nimport type { OtelExtension, ExtensionContext } from '../core/options';\n\nconst TRACER_NAME = '@raccoon.ninja/otel-react/router';\n\n/**\n * Extension for React Router v6/v7 route-change tracing.\n *\n * Usage:\n * ```tsx\n * import { OtelProvider, withReactRouter } from '@raccoon.ninja/otel-react';\n *\n * <OtelProvider serviceName=\"my-app\" extensions={[withReactRouter()]}>\n * <App />\n * </OtelProvider>\n * ```\n *\n * Note: The actual hook-based integration should be used inside\n * a component that has access to React Router's context. This extension\n * registers the tracer scope for route-change spans.\n */\nexport function withReactRouter(): OtelExtension {\n return (_context: ExtensionContext) => {\n // Pre-register the tracer scope so route spans are properly attributed\n trace.getTracer(TRACER_NAME, '1.0.0');\n };\n}\n\n/** Tracer name for route-change spans, exported for use in hooks. */\nexport const ROUTER_TRACER_NAME = TRACER_NAME;\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/core/options.ts","../src/core/resource.ts","../src/providers/tracer.ts","../src/providers/logger.ts","../src/providers/meter.ts","../src/instrumentations/auto.ts","../src/instrumentations/web-vitals.ts","../src/core/shutdown.ts","../src/core/init.ts","../src/components/OtelProvider.tsx","../src/components/TracedErrorBoundary.tsx","../src/hooks/useTracer.ts","../src/instrumentations/router.ts"],"names":["ATTR_SERVICE_NAME","ATTR_SERVICE_VERSION","SEMRESATTRS_DEPLOYMENT_ENVIRONMENT","resourceFromAttributes","OTLPTraceExporter","WebTracerProvider","BatchSpanProcessor","OTLPLogExporter","LoggerProvider","BatchLogRecordProcessor","logs","OTLPMetricExporter","MeterProvider","PeriodicExportingMetricReader","metrics","FetchInstrumentation","XMLHttpRequestInstrumentation","DocumentLoadInstrumentation","UserInteractionInstrumentation","registerInstrumentations","SeverityNumber","useRef","useEffect","Component","trace","SpanStatusCode","useMemo","TRACER_NAME"],"mappings":"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","file":"index.cjs","sourcesContent":["import type { WebTracerProvider } from '@opentelemetry/sdk-trace-web';\nimport type { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';\n\n/** Configuration for enabling/disabling specific auto-instrumentations. */\nexport interface InstrumentationConfig {\n /** Auto-instrument fetch() calls. Default: true */\n fetch?: boolean;\n /** Auto-instrument XMLHttpRequest. Default: true */\n xhr?: boolean;\n /** Document load timing spans. Default: true */\n documentLoad?: boolean;\n /** Click/input interaction spans. Default: true */\n userInteraction?: boolean;\n /** LCP, CLS, INP, TTFB, FCP metrics. Default: true */\n webVitals?: boolean;\n}\n\n/** Extension function type for opt-in instrumentations (e.g., withReactRouter). */\nexport type OtelExtension = (context: ExtensionContext) => void;\n\n/** Context provided to extension functions during initialization. */\nexport interface ExtensionContext {\n tracerProvider: WebTracerProvider;\n}\n\n/** Configuration options for initOtel(). */\nexport interface OtelOptions {\n /** Required. Sets the service.name resource attribute. */\n serviceName: string;\n\n /** OTLP HTTP endpoint. Default: 'http://localhost:4318' */\n endpoint?: string;\n\n /** Additional OTel resource attributes. */\n resourceAttributes?: Record<string, string>;\n\n /** Service version. Sets service.version resource attribute. */\n serviceVersion?: string;\n\n /** Deployment environment. Sets deployment.environment resource attribute. */\n environment?: string;\n\n /** Enable/disable specific auto-instrumentations. All enabled by default. */\n instrumentations?: InstrumentationConfig;\n\n /** Escape hatch: configure the TracerProvider before it's registered. */\n configureTracing?: (provider: WebTracerProvider) => void;\n\n /** Escape hatch: configure the OTLP exporter. */\n configureExporter?: (exporter: OTLPTraceExporter) => void;\n\n /** Custom headers sent with OTLP export requests (e.g., auth tokens). */\n headers?: Record<string, string>;\n\n /** Export timeout in milliseconds. Default: 30000 */\n exportTimeout?: number;\n\n /**\n * URLs to exclude from fetch/XHR instrumentation.\n * Supports string patterns or RegExp.\n */\n ignoreUrls?: Array<string | RegExp>;\n\n /**\n * Cross-origin URLs that should receive W3C Trace Context headers\n * (traceparent / tracestate). Required when the frontend calls APIs\n * on a different origin and you want end-to-end distributed traces.\n *\n * @example\n * ```ts\n * propagateTraceHeaderCorsUrls: [/api\\.example\\.com/, 'https://my-backend.local']\n * ```\n */\n propagateTraceHeaderCorsUrls?: Array<string | RegExp>;\n\n /** Extension functions for opt-in instrumentations. */\n extensions?: OtelExtension[];\n}\n\n/** Handle returned from initOtel() for lifecycle management. */\nexport interface OtelHandle {\n /** Flush all pending telemetry and shut down providers. */\n shutdown: () => Promise<void>;\n}\n\nconst DEFAULT_ENDPOINT = 'http://localhost:4318';\nconst DEFAULT_EXPORT_TIMEOUT = 30000;\n\nexport function resolveEndpoint(options: OtelOptions): string {\n return options.endpoint ?? DEFAULT_ENDPOINT;\n}\n\nexport function resolveExportTimeout(options: OtelOptions): number {\n return options.exportTimeout ?? DEFAULT_EXPORT_TIMEOUT;\n}\n\nexport function resolveInstrumentations(options: OtelOptions): Required<InstrumentationConfig> {\n return {\n fetch: options.instrumentations?.fetch ?? true,\n xhr: options.instrumentations?.xhr ?? true,\n documentLoad: options.instrumentations?.documentLoad ?? true,\n userInteraction: options.instrumentations?.userInteraction ?? true,\n webVitals: options.instrumentations?.webVitals ?? true,\n };\n}\n\nexport function validateOptions(options: OtelOptions): void {\n if (!options.serviceName || typeof options.serviceName !== 'string') {\n throw new Error(\n '[@raccoon.ninja/otel-react] serviceName is required and must be a non-empty string.',\n );\n }\n\n if (options.serviceName.trim() !== options.serviceName) {\n throw new Error(\n '[@raccoon.ninja/otel-react] serviceName must not have leading or trailing whitespace.',\n );\n }\n\n if (options.endpoint !== undefined) {\n if (typeof options.endpoint !== 'string' || options.endpoint.trim() === '') {\n throw new Error(\n '[@raccoon.ninja/otel-react] endpoint must be a non-empty string when provided.',\n );\n }\n }\n\n if (options.exportTimeout !== undefined) {\n if (typeof options.exportTimeout !== 'number' || options.exportTimeout <= 0) {\n throw new Error(\n '[@raccoon.ninja/otel-react] exportTimeout must be a positive number when provided.',\n );\n }\n }\n}\n","import { resourceFromAttributes } from '@opentelemetry/resources';\nimport {\n ATTR_SERVICE_NAME,\n ATTR_SERVICE_VERSION,\n SEMRESATTRS_DEPLOYMENT_ENVIRONMENT,\n} from '@opentelemetry/semantic-conventions';\nimport type { OtelOptions } from './options';\n\nconst SDK_NAME = '@raccoon.ninja/otel-react';\nconst SDK_VERSION = '1.1.0';\n\nexport function buildResource(options: OtelOptions) {\n const attributes: Record<string, string> = {\n [ATTR_SERVICE_NAME]: options.serviceName,\n 'telemetry.sdk.name': SDK_NAME,\n 'telemetry.sdk.version': SDK_VERSION,\n 'telemetry.sdk.language': 'webjs',\n };\n\n if (options.serviceVersion) {\n attributes[ATTR_SERVICE_VERSION] = options.serviceVersion;\n }\n\n if (options.environment) {\n attributes[SEMRESATTRS_DEPLOYMENT_ENVIRONMENT] = options.environment;\n }\n\n if (typeof navigator !== 'undefined') {\n if (navigator.language) {\n attributes['browser.language'] = navigator.language;\n }\n if (navigator.userAgent) {\n attributes['browser.user_agent'] = navigator.userAgent;\n }\n if (navigator.platform) {\n attributes['browser.platform'] = navigator.platform;\n }\n }\n\n if (options.resourceAttributes) {\n Object.assign(attributes, options.resourceAttributes);\n }\n\n return resourceFromAttributes(attributes);\n}\n","import { WebTracerProvider } from '@opentelemetry/sdk-trace-web';\nimport { BatchSpanProcessor } from '@opentelemetry/sdk-trace-base';\nimport { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';\nimport type { Resource } from '@opentelemetry/resources';\nimport type { OtelOptions } from '@/core/options';\nimport { resolveEndpoint, resolveExportTimeout } from '@/core/options';\n\nexport interface TracerSetupResult {\n provider: WebTracerProvider;\n exporter: OTLPTraceExporter;\n}\n\nexport function createTracerProvider(options: OtelOptions, resource: Resource): TracerSetupResult {\n const endpoint = resolveEndpoint(options);\n const timeout = resolveExportTimeout(options);\n\n const exporter = new OTLPTraceExporter({\n url: `${endpoint}/v1/traces`,\n headers: options.headers,\n timeoutMillis: timeout,\n });\n\n options.configureExporter?.(exporter);\n\n const provider = new WebTracerProvider({\n resource,\n spanProcessors: [new BatchSpanProcessor(exporter)],\n });\n\n options.configureTracing?.(provider);\n\n provider.register();\n\n return { provider, exporter };\n}\n","import { LoggerProvider, BatchLogRecordProcessor } from '@opentelemetry/sdk-logs';\nimport { OTLPLogExporter } from '@opentelemetry/exporter-logs-otlp-http';\nimport { logs } from '@opentelemetry/api-logs';\nimport type { Resource } from '@opentelemetry/resources';\nimport type { OtelOptions } from '@/core/options';\nimport { resolveEndpoint, resolveExportTimeout } from '@/core/options';\n\nexport function createLoggerProvider(options: OtelOptions, resource: Resource): LoggerProvider {\n const endpoint = resolveEndpoint(options);\n const timeout = resolveExportTimeout(options);\n\n const exporter = new OTLPLogExporter({\n url: `${endpoint}/v1/logs`,\n headers: options.headers,\n timeoutMillis: timeout,\n });\n\n const provider = new LoggerProvider({\n resource,\n processors: [new BatchLogRecordProcessor(exporter)],\n });\n\n logs.setGlobalLoggerProvider(provider);\n\n return provider;\n}\n","import { MeterProvider, PeriodicExportingMetricReader } from '@opentelemetry/sdk-metrics';\nimport { OTLPMetricExporter } from '@opentelemetry/exporter-metrics-otlp-http';\nimport { metrics } from '@opentelemetry/api';\nimport type { Resource } from '@opentelemetry/resources';\nimport type { OtelOptions } from '../core/options';\nimport { resolveEndpoint, resolveExportTimeout } from '../core/options';\n\nconst METRIC_EXPORT_INTERVAL_MS = 30_000;\n\nexport function createMeterProvider(options: OtelOptions, resource: Resource): MeterProvider {\n const endpoint = resolveEndpoint(options);\n const timeout = resolveExportTimeout(options);\n\n const exporter = new OTLPMetricExporter({\n url: `${endpoint}/v1/metrics`,\n headers: options.headers,\n timeoutMillis: timeout,\n });\n\n const provider = new MeterProvider({\n resource,\n readers: [\n new PeriodicExportingMetricReader({\n exporter,\n exportIntervalMillis: METRIC_EXPORT_INTERVAL_MS,\n }),\n ],\n });\n\n metrics.setGlobalMeterProvider(provider);\n\n return provider;\n}\n","import { registerInstrumentations } from '@opentelemetry/instrumentation';\nimport { FetchInstrumentation } from '@opentelemetry/instrumentation-fetch';\nimport { XMLHttpRequestInstrumentation } from '@opentelemetry/instrumentation-xml-http-request';\nimport { DocumentLoadInstrumentation } from '@opentelemetry/instrumentation-document-load';\nimport { UserInteractionInstrumentation } from '@opentelemetry/instrumentation-user-interaction';\nimport type { InstrumentationConfig, OtelOptions } from '@/core/options';\nimport { resolveInstrumentations } from '@/core/options';\n\nexport function registerAutoInstrumentations(options: OtelOptions): void {\n const config: Required<InstrumentationConfig> = resolveInstrumentations(options);\n const ignoreUrls = options.ignoreUrls ?? [];\n\n const instrumentations = [];\n\n const propagateTraceHeaderCorsUrls = options.propagateTraceHeaderCorsUrls ?? [];\n\n if (config.fetch) {\n instrumentations.push(\n new FetchInstrumentation({\n ignoreUrls,\n propagateTraceHeaderCorsUrls,\n }),\n );\n }\n\n if (config.xhr) {\n instrumentations.push(\n new XMLHttpRequestInstrumentation({\n ignoreUrls,\n propagateTraceHeaderCorsUrls,\n }),\n );\n }\n\n if (config.documentLoad) {\n instrumentations.push(new DocumentLoadInstrumentation());\n }\n\n if (config.userInteraction) {\n instrumentations.push(new UserInteractionInstrumentation());\n }\n\n if (instrumentations.length > 0) {\n registerInstrumentations({ instrumentations });\n }\n}\n","import { metrics } from '@opentelemetry/api';\nimport type { Metric } from 'web-vitals';\n\nconst METER_NAME = '@raccoon.ninja/otel-react/web-vitals';\n\nexport function startWebVitalsCollection(): void {\n const meter = metrics.getMeter(METER_NAME, '1.1.0');\n\n const lcpHistogram = meter.createHistogram('web_vitals.lcp', {\n description: 'Largest Contentful Paint',\n unit: 'ms',\n });\n\n const clsHistogram = meter.createHistogram('web_vitals.cls', {\n description: 'Cumulative Layout Shift',\n unit: '',\n });\n\n const inpHistogram = meter.createHistogram('web_vitals.inp', {\n description: 'Interaction to Next Paint',\n unit: 'ms',\n });\n\n const ttfbHistogram = meter.createHistogram('web_vitals.ttfb', {\n description: 'Time to First Byte',\n unit: 'ms',\n });\n\n const fcpHistogram = meter.createHistogram('web_vitals.fcp', {\n description: 'First Contentful Paint',\n unit: 'ms',\n });\n\n const recordMetric = (histogram: ReturnType<typeof meter.createHistogram>) => {\n return (metric: Metric) => {\n const attrs: Record<string, string> = {\n 'web_vitals.rating': metric.rating,\n };\n\n if (typeof window !== 'undefined' && window.location) {\n attrs['page.url'] = window.location.pathname;\n }\n\n histogram.record(metric.value, attrs);\n };\n };\n\n // Dynamic import to enable tree-shaking when web-vitals is not used\n import('web-vitals').then(({ onLCP, onCLS, onINP, onTTFB, onFCP }) => {\n onLCP(recordMetric(lcpHistogram));\n onCLS(recordMetric(clsHistogram));\n onINP(recordMetric(inpHistogram));\n onTTFB(recordMetric(ttfbHistogram));\n onFCP(recordMetric(fcpHistogram));\n });\n}\n","import type { WebTracerProvider } from '@opentelemetry/sdk-trace-web';\nimport type { LoggerProvider } from '@opentelemetry/sdk-logs';\nimport type { MeterProvider } from '@opentelemetry/sdk-metrics';\n\nexport interface ShutdownTargets {\n tracerProvider: WebTracerProvider;\n loggerProvider: LoggerProvider;\n meterProvider: MeterProvider;\n}\n\nlet shutdownTargets: ShutdownTargets | null = null;\nlet visibilityHandler: (() => void) | null = null;\nlet beforeUnloadHandler: (() => void) | null = null;\n\nexport function registerShutdownTargets(targets: ShutdownTargets): void {\n shutdownTargets = targets;\n\n visibilityHandler = () => {\n if (document.visibilityState === 'hidden') {\n flushAll();\n }\n };\n\n beforeUnloadHandler = () => {\n flushAll();\n };\n\n if (typeof document !== 'undefined') {\n document.addEventListener('visibilitychange', visibilityHandler);\n }\n if (typeof window !== 'undefined') {\n window.addEventListener('beforeunload', beforeUnloadHandler);\n }\n}\n\nfunction flushAll(): void {\n if (!shutdownTargets) return;\n\n try {\n shutdownTargets.tracerProvider.forceFlush();\n shutdownTargets.loggerProvider.forceFlush();\n shutdownTargets.meterProvider.forceFlush();\n } catch {\n // Flush is best-effort during page unload\n }\n}\n\nexport async function shutdown(): Promise<void> {\n if (!shutdownTargets) return;\n\n if (typeof document !== 'undefined' && visibilityHandler) {\n document.removeEventListener('visibilitychange', visibilityHandler);\n }\n if (typeof window !== 'undefined' && beforeUnloadHandler) {\n window.removeEventListener('beforeunload', beforeUnloadHandler);\n }\n\n try {\n await Promise.all([\n shutdownTargets.tracerProvider.forceFlush(),\n shutdownTargets.loggerProvider.forceFlush(),\n shutdownTargets.meterProvider.forceFlush(),\n ]);\n\n await Promise.all([\n shutdownTargets.tracerProvider.shutdown(),\n shutdownTargets.loggerProvider.shutdown(),\n shutdownTargets.meterProvider.shutdown(),\n ]);\n } finally {\n shutdownTargets = null;\n visibilityHandler = null;\n beforeUnloadHandler = null;\n }\n}\n","import { SeverityNumber } from '@opentelemetry/api-logs';\nimport type { OtelOptions, OtelHandle } from './options';\nimport { validateOptions, resolveInstrumentations } from './options';\nimport { buildResource } from './resource';\nimport { createTracerProvider } from '../providers/tracer';\nimport { createLoggerProvider } from '../providers/logger';\nimport { createMeterProvider } from '../providers/meter';\nimport { registerAutoInstrumentations } from '../instrumentations/auto';\nimport { startWebVitalsCollection } from '../instrumentations/web-vitals';\nimport { registerShutdownTargets, shutdown } from './shutdown';\n\nlet initialized = false;\n\nexport function initOtel(options: OtelOptions): OtelHandle {\n if (initialized) {\n console.warn(\n '[@raccoon.ninja/otel-react] initOtel() has already been called. Skipping re-initialization.',\n );\n return { shutdown };\n }\n\n validateOptions(options);\n\n const resource = buildResource(options);\n const { provider: tracerProvider } = createTracerProvider(options, resource);\n const loggerProvider = createLoggerProvider(options, resource);\n const meterProvider = createMeterProvider(options, resource);\n\n registerAutoInstrumentations(options);\n\n const instrumentationConfig = resolveInstrumentations(options);\n if (instrumentationConfig.webVitals) {\n startWebVitalsCollection();\n }\n\n registerShutdownTargets({ tracerProvider, loggerProvider, meterProvider });\n\n // Run extensions\n if (options.extensions) {\n for (const ext of options.extensions) {\n ext({ tracerProvider });\n }\n }\n\n // Log initialization success\n const logger = loggerProvider.getLogger('@raccoon.ninja/otel-react', '1.1.0');\n logger.emit({\n severityNumber: SeverityNumber.INFO,\n severityText: 'INFO',\n body: `OpenTelemetry initialized for service \"${options.serviceName}\"`,\n attributes: {\n 'otel.service_name': options.serviceName,\n },\n });\n\n initialized = true;\n\n return {\n shutdown: async () => {\n await shutdown();\n initialized = false;\n },\n };\n}\n\n/** Reset initialization state (for testing). */\nexport function _resetInitState(): void {\n initialized = false;\n}\n","import { useEffect, useRef, type ReactNode } from 'react';\nimport { initOtel } from '../core/init';\nimport type { OtelOptions, OtelHandle, OtelExtension } from '../core/options';\n\n/** Props for the OtelProvider component. */\nexport interface OtelProviderProps {\n /** Required. Sets the service.name resource attribute. */\n serviceName: string;\n /** OTLP HTTP endpoint. Default: 'http://localhost:4318' */\n endpoint?: string;\n /** Additional OTel resource attributes. */\n resourceAttributes?: Record<string, string>;\n /** Service version. */\n serviceVersion?: string;\n /** Deployment environment. */\n environment?: string;\n /** Enable/disable specific auto-instrumentations. */\n instrumentations?: OtelOptions['instrumentations'];\n /** Custom headers sent with OTLP export requests. */\n headers?: Record<string, string>;\n /** Export timeout in milliseconds. */\n exportTimeout?: number;\n /** URLs to exclude from fetch/XHR instrumentation. */\n ignoreUrls?: Array<string | RegExp>;\n /** Cross-origin URLs that should receive W3C Trace Context headers. */\n propagateTraceHeaderCorsUrls?: Array<string | RegExp>;\n /** Escape hatch: configure the TracerProvider. */\n configureTracing?: OtelOptions['configureTracing'];\n /** Escape hatch: configure the OTLP exporter. */\n configureExporter?: OtelOptions['configureExporter'];\n /** Extension functions for opt-in instrumentations. */\n extensions?: OtelExtension[];\n /** React children to render. */\n children: ReactNode;\n}\n\n/**\n * React Provider component that initializes OpenTelemetry on mount\n * and flushes/shuts down on unmount.\n *\n * @example\n * ```tsx\n * import { OtelProvider } from '@raccoon.ninja/otel-react';\n *\n * function App() {\n * return (\n * <OtelProvider serviceName=\"my-app\">\n * <RestOfTheApp />\n * </OtelProvider>\n * );\n * }\n * ```\n */\nexport function OtelProvider({\n children,\n serviceName,\n endpoint,\n resourceAttributes,\n serviceVersion,\n environment,\n instrumentations,\n headers,\n exportTimeout,\n ignoreUrls,\n propagateTraceHeaderCorsUrls,\n configureTracing,\n configureExporter,\n extensions,\n}: OtelProviderProps) {\n const handleRef = useRef<OtelHandle | null>(null);\n\n useEffect(() => {\n const handle = initOtel({\n serviceName,\n endpoint,\n resourceAttributes,\n serviceVersion,\n environment,\n instrumentations,\n headers,\n exportTimeout,\n ignoreUrls,\n propagateTraceHeaderCorsUrls,\n configureTracing,\n configureExporter,\n extensions,\n });\n\n handleRef.current = handle;\n\n return () => {\n handleRef.current?.shutdown();\n handleRef.current = null;\n };\n // We intentionally only run this on mount/unmount.\n // Config changes require remounting the provider.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n return <>{children}</>;\n}\n","import { Component, type ReactNode, type ErrorInfo } from 'react';\nimport { trace, SpanStatusCode } from '@opentelemetry/api';\nimport { SeverityNumber } from '@opentelemetry/api-logs';\nimport { logs } from '@opentelemetry/api-logs';\n\nconst TRACER_NAME = '@raccoon.ninja/otel-react/error-boundary';\nconst LOGGER_NAME = '@raccoon.ninja/otel-react/error-boundary';\n\n/** Props for the TracedErrorBoundary component. */\nexport interface TracedErrorBoundaryProps {\n /** Fallback UI to render when an error is caught. */\n fallback: ReactNode | ((error: Error, reset: () => void) => ReactNode);\n /** Optional callback when an error is caught. */\n onError?: (error: Error, errorInfo: ErrorInfo) => void;\n /** Children to render. */\n children: ReactNode;\n}\n\ninterface TracedErrorBoundaryState {\n hasError: boolean;\n error: Error | null;\n}\n\n/**\n * Error boundary that records caught errors as OpenTelemetry spans and logs.\n *\n * @example\n * ```tsx\n * import { TracedErrorBoundary } from '@raccoon.ninja/otel-react';\n *\n * <TracedErrorBoundary fallback={<ErrorPage />}>\n * <RiskyComponent />\n * </TracedErrorBoundary>\n * ```\n */\nexport class TracedErrorBoundary extends Component<\n TracedErrorBoundaryProps,\n TracedErrorBoundaryState\n> {\n constructor(props: TracedErrorBoundaryProps) {\n super(props);\n this.state = { hasError: false, error: null };\n }\n\n static getDerivedStateFromError(error: Error): TracedErrorBoundaryState {\n return { hasError: true, error };\n }\n\n componentDidCatch(error: Error, errorInfo: ErrorInfo): void {\n const tracer = trace.getTracer(TRACER_NAME, '1.1.0');\n const span = tracer.startSpan('error-boundary.catch');\n\n span.setStatus({ code: SpanStatusCode.ERROR, message: error.message });\n span.setAttribute('error.type', error.name);\n span.setAttribute('error.message', error.message);\n\n if (error.stack) {\n span.setAttribute('error.stack', error.stack);\n }\n if (errorInfo.componentStack) {\n span.setAttribute('error.component_stack', errorInfo.componentStack);\n }\n\n span.recordException(error);\n span.end();\n\n // Also emit as a log record\n try {\n const logger = logs.getLogger(LOGGER_NAME, '1.1.0');\n logger.emit({\n severityNumber: SeverityNumber.ERROR,\n severityText: 'ERROR',\n body: `Unhandled error: ${error.message}`,\n attributes: {\n 'error.type': error.name,\n 'error.message': error.message,\n ...(error.stack ? { 'error.stack': error.stack } : {}),\n ...(errorInfo.componentStack\n ? { 'error.component_stack': errorInfo.componentStack }\n : {}),\n },\n });\n } catch {\n // Logging is best-effort\n }\n\n this.props.onError?.(error, errorInfo);\n }\n\n private reset = () => {\n this.setState({ hasError: false, error: null });\n };\n\n render() {\n if (this.state.hasError && this.state.error) {\n const { fallback } = this.props;\n if (typeof fallback === 'function') {\n return fallback(this.state.error, this.reset);\n }\n return fallback;\n }\n\n return this.props.children;\n }\n}\n","import { useMemo } from 'react';\nimport { trace, type Tracer } from '@opentelemetry/api';\n\nconst DEFAULT_TRACER_NAME = '@raccoon.ninja/otel-react/custom';\n\n/**\n * Hook to get an OpenTelemetry Tracer for creating custom spans.\n *\n * @param name - Optional tracer name. Defaults to '@raccoon.ninja/otel-react/custom'.\n * @param version - Optional tracer version.\n * @returns An OTel Tracer instance.\n *\n * @example\n * ```tsx\n * function MyComponent() {\n * const tracer = useTracer();\n *\n * const handleClick = () => {\n * const span = tracer.startSpan('button-click');\n * // ... do work ...\n * span.end();\n * };\n * }\n * ```\n */\nexport function useTracer(name?: string, version?: string): Tracer {\n return useMemo(() => trace.getTracer(name ?? DEFAULT_TRACER_NAME, version), [name, version]);\n}\n","import { trace } from '@opentelemetry/api';\nimport type { OtelExtension, ExtensionContext } from '../core/options';\n\nconst TRACER_NAME = '@raccoon.ninja/otel-react/router';\n\n/**\n * Extension for React Router v6/v7 route-change tracing.\n *\n * Usage:\n * ```tsx\n * import { OtelProvider, withReactRouter } from '@raccoon.ninja/otel-react';\n *\n * <OtelProvider serviceName=\"my-app\" extensions={[withReactRouter()]}>\n * <App />\n * </OtelProvider>\n * ```\n *\n * Note: The actual hook-based integration should be used inside\n * a component that has access to React Router's context. This extension\n * registers the tracer scope for route-change spans.\n */\nexport function withReactRouter(): OtelExtension {\n return (_context: ExtensionContext) => {\n // Pre-register the tracer scope so route spans are properly attributed\n trace.getTracer(TRACER_NAME, '1.1.0');\n };\n}\n\n/** Tracer name for route-change spans, exported for use in hooks. */\nexport const ROUTER_TRACER_NAME = TRACER_NAME;\n"]}
|
package/dist/index.d.mts
CHANGED
|
@@ -50,6 +50,17 @@ interface OtelOptions {
|
|
|
50
50
|
* Supports string patterns or RegExp.
|
|
51
51
|
*/
|
|
52
52
|
ignoreUrls?: Array<string | RegExp>;
|
|
53
|
+
/**
|
|
54
|
+
* Cross-origin URLs that should receive W3C Trace Context headers
|
|
55
|
+
* (traceparent / tracestate). Required when the frontend calls APIs
|
|
56
|
+
* on a different origin and you want end-to-end distributed traces.
|
|
57
|
+
*
|
|
58
|
+
* @example
|
|
59
|
+
* ```ts
|
|
60
|
+
* propagateTraceHeaderCorsUrls: [/api\.example\.com/, 'https://my-backend.local']
|
|
61
|
+
* ```
|
|
62
|
+
*/
|
|
63
|
+
propagateTraceHeaderCorsUrls?: Array<string | RegExp>;
|
|
53
64
|
/** Extension functions for opt-in instrumentations. */
|
|
54
65
|
extensions?: OtelExtension[];
|
|
55
66
|
}
|
|
@@ -81,6 +92,8 @@ interface OtelProviderProps {
|
|
|
81
92
|
exportTimeout?: number;
|
|
82
93
|
/** URLs to exclude from fetch/XHR instrumentation. */
|
|
83
94
|
ignoreUrls?: Array<string | RegExp>;
|
|
95
|
+
/** Cross-origin URLs that should receive W3C Trace Context headers. */
|
|
96
|
+
propagateTraceHeaderCorsUrls?: Array<string | RegExp>;
|
|
84
97
|
/** Escape hatch: configure the TracerProvider. */
|
|
85
98
|
configureTracing?: OtelOptions['configureTracing'];
|
|
86
99
|
/** Escape hatch: configure the OTLP exporter. */
|
|
@@ -107,7 +120,7 @@ interface OtelProviderProps {
|
|
|
107
120
|
* }
|
|
108
121
|
* ```
|
|
109
122
|
*/
|
|
110
|
-
declare function OtelProvider({ children, serviceName, endpoint, resourceAttributes, serviceVersion, environment, instrumentations, headers, exportTimeout, ignoreUrls, configureTracing, configureExporter, extensions, }: OtelProviderProps): react_jsx_runtime.JSX.Element;
|
|
123
|
+
declare function OtelProvider({ children, serviceName, endpoint, resourceAttributes, serviceVersion, environment, instrumentations, headers, exportTimeout, ignoreUrls, propagateTraceHeaderCorsUrls, configureTracing, configureExporter, extensions, }: OtelProviderProps): react_jsx_runtime.JSX.Element;
|
|
111
124
|
|
|
112
125
|
/** Props for the TracedErrorBoundary component. */
|
|
113
126
|
interface TracedErrorBoundaryProps {
|
package/dist/index.d.ts
CHANGED
|
@@ -50,6 +50,17 @@ interface OtelOptions {
|
|
|
50
50
|
* Supports string patterns or RegExp.
|
|
51
51
|
*/
|
|
52
52
|
ignoreUrls?: Array<string | RegExp>;
|
|
53
|
+
/**
|
|
54
|
+
* Cross-origin URLs that should receive W3C Trace Context headers
|
|
55
|
+
* (traceparent / tracestate). Required when the frontend calls APIs
|
|
56
|
+
* on a different origin and you want end-to-end distributed traces.
|
|
57
|
+
*
|
|
58
|
+
* @example
|
|
59
|
+
* ```ts
|
|
60
|
+
* propagateTraceHeaderCorsUrls: [/api\.example\.com/, 'https://my-backend.local']
|
|
61
|
+
* ```
|
|
62
|
+
*/
|
|
63
|
+
propagateTraceHeaderCorsUrls?: Array<string | RegExp>;
|
|
53
64
|
/** Extension functions for opt-in instrumentations. */
|
|
54
65
|
extensions?: OtelExtension[];
|
|
55
66
|
}
|
|
@@ -81,6 +92,8 @@ interface OtelProviderProps {
|
|
|
81
92
|
exportTimeout?: number;
|
|
82
93
|
/** URLs to exclude from fetch/XHR instrumentation. */
|
|
83
94
|
ignoreUrls?: Array<string | RegExp>;
|
|
95
|
+
/** Cross-origin URLs that should receive W3C Trace Context headers. */
|
|
96
|
+
propagateTraceHeaderCorsUrls?: Array<string | RegExp>;
|
|
84
97
|
/** Escape hatch: configure the TracerProvider. */
|
|
85
98
|
configureTracing?: OtelOptions['configureTracing'];
|
|
86
99
|
/** Escape hatch: configure the OTLP exporter. */
|
|
@@ -107,7 +120,7 @@ interface OtelProviderProps {
|
|
|
107
120
|
* }
|
|
108
121
|
* ```
|
|
109
122
|
*/
|
|
110
|
-
declare function OtelProvider({ children, serviceName, endpoint, resourceAttributes, serviceVersion, environment, instrumentations, headers, exportTimeout, ignoreUrls, configureTracing, configureExporter, extensions, }: OtelProviderProps): react_jsx_runtime.JSX.Element;
|
|
123
|
+
declare function OtelProvider({ children, serviceName, endpoint, resourceAttributes, serviceVersion, environment, instrumentations, headers, exportTimeout, ignoreUrls, propagateTraceHeaderCorsUrls, configureTracing, configureExporter, extensions, }: OtelProviderProps): react_jsx_runtime.JSX.Element;
|
|
111
124
|
|
|
112
125
|
/** Props for the TracedErrorBoundary component. */
|
|
113
126
|
interface TracedErrorBoundaryProps {
|
package/dist/index.mjs
CHANGED
|
@@ -64,7 +64,7 @@ function validateOptions(options) {
|
|
|
64
64
|
}
|
|
65
65
|
}
|
|
66
66
|
var SDK_NAME = "@raccoon.ninja/otel-react";
|
|
67
|
-
var SDK_VERSION = "1.
|
|
67
|
+
var SDK_VERSION = "1.1.0";
|
|
68
68
|
function buildResource(options) {
|
|
69
69
|
const attributes = {
|
|
70
70
|
[ATTR_SERVICE_NAME]: options.serviceName,
|
|
@@ -119,8 +119,10 @@ function createLoggerProvider(options, resource) {
|
|
|
119
119
|
headers: options.headers,
|
|
120
120
|
timeoutMillis: timeout
|
|
121
121
|
});
|
|
122
|
-
const provider = new LoggerProvider({
|
|
123
|
-
|
|
122
|
+
const provider = new LoggerProvider({
|
|
123
|
+
resource,
|
|
124
|
+
processors: [new BatchLogRecordProcessor(exporter)]
|
|
125
|
+
});
|
|
124
126
|
logs.setGlobalLoggerProvider(provider);
|
|
125
127
|
return provider;
|
|
126
128
|
}
|
|
@@ -149,17 +151,20 @@ function registerAutoInstrumentations(options) {
|
|
|
149
151
|
const config = resolveInstrumentations(options);
|
|
150
152
|
const ignoreUrls = options.ignoreUrls ?? [];
|
|
151
153
|
const instrumentations = [];
|
|
154
|
+
const propagateTraceHeaderCorsUrls = options.propagateTraceHeaderCorsUrls ?? [];
|
|
152
155
|
if (config.fetch) {
|
|
153
156
|
instrumentations.push(
|
|
154
157
|
new FetchInstrumentation({
|
|
155
|
-
ignoreUrls
|
|
158
|
+
ignoreUrls,
|
|
159
|
+
propagateTraceHeaderCorsUrls
|
|
156
160
|
})
|
|
157
161
|
);
|
|
158
162
|
}
|
|
159
163
|
if (config.xhr) {
|
|
160
164
|
instrumentations.push(
|
|
161
165
|
new XMLHttpRequestInstrumentation({
|
|
162
|
-
ignoreUrls
|
|
166
|
+
ignoreUrls,
|
|
167
|
+
propagateTraceHeaderCorsUrls
|
|
163
168
|
})
|
|
164
169
|
);
|
|
165
170
|
}
|
|
@@ -175,7 +180,7 @@ function registerAutoInstrumentations(options) {
|
|
|
175
180
|
}
|
|
176
181
|
var METER_NAME = "@raccoon.ninja/otel-react/web-vitals";
|
|
177
182
|
function startWebVitalsCollection() {
|
|
178
|
-
const meter = metrics.getMeter(METER_NAME, "1.
|
|
183
|
+
const meter = metrics.getMeter(METER_NAME, "1.1.0");
|
|
179
184
|
const lcpHistogram = meter.createHistogram("web_vitals.lcp", {
|
|
180
185
|
description: "Largest Contentful Paint",
|
|
181
186
|
unit: "ms"
|
|
@@ -297,7 +302,7 @@ function initOtel(options) {
|
|
|
297
302
|
ext({ tracerProvider });
|
|
298
303
|
}
|
|
299
304
|
}
|
|
300
|
-
const logger = loggerProvider.getLogger("@raccoon.ninja/otel-react", "1.
|
|
305
|
+
const logger = loggerProvider.getLogger("@raccoon.ninja/otel-react", "1.1.0");
|
|
301
306
|
logger.emit({
|
|
302
307
|
severityNumber: SeverityNumber.INFO,
|
|
303
308
|
severityText: "INFO",
|
|
@@ -325,6 +330,7 @@ function OtelProvider({
|
|
|
325
330
|
headers,
|
|
326
331
|
exportTimeout,
|
|
327
332
|
ignoreUrls,
|
|
333
|
+
propagateTraceHeaderCorsUrls,
|
|
328
334
|
configureTracing,
|
|
329
335
|
configureExporter,
|
|
330
336
|
extensions
|
|
@@ -341,6 +347,7 @@ function OtelProvider({
|
|
|
341
347
|
headers,
|
|
342
348
|
exportTimeout,
|
|
343
349
|
ignoreUrls,
|
|
350
|
+
propagateTraceHeaderCorsUrls,
|
|
344
351
|
configureTracing,
|
|
345
352
|
configureExporter,
|
|
346
353
|
extensions
|
|
@@ -364,7 +371,7 @@ var TracedErrorBoundary = class extends Component {
|
|
|
364
371
|
return { hasError: true, error };
|
|
365
372
|
}
|
|
366
373
|
componentDidCatch(error, errorInfo) {
|
|
367
|
-
const tracer = trace.getTracer(TRACER_NAME, "1.
|
|
374
|
+
const tracer = trace.getTracer(TRACER_NAME, "1.1.0");
|
|
368
375
|
const span = tracer.startSpan("error-boundary.catch");
|
|
369
376
|
span.setStatus({ code: SpanStatusCode.ERROR, message: error.message });
|
|
370
377
|
span.setAttribute("error.type", error.name);
|
|
@@ -378,7 +385,7 @@ var TracedErrorBoundary = class extends Component {
|
|
|
378
385
|
span.recordException(error);
|
|
379
386
|
span.end();
|
|
380
387
|
try {
|
|
381
|
-
const logger = logs.getLogger(LOGGER_NAME, "1.
|
|
388
|
+
const logger = logs.getLogger(LOGGER_NAME, "1.1.0");
|
|
382
389
|
logger.emit({
|
|
383
390
|
severityNumber: SeverityNumber.ERROR,
|
|
384
391
|
severityText: "ERROR",
|
|
@@ -415,7 +422,7 @@ function useTracer(name, version) {
|
|
|
415
422
|
var TRACER_NAME2 = "@raccoon.ninja/otel-react/router";
|
|
416
423
|
function withReactRouter() {
|
|
417
424
|
return (_context) => {
|
|
418
|
-
trace.getTracer(TRACER_NAME2, "1.
|
|
425
|
+
trace.getTracer(TRACER_NAME2, "1.1.0");
|
|
419
426
|
};
|
|
420
427
|
}
|
|
421
428
|
|