|
1 |
| -import { MeterProvider, MetricReader, PeriodicExportingMetricReader } from '@opentelemetry/sdk-metrics'; |
2 |
| -import { PrometheusExporter } from '@opentelemetry/exporter-prometheus'; |
3 | 1 | import { OTLPMetricExporter } from '@opentelemetry/exporter-metrics-otlp-http';
|
4 |
| -import { Resource } from '@opentelemetry/resources'; |
| 2 | +import { PrometheusExporter } from '@opentelemetry/exporter-prometheus'; |
| 3 | +import { MeterProvider, MetricReader, PeriodicExportingMetricReader } from '@opentelemetry/sdk-metrics'; |
| 4 | +import { logger } from '@powersync/lib-services-framework'; |
5 | 5 | import { ServiceContext } from '../../system/ServiceContext.js';
|
6 |
| -import { OpenTelemetryMetricsFactory } from './OpenTelemetryMetricsFactory.js'; |
7 | 6 | import { MetricsFactory } from '../metrics-interfaces.js';
|
8 |
| -import { logger } from '@powersync/lib-services-framework'; |
| 7 | +import { OpenTelemetryMetricsFactory } from './OpenTelemetryMetricsFactory.js'; |
9 | 8 |
|
10 | 9 | import pkg from '../../../package.json' with { type: 'json' };
|
11 |
| - |
12 |
| -export interface RuntimeMetadata { |
13 |
| - [key: string]: string | number | undefined; |
14 |
| -} |
| 10 | +import { resourceFromAttributes } from '@opentelemetry/resources'; |
15 | 11 |
|
16 | 12 | export function createOpenTelemetryMetricsFactory(context: ServiceContext): MetricsFactory {
|
17 | 13 | const { configuration, lifeCycleEngine, storageEngine } = context;
|
@@ -43,31 +39,36 @@ export function createOpenTelemetryMetricsFactory(context: ServiceContext): Metr
|
43 | 39 | configuredExporters.push(periodicExporter);
|
44 | 40 | }
|
45 | 41 |
|
46 |
| - let resolvedMetadata: (metadata: RuntimeMetadata) => void; |
47 |
| - const runtimeMetadata: Promise<RuntimeMetadata> = new Promise((resolve) => { |
48 |
| - resolvedMetadata = resolve; |
| 42 | + let resolvedInstanceId: (id: string) => void; |
| 43 | + const instanceIdPromise = new Promise<string>((resolve) => { |
| 44 | + resolvedInstanceId = resolve; |
49 | 45 | });
|
50 | 46 |
|
51 | 47 | lifeCycleEngine.withLifecycle(null, {
|
52 | 48 | start: async () => {
|
53 | 49 | const bucketStorage = storageEngine.activeBucketStorage;
|
54 | 50 | try {
|
55 | 51 | const instanceId = await bucketStorage.getPowerSyncInstanceId();
|
56 |
| - resolvedMetadata({ ['instance_id']: instanceId }); |
| 52 | + resolvedInstanceId(instanceId); |
57 | 53 | } catch (err) {
|
58 |
| - resolvedMetadata({ ['instance_id']: 'Unknown' }); |
| 54 | + resolvedInstanceId('Unknown'); |
59 | 55 | }
|
60 | 56 | }
|
61 | 57 | });
|
62 | 58 |
|
| 59 | + const resource = resourceFromAttributes({ |
| 60 | + ['service']: 'PowerSync', |
| 61 | + ['service.version']: pkg.version, |
| 62 | + ['instance_id']: instanceIdPromise |
| 63 | + }); |
| 64 | + |
| 65 | + // This triggers OpenTelemetry to resolve the async attributes (instanceIdPromise). |
| 66 | + // This will never reject, and we don't specifically need to wait for it. |
| 67 | + resource.waitForAsyncAttributes?.(); |
| 68 | + |
63 | 69 | const meterProvider = new MeterProvider({
|
64 |
| - resource: new Resource( |
65 |
| - { |
66 |
| - ['service']: 'PowerSync', |
67 |
| - ['service.version']: pkg.version |
68 |
| - }, |
69 |
| - runtimeMetadata |
70 |
| - ), |
| 70 | + resource, |
| 71 | + |
71 | 72 | readers: configuredExporters
|
72 | 73 | });
|
73 | 74 |
|
|
0 commit comments