Skip to content

Commit 6a16c3d

Browse files
committed
Added basic metrics interfaces, a metrics factory and an implementation of those interfaces for Opentelemetry
Added a MetricsEngine that handles creation and registration of metrics
1 parent f11079f commit 6a16c3d

File tree

7 files changed

+283
-269
lines changed

7 files changed

+283
-269
lines changed

packages/service-core-tests/src/test-utils/metrics-utils.ts

Lines changed: 0 additions & 14 deletions
This file was deleted.

packages/service-core/src/metrics/Metrics.ts

Lines changed: 0 additions & 255 deletions
This file was deleted.
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
import { logger, ServiceAssertionError } from '@powersync/lib-services-framework';
2+
import { Counter, UpDownCounter, ObservableGauge, MetricMetadata, MetricsFactory } from './metrics-interfaces.js';
3+
4+
export interface MetricsEngineOptions {
5+
factory: MetricsFactory;
6+
disable_telemetry_sharing: boolean;
7+
}
8+
9+
export class MetricsEngine {
10+
private counters: Map<string, Counter>;
11+
private upDownCounters: Map<string, UpDownCounter>;
12+
private observableGauges: Map<string, ObservableGauge>;
13+
14+
constructor(private options: MetricsEngineOptions) {
15+
this.counters = new Map();
16+
this.upDownCounters = new Map();
17+
this.observableGauges = new Map();
18+
}
19+
20+
private get factory(): MetricsFactory {
21+
return this.options.factory;
22+
}
23+
24+
createCounter(metadata: MetricMetadata): Counter {
25+
if (this.counters.has(metadata.name)) {
26+
logger.warn(`Counter with name ${metadata.name} already created and registered, skipping.`);
27+
return this.counters.get(metadata.name)!;
28+
}
29+
30+
const counter = this.factory.createCounter(metadata);
31+
this.counters.set(metadata.name, counter);
32+
return counter;
33+
}
34+
createUpDownCounter(metadata: MetricMetadata): UpDownCounter {
35+
if (this.upDownCounters.has(metadata.name)) {
36+
logger.warn(`UpDownCounter with name ${metadata.name} already created and registered, skipping.`);
37+
return this.upDownCounters.get(metadata.name)!;
38+
}
39+
40+
const upDownCounter = this.factory.createUpDownCounter(metadata);
41+
this.upDownCounters.set(metadata.name, upDownCounter);
42+
return upDownCounter;
43+
}
44+
45+
createObservableGauge(metadata: MetricMetadata): ObservableGauge {
46+
if (this.observableGauges.has(metadata.name)) {
47+
logger.warn(`ObservableGauge with name ${metadata.name} already created and registered, skipping.`);
48+
return this.observableGauges.get(metadata.name)!;
49+
}
50+
51+
const observableGauge = this.factory.createObservableGauge(metadata);
52+
this.observableGauges.set(metadata.name, observableGauge);
53+
return observableGauge;
54+
}
55+
56+
getCounter(name: string): Counter {
57+
const counter = this.counters.get(name);
58+
if (!counter) {
59+
throw new ServiceAssertionError(`Counter '${name}' has not been created and registered yet.`);
60+
}
61+
return counter;
62+
}
63+
64+
getUpDownCounter(name: string): UpDownCounter {
65+
const upDownCounter = this.upDownCounters.get(name);
66+
if (!upDownCounter) {
67+
throw new ServiceAssertionError(`UpDownCounter '${name}' has not been created and registered yet.`);
68+
}
69+
return upDownCounter;
70+
}
71+
72+
getObservableGauge(name: string): ObservableGauge {
73+
const observableGauge = this.observableGauges.get(name);
74+
if (!observableGauge) {
75+
throw new ServiceAssertionError(`ObservableGauge '${name}' has not been created and registered yet.`);
76+
}
77+
return observableGauge;
78+
}
79+
80+
public async start(): Promise<void> {
81+
logger.info(
82+
`
83+
Attention:
84+
PowerSync collects completely anonymous telemetry regarding usage.
85+
This information is used to shape our roadmap to better serve our customers.
86+
You can learn more, including how to opt-out if you'd not like to participate in this anonymous program, by visiting the following URL:
87+
https://docs.powersync.com/self-hosting/lifecycle-maintenance/telemetry
88+
`.trim()
89+
);
90+
logger.info(`Anonymous telemetry is currently: ${this.options.disable_telemetry_sharing ? 'disabled' : 'enabled'}`);
91+
92+
logger.info('Successfully started Metrics Engine.');
93+
}
94+
95+
public async shutdown(): Promise<void> {
96+
logger.info('Successfully shut down Metrics Engine.');
97+
}
98+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
export * from './MetricsEngine.js';
2+
export * from './metrics-interfaces.js';
3+
export * from './open-telemetry/OpenTelemetryMetricsFactory.js';
4+
export * from './open-telemetry/util.js';

0 commit comments

Comments
 (0)