diff --git a/.changeset/dull-bananas-reflect.md b/.changeset/dull-bananas-reflect.md new file mode 100644 index 0000000..7a7cc41 --- /dev/null +++ b/.changeset/dull-bananas-reflect.md @@ -0,0 +1,7 @@ +--- +'@powersync/service-core': minor +'@powersync/service-types': minor +'@powersync/service-image': minor +--- + +Added the ability to specify additional metrics export endpoints. diff --git a/packages/service-core/src/metrics/Metrics.ts b/packages/service-core/src/metrics/Metrics.ts index 2ec7591..ccba160 100644 --- a/packages/service-core/src/metrics/Metrics.ts +++ b/packages/service-core/src/metrics/Metrics.ts @@ -8,11 +8,13 @@ import * as storage from '../storage/storage-index.js'; import { CorePowerSyncSystem } from '../system/CorePowerSyncSystem.js'; import { Resource } from '@opentelemetry/resources'; import { logger } from '@powersync/lib-services-framework'; +import { configFile } from '@powersync/service-types'; export interface MetricsOptions { disable_telemetry_sharing: boolean; powersync_instance_id: string; internal_metrics_endpoint: string; + additional_endpoints?: configFile.AdditionalMetricsEndpoint[]; } export class Metrics { @@ -175,6 +177,19 @@ Anonymous telemetry is currently: ${options.disable_telemetry_sharing ? 'disable configuredExporters.push(periodicExporter); } + // Create extra exporters for any additionally configured metric endpoints + for (const endpoint of options.additional_endpoints ?? []) { + logger.info(`Exporting metrics to endpoint: ${endpoint}`); + const additionalEndpointExporter = new PeriodicExportingMetricReader({ + exporter: new OTLPMetricExporter({ + url: endpoint.url + }), + exportIntervalMillis: endpoint.export_interval_ms ?? 1000 * 60 * 5 // 5 Minutes + }); + + configuredExporters.push(additionalEndpointExporter); + } + const meterProvider = new MeterProvider({ resource: new Resource({ ['service']: 'PowerSync', diff --git a/packages/service-core/src/util/config/compound-config-collector.ts b/packages/service-core/src/util/config/compound-config-collector.ts index 3ae8566..74b531f 100644 --- a/packages/service-core/src/util/config/compound-config-collector.ts +++ b/packages/service-core/src/util/config/compound-config-collector.ts @@ -122,7 +122,8 @@ export class CompoundConfigCollector { telemetry: { disable_telemetry_sharing: baseConfig.telemetry?.disable_telemetry_sharing ?? false, internal_service_endpoint: - baseConfig.telemetry?.internal_service_endpoint ?? 'https://pulse.journeyapps.com/v1/metrics' + baseConfig.telemetry?.internal_service_endpoint ?? 'https://pulse.journeyapps.com/v1/metrics', + additional_endpoints: baseConfig?.telemetry?.additional_endpoints }, slot_name_prefix: connections[0]?.slot_name_prefix ?? 'powersync_' }; diff --git a/packages/service-core/src/util/config/types.ts b/packages/service-core/src/util/config/types.ts index 94a09ba..0392a33 100644 --- a/packages/service-core/src/util/config/types.ts +++ b/packages/service-core/src/util/config/types.ts @@ -59,6 +59,7 @@ export type ResolvedPowerSyncConfig = { telemetry: { disable_telemetry_sharing: boolean; internal_service_endpoint: string; + additional_endpoints?: configFile.AdditionalMetricsEndpoint[]; }; /** Prefix for postgres replication slot names. May eventually be connection-specific. */ diff --git a/packages/types/src/config/PowerSyncConfig.ts b/packages/types/src/config/PowerSyncConfig.ts index a0bf765..ea2be1c 100644 --- a/packages/types/src/config/PowerSyncConfig.ts +++ b/packages/types/src/config/PowerSyncConfig.ts @@ -92,6 +92,16 @@ export const storageConfig = t.object({ export type StorageConfig = t.Decoded; +/** + * An additional OTLP metrics endpoint + */ +export const AdditionalMetricsEndpoint = t.object({ + url: t.string, + export_interval_ms: t.number.optional() +}); + +export type AdditionalMetricsEndpoint = t.Decoded; + export const powerSyncConfig = t.object({ replication: t .object({ @@ -145,7 +155,8 @@ export const powerSyncConfig = t.object({ telemetry: t .object({ disable_telemetry_sharing: t.boolean, - internal_service_endpoint: t.string.optional() + internal_service_endpoint: t.string.optional(), + additional_endpoints: t.array(AdditionalMetricsEndpoint).optional() }) .optional() }); diff --git a/service/src/system/PowerSyncSystem.ts b/service/src/system/PowerSyncSystem.ts index 93024dc..d8d904c 100644 --- a/service/src/system/PowerSyncSystem.ts +++ b/service/src/system/PowerSyncSystem.ts @@ -44,7 +44,8 @@ export class PowerSyncSystem extends system.CorePowerSyncSystem { await Metrics.initialise({ powersync_instance_id: instanceId, disable_telemetry_sharing: config.telemetry.disable_telemetry_sharing, - internal_metrics_endpoint: config.telemetry.internal_service_endpoint + internal_metrics_endpoint: config.telemetry.internal_service_endpoint, + additional_endpoints: config.telemetry.additional_endpoints }); }, async stop() {