@cratis/chronicle 6.32.1 → 6.34.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/ChronicleClient.ts +35 -33
- package/ChronicleOptions.ts +27 -1
- package/EventStore.ts +14 -12
- package/Metrics.ts +70 -96
- package/Tracing.ts +4 -2
- package/WellKnownTelemetryNames.ts +67 -0
- package/artifacts/validateArtifactSchemas.spec.ts +1 -1
- package/artifacts/withActivatedArtifact.ts +7 -5
- package/connection/ChronicleConnection.ts +18 -6
- package/connection/CompatibilityPreflight.ts +2 -1
- package/connection/KernelKeepAlive.ts +13 -7
- package/connection/TokenProvider.ts +3 -1
- package/connection/TraceContextMiddleware.ts +30 -0
- package/connection/for_ChronicleConnection/when_creating_clients/with_correlated_multi_host_callers.spec.ts +73 -0
- package/connection/for_OAuthTokenProvider/when_acquiring_tokens/with_http_instrumentation.spec.ts +102 -0
- package/connection/for_TraceContextMiddleware/when_calling/with_active_context.spec.ts +235 -0
- package/connection/for_TraceContextMiddleware/when_calling/with_grpc_instrumentation.spec.ts +102 -0
- package/correlation/CorrelationIdManager.ts +10 -0
- package/dist/ChronicleClient.d.ts.map +1 -1
- package/dist/ChronicleClient.js +35 -33
- package/dist/ChronicleClient.js.map +1 -1
- package/dist/ChronicleOptions.d.ts +8 -0
- package/dist/ChronicleOptions.d.ts.map +1 -1
- package/dist/ChronicleOptions.js +19 -1
- package/dist/ChronicleOptions.js.map +1 -1
- package/dist/EventStore.d.ts +3 -1
- package/dist/EventStore.d.ts.map +1 -1
- package/dist/EventStore.js +14 -12
- package/dist/EventStore.js.map +1 -1
- package/dist/Metrics.d.ts +23 -64
- package/dist/Metrics.d.ts.map +1 -1
- package/dist/Metrics.js +62 -92
- package/dist/Metrics.js.map +1 -1
- package/dist/Tracing.d.ts +1 -1
- package/dist/Tracing.d.ts.map +1 -1
- package/dist/Tracing.js +4 -2
- package/dist/Tracing.js.map +1 -1
- package/dist/WellKnownTelemetryNames.d.ts +65 -0
- package/dist/WellKnownTelemetryNames.d.ts.map +1 -0
- package/dist/WellKnownTelemetryNames.js +67 -0
- package/dist/WellKnownTelemetryNames.js.map +1 -0
- package/dist/artifacts/withActivatedArtifact.d.ts +2 -1
- package/dist/artifacts/withActivatedArtifact.d.ts.map +1 -1
- package/dist/artifacts/withActivatedArtifact.js +5 -4
- package/dist/artifacts/withActivatedArtifact.js.map +1 -1
- package/dist/connection/ChronicleConnection.d.ts +5 -0
- package/dist/connection/ChronicleConnection.d.ts.map +1 -1
- package/dist/connection/ChronicleConnection.js +13 -6
- package/dist/connection/ChronicleConnection.js.map +1 -1
- package/dist/connection/CompatibilityPreflight.d.ts.map +1 -1
- package/dist/connection/CompatibilityPreflight.js +2 -1
- package/dist/connection/CompatibilityPreflight.js.map +1 -1
- package/dist/connection/KernelKeepAlive.d.ts +3 -1
- package/dist/connection/KernelKeepAlive.d.ts.map +1 -1
- package/dist/connection/KernelKeepAlive.js +10 -7
- package/dist/connection/KernelKeepAlive.js.map +1 -1
- package/dist/connection/TokenProvider.d.ts.map +1 -1
- package/dist/connection/TokenProvider.js +3 -1
- package/dist/connection/TokenProvider.js.map +1 -1
- package/dist/connection/TraceContextMiddleware.d.ts +4 -0
- package/dist/connection/TraceContextMiddleware.d.ts.map +1 -0
- package/dist/connection/TraceContextMiddleware.js +30 -0
- package/dist/connection/TraceContextMiddleware.js.map +1 -0
- package/dist/correlation/CorrelationIdManager.d.ts +4 -0
- package/dist/correlation/CorrelationIdManager.d.ts.map +1 -1
- package/dist/correlation/CorrelationIdManager.js +8 -0
- package/dist/correlation/CorrelationIdManager.js.map +1 -1
- package/dist/eventSequences/EventLog.d.ts +2 -1
- package/dist/eventSequences/EventLog.d.ts.map +1 -1
- package/dist/eventSequences/EventLog.js +2 -2
- package/dist/eventSequences/EventLog.js.map +1 -1
- package/dist/eventSequences/EventSequence.d.ts +4 -1
- package/dist/eventSequences/EventSequence.d.ts.map +1 -1
- package/dist/eventSequences/EventSequence.js +63 -80
- package/dist/eventSequences/EventSequence.js.map +1 -1
- package/dist/eventStoreSubscriptions/EventStoreSubscriptions.d.ts.map +1 -1
- package/dist/eventStoreSubscriptions/EventStoreSubscriptions.js +3 -4
- package/dist/eventStoreSubscriptions/EventStoreSubscriptions.js.map +1 -1
- package/dist/index.d.ts +7 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -1
- package/dist/index.js.map +1 -1
- package/dist/logging/ChronicleLogEntry.d.ts +11 -0
- package/dist/logging/ChronicleLogEntry.d.ts.map +1 -0
- package/dist/logging/ChronicleLogEntry.js +4 -0
- package/dist/logging/ChronicleLogEntry.js.map +1 -0
- package/dist/logging/ChronicleLogLevel.d.ts +9 -0
- package/dist/logging/ChronicleLogLevel.d.ts.map +1 -0
- package/dist/logging/ChronicleLogLevel.js +12 -0
- package/dist/logging/ChronicleLogLevel.js.map +1 -0
- package/dist/logging/DiagChronicleLogger.d.ts +7 -0
- package/dist/logging/DiagChronicleLogger.d.ts.map +1 -0
- package/dist/logging/DiagChronicleLogger.js +10 -0
- package/dist/logging/DiagChronicleLogger.js.map +1 -0
- package/dist/logging/IChronicleLogger.d.ts +7 -0
- package/dist/logging/IChronicleLogger.d.ts.map +1 -0
- package/dist/logging/IChronicleLogger.js +4 -0
- package/dist/logging/IChronicleLogger.js.map +1 -0
- package/dist/logging/createLogger.d.ts +10 -0
- package/dist/logging/createLogger.d.ts.map +1 -0
- package/dist/logging/createLogger.js +55 -0
- package/dist/logging/createLogger.js.map +1 -0
- package/dist/projections/Projections.d.ts.map +1 -1
- package/dist/projections/Projections.js +4 -3
- package/dist/projections/Projections.js.map +1 -1
- package/dist/reactors/Reactors.d.ts.map +1 -1
- package/dist/reactors/Reactors.js +26 -24
- package/dist/reactors/Reactors.js.map +1 -1
- package/dist/readModels/IReadModels.d.ts +14 -0
- package/dist/readModels/IReadModels.d.ts.map +1 -1
- package/dist/readModels/ReadModels.d.ts +6 -0
- package/dist/readModels/ReadModels.d.ts.map +1 -1
- package/dist/readModels/ReadModels.js +110 -0
- package/dist/readModels/ReadModels.js.map +1 -1
- package/dist/readModels/for_ReadModels/given/a_stored_read_model.d.ts +20 -0
- package/dist/readModels/for_ReadModels/given/a_stored_read_model.d.ts.map +1 -0
- package/dist/readModels/for_ReadModels/given/a_stored_read_model.js +79 -0
- package/dist/readModels/for_ReadModels/given/a_stored_read_model.js.map +1 -0
- package/dist/reducers/Reducers.d.ts.map +1 -1
- package/dist/reducers/Reducers.js +28 -25
- package/dist/reducers/Reducers.js.map +1 -1
- package/dist/seeding/EventSeeding.d.ts.map +1 -1
- package/dist/seeding/EventSeeding.js +4 -3
- package/dist/seeding/EventSeeding.js.map +1 -1
- package/dist/telemetry/ChronicleTelemetryOptions.d.ts +11 -0
- package/dist/telemetry/ChronicleTelemetryOptions.d.ts.map +1 -0
- package/dist/telemetry/ChronicleTelemetryOptions.js +4 -0
- package/dist/telemetry/ChronicleTelemetryOptions.js.map +1 -0
- package/dist/telemetry/observeOperation.d.ts +6 -0
- package/dist/telemetry/observeOperation.d.ts.map +1 -0
- package/dist/telemetry/observeOperation.js +23 -0
- package/dist/telemetry/observeOperation.js.map +1 -0
- package/dist/telemetry/runInBackgroundContext.d.ts +3 -0
- package/dist/telemetry/runInBackgroundContext.d.ts.map +1 -0
- package/dist/telemetry/runInBackgroundContext.js +9 -0
- package/dist/telemetry/runInBackgroundContext.js.map +1 -0
- package/dist/telemetry/spanAttributes.d.ts +14 -0
- package/dist/telemetry/spanAttributes.d.ts.map +1 -0
- package/dist/telemetry/spanAttributes.js +47 -0
- package/dist/telemetry/spanAttributes.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/eventSequences/EventLog.ts +4 -2
- package/eventSequences/EventSequence.ts +64 -81
- package/eventStoreSubscriptions/EventStoreSubscriptions.ts +5 -5
- package/for_ChronicleClient/when_starting_background_work/with_a_correlated_caller.spec.ts +150 -0
- package/for_ChronicleOptions/when_configuring_telemetry/with_event_source_identifiers.spec.ts +44 -0
- package/index.ts +7 -1
- package/logging/ChronicleLogEntry.ts +14 -0
- package/logging/ChronicleLogLevel.ts +11 -0
- package/logging/DiagChronicleLogger.ts +13 -0
- package/logging/IChronicleLogger.ts +10 -0
- package/logging/createLogger.ts +50 -0
- package/logging/for_ChronicleLogger/when_logging/with_client_owned_sinks.spec.ts +96 -0
- package/package.json +7 -1
- package/projections/Projections.ts +4 -3
- package/reactors/Reactors.ts +27 -25
- package/reactors/for_Reactors/when_delivering/with_activation.spec.ts +14 -14
- package/readModels/IReadModels.ts +15 -0
- package/readModels/ReadModels.ts +118 -1
- package/readModels/for_ReadModels/given/a_stored_read_model.ts +62 -0
- package/readModels/for_ReadModels/when_releasing_a_document/with_a_default_subject.spec.ts +39 -0
- package/readModels/for_ReadModels/when_releasing_a_document/with_a_frozen_document.spec.ts +28 -0
- package/readModels/for_ReadModels/when_releasing_a_document/with_a_malformed_response.spec.ts +24 -0
- package/readModels/for_ReadModels/when_releasing_a_document/with_a_reported_failure.spec.ts +38 -0
- package/readModels/for_ReadModels/when_releasing_a_document/with_an_empty_released_value.spec.ts +19 -0
- package/readModels/for_ReadModels/when_releasing_a_document/with_an_unknown_subject_property.spec.ts +42 -0
- package/readModels/for_ReadModels/when_releasing_a_document/with_bookkeeping_fields.spec.ts +27 -0
- package/readModels/for_ReadModels/when_releasing_a_document/with_conflicting_or_missing_properties.spec.ts +32 -0
- package/readModels/for_ReadModels/when_releasing_a_document/with_empty_subject_metadata.spec.ts +56 -0
- package/readModels/for_ReadModels/when_releasing_a_document/with_invalid_subject_metadata.spec.ts +27 -0
- package/readModels/for_ReadModels/when_releasing_a_document/with_mixed_subjects.spec.ts +38 -0
- package/readModels/for_ReadModels/when_releasing_a_document/with_property_subjects.spec.ts +52 -0
- package/readModels/for_ReadModels/when_releasing_a_document/with_whitespace_subjects.spec.ts +24 -0
- package/readModels/for_ReadModels/when_releasing_a_document/without_subjects.spec.ts +24 -0
- package/reducers/Reducers.ts +29 -26
- package/seeding/EventSeeding.ts +6 -4
- package/telemetry/ChronicleTelemetryOptions.ts +8 -0
- package/telemetry/for_ChronicleTelemetry/given/a_telemetry_session.fixture.ts +36 -0
- package/telemetry/for_ChronicleTelemetry/given/an_event_sequence.fixture.ts +29 -0
- package/telemetry/for_ChronicleTelemetry/when_appending/with_shared_and_legacy_attributes.spec.ts +58 -0
- package/telemetry/for_ChronicleTelemetry/when_appending/without_an_sdk.spec.ts +15 -0
- package/telemetry/for_ChronicleTelemetry/when_documenting/with_public_names.spec.ts +15 -0
- package/telemetry/for_ChronicleTelemetry/when_recording_failures/with_sensitive_exception_details.spec.ts +34 -0
- package/telemetry/for_ChronicleTelemetry/when_recording_identifiers/with_per_client_privacy.spec.ts +92 -0
- package/telemetry/for_ChronicleTelemetry/when_recording_metrics/with_legacy_overlap.spec.ts +40 -0
- package/telemetry/for_ChronicleTelemetry/when_recording_sequence_numbers/with_integer_precision.spec.ts +23 -0
- package/telemetry/observeOperation.ts +25 -0
- package/telemetry/runInBackgroundContext.ts +10 -0
- package/telemetry/spanAttributes.ts +49 -0
package/ChronicleClient.ts
CHANGED
|
@@ -2,7 +2,9 @@
|
|
|
2
2
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
3
3
|
|
|
4
4
|
import * as os from 'os';
|
|
5
|
-
import {
|
|
5
|
+
import { createLogger } from './logging/createLogger.js';
|
|
6
|
+
import { setTelemetryAttribute, recordSafeException } from './telemetry/spanAttributes.js';
|
|
7
|
+
import { WellKnownTelemetryNames } from './WellKnownTelemetryNames.js';
|
|
6
8
|
import { SpanStatusCode } from '@opentelemetry/api';
|
|
7
9
|
import { ChronicleOptions } from './ChronicleOptions.js';
|
|
8
10
|
import { ChronicleConnection } from './connection/index.js';
|
|
@@ -19,7 +21,8 @@ import { EventStoreNamespaceName } from './EventStoreNamespaceName.js';
|
|
|
19
21
|
import { IChronicleClient } from './IChronicleClient.js';
|
|
20
22
|
import { IEventStore } from './IEventStore.js';
|
|
21
23
|
import { ChronicleMetrics } from './Metrics.js';
|
|
22
|
-
import {
|
|
24
|
+
import { observeOperation } from './telemetry/observeOperation.js';
|
|
25
|
+
import { runInBackgroundContext } from './telemetry/runInBackgroundContext.js';
|
|
23
26
|
import { TypeDiscoverer } from './types/index.js';
|
|
24
27
|
import { takeUnregisteredModelBoundMappings } from './types/modelBoundPropertyMetadata.js';
|
|
25
28
|
import { reachableReadModelTypes } from './readModels/rootReadModelTypes.js';
|
|
@@ -45,9 +48,7 @@ export class ChronicleClient implements IChronicleClient {
|
|
|
45
48
|
private readonly _stores: Map<string, EventStore> = new Map();
|
|
46
49
|
private readonly _lifecycle = new ConnectionLifecycle();
|
|
47
50
|
|
|
48
|
-
private readonly _logger
|
|
49
|
-
namespace: '@cratis/chronicle/ChronicleClient'
|
|
50
|
-
});
|
|
51
|
+
private readonly _logger: ReturnType<typeof createLogger>;
|
|
51
52
|
|
|
52
53
|
private _watchdogHandle?: ReturnType<typeof setInterval>;
|
|
53
54
|
private _connectOperation?: Promise<void>;
|
|
@@ -64,6 +65,7 @@ export class ChronicleClient implements IChronicleClient {
|
|
|
64
65
|
* @param options - The options to configure the client, including the connection string.
|
|
65
66
|
*/
|
|
66
67
|
constructor(readonly options: ChronicleOptions) {
|
|
68
|
+
this._logger = createLogger('@cratis/chronicle/ChronicleClient', options.logger);
|
|
67
69
|
// When TLS is disabled, pass pre-built insecure credentials directly.
|
|
68
70
|
// @cratis/chronicle.contracts ≤15.24.3 always composes call credentials with
|
|
69
71
|
// channel credentials, which gRPC forbids for insecure channels. Passing
|
|
@@ -72,7 +74,7 @@ export class ChronicleClient implements IChronicleClient {
|
|
|
72
74
|
const connectionOptions = options.connectionString.disableTls
|
|
73
75
|
? { connectionString: options.connectionString, credentials: options.connectionString.createCredentials() }
|
|
74
76
|
: { connectionString: options.connectionString };
|
|
75
|
-
this._connection = new ChronicleConnection(connectionOptions);
|
|
77
|
+
this._connection = new ChronicleConnection({ ...connectionOptions, logger: options.logger });
|
|
76
78
|
|
|
77
79
|
this._logger.info('Created Chronicle client', {
|
|
78
80
|
serverAddress: `${options.connectionString.serverAddress.host}:${options.connectionString.serverAddress.port}`,
|
|
@@ -80,9 +82,11 @@ export class ChronicleClient implements IChronicleClient {
|
|
|
80
82
|
});
|
|
81
83
|
|
|
82
84
|
if (options.discoveryPatterns.length > 0) {
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
this.
|
|
85
|
+
runInBackgroundContext(() => {
|
|
86
|
+
this._discoveryOperation = TypeDiscoverer.default.discover(options.discoveryPatterns);
|
|
87
|
+
this._discoveryOperation.catch(error => {
|
|
88
|
+
this._logger.error('Artifact file discovery failed', { error });
|
|
89
|
+
});
|
|
86
90
|
});
|
|
87
91
|
}
|
|
88
92
|
|
|
@@ -120,9 +124,9 @@ export class ChronicleClient implements IChronicleClient {
|
|
|
120
124
|
? new EventStoreNamespaceName(namespace)
|
|
121
125
|
: namespace;
|
|
122
126
|
|
|
123
|
-
return
|
|
124
|
-
span
|
|
125
|
-
span
|
|
127
|
+
return observeOperation(WellKnownTelemetryNames.spans.getEventStore, async span => {
|
|
128
|
+
setTelemetryAttribute(span, 'eventStore', storeName.value);
|
|
129
|
+
setTelemetryAttribute(span, 'namespace', namespaceName.value);
|
|
126
130
|
try {
|
|
127
131
|
const store = await this.withReconnect('get_event_store', async () => {
|
|
128
132
|
await this.ensureConnected();
|
|
@@ -142,7 +146,7 @@ export class ChronicleClient implements IChronicleClient {
|
|
|
142
146
|
});
|
|
143
147
|
ensureCommandSuccess('ensure event store', await this._connection.eventStores.ensureEventStore({ Name: storeName.value }));
|
|
144
148
|
|
|
145
|
-
const created = new EventStore(storeName, namespaceName, this._connection, this._lifecycle, this.options.defaultSinkTypeId, this.options.clientArtifactsProvider, this.options.reactorResultHandler, this.options.artifactActivator, this.options.readModelNamingPolicy);
|
|
149
|
+
const created = new EventStore(storeName, namespaceName, this._connection, this._lifecycle, this.options.defaultSinkTypeId, this.options.clientArtifactsProvider, this.options.reactorResultHandler, this.options.artifactActivator, this.options.readModelNamingPolicy, this.options.telemetry);
|
|
146
150
|
this._stores.set(key, created);
|
|
147
151
|
|
|
148
152
|
await this.registerArtifactsForStore(created, 'new-store');
|
|
@@ -156,12 +160,11 @@ export class ChronicleClient implements IChronicleClient {
|
|
|
156
160
|
span.setStatus({ code: SpanStatusCode.OK });
|
|
157
161
|
return store;
|
|
158
162
|
} catch (error) {
|
|
159
|
-
span
|
|
160
|
-
span.recordException(error as Error);
|
|
163
|
+
recordSafeException(span, error);
|
|
161
164
|
this._logger.error('Failed getting event store', {
|
|
162
165
|
eventStore: storeName.value,
|
|
163
166
|
namespace: namespaceName.value,
|
|
164
|
-
error
|
|
167
|
+
error
|
|
165
168
|
});
|
|
166
169
|
throw error;
|
|
167
170
|
} finally {
|
|
@@ -172,7 +175,7 @@ export class ChronicleClient implements IChronicleClient {
|
|
|
172
175
|
|
|
173
176
|
/** @inheritdoc */
|
|
174
177
|
async getEventStores(): Promise<EventStoreName[]> {
|
|
175
|
-
return
|
|
178
|
+
return observeOperation(WellKnownTelemetryNames.spans.getEventStores, async span => {
|
|
176
179
|
try {
|
|
177
180
|
const response = await this.withReconnect('get_event_stores', async () => {
|
|
178
181
|
await this.ensureConnected();
|
|
@@ -185,10 +188,9 @@ export class ChronicleClient implements IChronicleClient {
|
|
|
185
188
|
span.setStatus({ code: SpanStatusCode.OK });
|
|
186
189
|
return result;
|
|
187
190
|
} catch (error) {
|
|
188
|
-
span
|
|
189
|
-
span.recordException(error as Error);
|
|
191
|
+
recordSafeException(span, error);
|
|
190
192
|
this._logger.error('Failed retrieving event stores', {
|
|
191
|
-
error
|
|
193
|
+
error
|
|
192
194
|
});
|
|
193
195
|
throw error;
|
|
194
196
|
} finally {
|
|
@@ -210,7 +212,7 @@ export class ChronicleClient implements IChronicleClient {
|
|
|
210
212
|
if (this._lifecycle.isConnected) {
|
|
211
213
|
void this._lifecycle.disconnected(error => {
|
|
212
214
|
this._logger.error('Disconnected lifecycle callback failed during dispose', {
|
|
213
|
-
error
|
|
215
|
+
error
|
|
214
216
|
});
|
|
215
217
|
});
|
|
216
218
|
}
|
|
@@ -244,7 +246,7 @@ export class ChronicleClient implements IChronicleClient {
|
|
|
244
246
|
await this.startKernelKeepAlive();
|
|
245
247
|
await this._lifecycle.connected(error => {
|
|
246
248
|
this._logger.error('Connected lifecycle callback failed', {
|
|
247
|
-
error
|
|
249
|
+
error
|
|
248
250
|
});
|
|
249
251
|
});
|
|
250
252
|
return;
|
|
@@ -280,7 +282,7 @@ export class ChronicleClient implements IChronicleClient {
|
|
|
280
282
|
}
|
|
281
283
|
|
|
282
284
|
if (!this._connectOperation) {
|
|
283
|
-
this._connectOperation = this.connectWithRetry().finally(() => {
|
|
285
|
+
this._connectOperation = runInBackgroundContext(() => this.connectWithRetry()).finally(() => {
|
|
284
286
|
this._connectOperation = undefined;
|
|
285
287
|
});
|
|
286
288
|
}
|
|
@@ -292,16 +294,16 @@ export class ChronicleClient implements IChronicleClient {
|
|
|
292
294
|
if (this._connectionFailure) throw this._connectionFailure;
|
|
293
295
|
|
|
294
296
|
if (!this._reconnectOperation) {
|
|
295
|
-
this._reconnectOperation = (async () => {
|
|
297
|
+
this._reconnectOperation = runInBackgroundContext(async () => {
|
|
296
298
|
this._logger.warn('Reconnecting to Chronicle kernel', {
|
|
297
299
|
reason,
|
|
298
|
-
error
|
|
300
|
+
error
|
|
299
301
|
});
|
|
300
302
|
|
|
301
303
|
if (this._lifecycle.isConnected) {
|
|
302
304
|
await this._lifecycle.disconnected(disconnectError => {
|
|
303
305
|
this._logger.error('Disconnected lifecycle callback failed', {
|
|
304
|
-
error:
|
|
306
|
+
error: disconnectError
|
|
305
307
|
});
|
|
306
308
|
});
|
|
307
309
|
}
|
|
@@ -317,7 +319,7 @@ export class ChronicleClient implements IChronicleClient {
|
|
|
317
319
|
await this.startKernelKeepAlive();
|
|
318
320
|
await this._lifecycle.connected(connectedError => {
|
|
319
321
|
this._logger.error('Connected lifecycle callback failed after reconnect', {
|
|
320
|
-
error:
|
|
322
|
+
error: connectedError
|
|
321
323
|
});
|
|
322
324
|
});
|
|
323
325
|
return;
|
|
@@ -331,7 +333,7 @@ export class ChronicleClient implements IChronicleClient {
|
|
|
331
333
|
await this.backOff(attempt, 'Reconnect attempt failed, retrying', reconnectError);
|
|
332
334
|
}
|
|
333
335
|
}
|
|
334
|
-
})
|
|
336
|
+
}).finally(() => {
|
|
335
337
|
this._reconnectOperation = undefined;
|
|
336
338
|
});
|
|
337
339
|
}
|
|
@@ -351,7 +353,7 @@ export class ChronicleClient implements IChronicleClient {
|
|
|
351
353
|
this._logger.warn(message, {
|
|
352
354
|
attempt,
|
|
353
355
|
delayMs,
|
|
354
|
-
error
|
|
356
|
+
error
|
|
355
357
|
});
|
|
356
358
|
|
|
357
359
|
await new Promise(resolve => setTimeout(resolve, delayMs));
|
|
@@ -437,9 +439,9 @@ export class ChronicleClient implements IChronicleClient {
|
|
|
437
439
|
}
|
|
438
440
|
|
|
439
441
|
private startConnectionWatchdog(): void {
|
|
440
|
-
this._watchdogHandle = setInterval(() => {
|
|
442
|
+
this._watchdogHandle = runInBackgroundContext(() => setInterval(() => {
|
|
441
443
|
void this.runHealthCheck().catch(error => this.backgroundConnectionFailed('watchdog-health-check', error));
|
|
442
|
-
}, ChronicleClient._healthCheckIntervalMs);
|
|
444
|
+
}, ChronicleClient._healthCheckIntervalMs));
|
|
443
445
|
|
|
444
446
|
this._watchdogHandle.unref?.();
|
|
445
447
|
}
|
|
@@ -477,7 +479,7 @@ export class ChronicleClient implements IChronicleClient {
|
|
|
477
479
|
}
|
|
478
480
|
|
|
479
481
|
void this.reconnect(reason, error).catch(failure => this.backgroundConnectionFailed(reason, failure));
|
|
480
|
-
});
|
|
482
|
+
}, {}, this.options.logger);
|
|
481
483
|
|
|
482
484
|
await keepAlive.start(
|
|
483
485
|
{
|
|
@@ -511,7 +513,7 @@ export class ChronicleClient implements IChronicleClient {
|
|
|
511
513
|
this.failConnection(error instanceof Error ? error : new Error(String(error)));
|
|
512
514
|
this._logger.error('Background connection recovery failed; create a new client after correcting the server', {
|
|
513
515
|
reason,
|
|
514
|
-
error
|
|
516
|
+
error
|
|
515
517
|
});
|
|
516
518
|
}
|
|
517
519
|
|
package/ChronicleOptions.ts
CHANGED
|
@@ -1,14 +1,19 @@
|
|
|
1
1
|
// Copyright (c) Cratis. All rights reserved.
|
|
2
2
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
3
3
|
|
|
4
|
+
import { types } from 'node:util';
|
|
4
5
|
import { DefaultClientArtifactsProvider, IClientArtifactsProvider } from './artifacts/index.js';
|
|
5
6
|
import { ChronicleConnectionString } from './connection/index.js';
|
|
6
7
|
import { WellKnownSinks } from './sinks/index.js';
|
|
7
8
|
import type { ReactorResultHandler } from './reactors/ReactorResultHandler.js';
|
|
8
9
|
import type { ClientArtifactsActivator } from './artifacts/ClientArtifactsActivator.js';
|
|
9
10
|
import type { ReadModelNamingPolicy } from './readModels/ReadModelNamingPolicy.js';
|
|
11
|
+
import type { ChronicleTelemetryOptions } from './telemetry/ChronicleTelemetryOptions.js';
|
|
12
|
+
import type { IChronicleLogger } from './logging/IChronicleLogger.js';
|
|
10
13
|
|
|
11
14
|
type ChronicleOptionsConstructorParams = {
|
|
15
|
+
telemetry?: ChronicleTelemetryOptions;
|
|
16
|
+
logger?: IChronicleLogger;
|
|
12
17
|
connectionString: ChronicleConnectionString;
|
|
13
18
|
programIdentifier?: string;
|
|
14
19
|
softwareVersion?: string;
|
|
@@ -22,6 +27,8 @@ type ChronicleOptionsConstructorParams = {
|
|
|
22
27
|
};
|
|
23
28
|
|
|
24
29
|
type ChronicleOptionsFactoryParams = {
|
|
30
|
+
telemetry?: ChronicleTelemetryOptions;
|
|
31
|
+
logger?: IChronicleLogger;
|
|
25
32
|
clientArtifactsProvider?: IClientArtifactsProvider;
|
|
26
33
|
discoveryPatterns?: string[];
|
|
27
34
|
defaultSinkTypeId?: string;
|
|
@@ -34,6 +41,12 @@ type ChronicleOptionsFactoryParams = {
|
|
|
34
41
|
* Represents configuration options for the Chronicle client.
|
|
35
42
|
*/
|
|
36
43
|
export class ChronicleOptions {
|
|
44
|
+
/** Per-client telemetry privacy settings. Event source identifiers are omitted by default. */
|
|
45
|
+
readonly telemetry?: ChronicleTelemetryOptions;
|
|
46
|
+
|
|
47
|
+
/** Application diagnostic sink. Absent uses the OpenTelemetry diag compatibility adapter. */
|
|
48
|
+
readonly logger?: IChronicleLogger;
|
|
49
|
+
|
|
37
50
|
/**
|
|
38
51
|
* The connection string used to connect to the Chronicle Kernel.
|
|
39
52
|
*/
|
|
@@ -101,6 +114,17 @@ export class ChronicleOptions {
|
|
|
101
114
|
this.reactorResultHandler = options.reactorResultHandler;
|
|
102
115
|
this.artifactActivator = options.artifactActivator;
|
|
103
116
|
this.readModelNamingPolicy = options.readModelNamingPolicy;
|
|
117
|
+
const policy = options.telemetry?.eventSourceId;
|
|
118
|
+
if (policy !== undefined) {
|
|
119
|
+
if (policy?.mode !== 'raw' && policy?.mode !== 'hmac') {
|
|
120
|
+
throw new TypeError('telemetry.eventSourceId.mode must be raw or hmac.');
|
|
121
|
+
}
|
|
122
|
+
if (policy.mode === 'hmac' && (!types.isUint8Array(policy.key) || policy.key.byteLength === 0)) {
|
|
123
|
+
throw new TypeError('telemetry.eventSourceId.key must be a non-empty Uint8Array for hmac mode.');
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
this.telemetry = options.telemetry;
|
|
127
|
+
this.logger = options.logger;
|
|
104
128
|
}
|
|
105
129
|
|
|
106
130
|
private static defaultDiscoveryPatterns(): string[] {
|
|
@@ -144,7 +168,9 @@ export class ChronicleOptions {
|
|
|
144
168
|
defaultSinkTypeId: options?.defaultSinkTypeId,
|
|
145
169
|
reactorResultHandler: options?.reactorResultHandler,
|
|
146
170
|
artifactActivator: options?.artifactActivator,
|
|
147
|
-
readModelNamingPolicy: options?.readModelNamingPolicy
|
|
171
|
+
readModelNamingPolicy: options?.readModelNamingPolicy,
|
|
172
|
+
telemetry: options?.telemetry,
|
|
173
|
+
logger: options?.logger
|
|
148
174
|
});
|
|
149
175
|
}
|
|
150
176
|
|
package/EventStore.ts
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
// Copyright (c) Cratis. All rights reserved.
|
|
2
2
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
3
3
|
|
|
4
|
-
import {
|
|
4
|
+
import { createLogger } from './logging/createLogger.js';
|
|
5
|
+
import type { ChronicleTelemetryOptions } from './telemetry/ChronicleTelemetryOptions.js';
|
|
6
|
+
import { setTelemetryAttribute, recordSafeException } from './telemetry/spanAttributes.js';
|
|
7
|
+
import { WellKnownTelemetryNames } from './WellKnownTelemetryNames.js';
|
|
5
8
|
import { SpanStatusCode } from '@opentelemetry/api';
|
|
6
9
|
import { ChronicleConnection } from './connection/index.js';
|
|
7
10
|
import { ConnectionLifecycle } from './connection/ConnectionLifecycle.js';
|
|
@@ -31,7 +34,7 @@ import { IReadModels } from './readModels/IReadModels.js';
|
|
|
31
34
|
import { ReadModels } from './readModels/ReadModels.js';
|
|
32
35
|
import { EventSeeding } from './seeding/EventSeeding.js';
|
|
33
36
|
import { IEventSeeding } from './seeding/IEventSeeding.js';
|
|
34
|
-
import {
|
|
37
|
+
import { observeOperation } from './telemetry/observeOperation.js';
|
|
35
38
|
import { DefaultClientArtifactsProvider } from './artifacts/DefaultClientArtifactsProvider.js';
|
|
36
39
|
import type { IClientArtifactsProvider } from './artifacts/IClientArtifactsProvider.js';
|
|
37
40
|
import { validateArtifactSchemas } from './artifacts/validateArtifactSchemas.js';
|
|
@@ -59,9 +62,7 @@ import { Observers } from './observation/Observers.js';
|
|
|
59
62
|
* via gRPC using the provided {@link ChronicleConnection}.
|
|
60
63
|
*/
|
|
61
64
|
export class EventStore implements IEventStore {
|
|
62
|
-
private readonly _logger
|
|
63
|
-
namespace: '@cratis/chronicle/EventStore'
|
|
64
|
-
});
|
|
65
|
+
private readonly _logger: ReturnType<typeof createLogger>;
|
|
65
66
|
|
|
66
67
|
readonly eventLog: IEventLog;
|
|
67
68
|
readonly eventTypes: IEventTypes;
|
|
@@ -93,15 +94,17 @@ export class EventStore implements IEventStore {
|
|
|
93
94
|
private readonly _artifacts: IClientArtifactsProvider = DefaultClientArtifactsProvider.default,
|
|
94
95
|
reactorResultHandler?: ReactorResultHandler,
|
|
95
96
|
artifactActivator?: ClientArtifactsActivator,
|
|
96
|
-
readModelNamingPolicy?: ReadModelNamingPolicy
|
|
97
|
+
readModelNamingPolicy?: ReadModelNamingPolicy,
|
|
98
|
+
private readonly _telemetry?: ChronicleTelemetryOptions
|
|
97
99
|
) {
|
|
100
|
+
this._logger = createLogger('@cratis/chronicle/EventStore', _connection.logger);
|
|
98
101
|
this.unitOfWorkManager = new UnitOfWorkManager(this);
|
|
99
102
|
|
|
100
103
|
const artifacts = this._artifacts;
|
|
101
104
|
this._constraints = new Constraints(name.value, _connection, artifacts);
|
|
102
105
|
this.constraints = this._constraints;
|
|
103
106
|
const resolveConstraintMessage = this._constraints.resolveMessageFor.bind(this._constraints);
|
|
104
|
-
this.eventLog = new EventLog(name.value, namespace.value, _connection, this.unitOfWorkManager, resolveConstraintMessage);
|
|
107
|
+
this.eventLog = new EventLog(name.value, namespace.value, _connection, this.unitOfWorkManager, resolveConstraintMessage, _telemetry);
|
|
105
108
|
this._sequences.set(EventSequenceId.eventLog.value, this.eventLog);
|
|
106
109
|
|
|
107
110
|
this.eventTypes = new EventTypes(name.value, _connection, artifacts);
|
|
@@ -180,7 +183,7 @@ export class EventStore implements IEventStore {
|
|
|
180
183
|
|
|
181
184
|
const sequence = new EventSequence(
|
|
182
185
|
id, this.name.value, this.namespace.value, this._connection, this.unitOfWorkManager,
|
|
183
|
-
this._constraints.resolveMessageFor.bind(this._constraints)
|
|
186
|
+
this._constraints.resolveMessageFor.bind(this._constraints), this._telemetry
|
|
184
187
|
);
|
|
185
188
|
this._sequences.set(id.value, sequence);
|
|
186
189
|
return sequence;
|
|
@@ -188,16 +191,15 @@ export class EventStore implements IEventStore {
|
|
|
188
191
|
|
|
189
192
|
/** @inheritdoc */
|
|
190
193
|
async getNamespaces(): Promise<EventStoreNamespaceName[]> {
|
|
191
|
-
return
|
|
192
|
-
span
|
|
194
|
+
return observeOperation(WellKnownTelemetryNames.spans.getNamespaces, async span => {
|
|
195
|
+
setTelemetryAttribute(span, 'eventStore', this.name.value);
|
|
193
196
|
try {
|
|
194
197
|
const response = await this._connection.namespaces.allNamespaces({ EventStore: this.name.value });
|
|
195
198
|
const result = ensureQuerySuccess('get namespaces', response).map(namespace => new EventStoreNamespaceName(namespace.Name));
|
|
196
199
|
span.setStatus({ code: SpanStatusCode.OK });
|
|
197
200
|
return result;
|
|
198
201
|
} catch (error) {
|
|
199
|
-
span
|
|
200
|
-
span.recordException(error as Error);
|
|
202
|
+
recordSafeException(span, error);
|
|
201
203
|
throw error;
|
|
202
204
|
} finally {
|
|
203
205
|
span.end();
|
package/Metrics.ts
CHANGED
|
@@ -1,109 +1,83 @@
|
|
|
1
1
|
// Copyright (c) Cratis. All rights reserved.
|
|
2
2
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
3
3
|
|
|
4
|
-
import { metrics } from '@opentelemetry/api';
|
|
4
|
+
import { metrics, type Attributes, type Counter, type Histogram } from '@opentelemetry/api';
|
|
5
|
+
import { clientVersion } from './connection/clientVersion.js';
|
|
6
|
+
import { WellKnownTelemetryNames as names } from './WellKnownTelemetryNames.js';
|
|
5
7
|
|
|
6
|
-
/**
|
|
7
|
-
|
|
8
|
-
* This matches {@link ChronicleInstrumentationName} from Tracing so that all Chronicle
|
|
9
|
-
* telemetry is grouped under a single instrumentation scope in your observability backend.
|
|
10
|
-
*/
|
|
11
|
-
export const ChronicleMeterName = '@cratis/chronicle';
|
|
8
|
+
/** The versioned instrumentation scope shared by Chronicle client traces and metrics. */
|
|
9
|
+
export const ChronicleMeterName = names.scope;
|
|
12
10
|
|
|
13
|
-
/**
|
|
14
|
-
|
|
15
|
-
*
|
|
16
|
-
* If your application has configured an OpenTelemetry SDK (e.g. via {@link https://www.npmjs.com/package/@opentelemetry/sdk-node}),
|
|
17
|
-
* Chronicle metrics will automatically flow through it.
|
|
18
|
-
* If no SDK is configured, the no-op meter is used and no overhead is incurred.
|
|
19
|
-
*/
|
|
20
|
-
export const ChronicleMeter = metrics.getMeter(ChronicleMeterName);
|
|
11
|
+
/** The Chronicle meter. Applications own SDK configuration and export. */
|
|
12
|
+
export const ChronicleMeter = metrics.getMeter(ChronicleMeterName, clientVersion);
|
|
21
13
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
* Counts the number of individual events appended to an event sequence.
|
|
29
|
-
*
|
|
30
|
-
* Attributes: `chronicle.event_store`, `chronicle.namespace`,
|
|
31
|
-
* `chronicle.event_sequence_id`, `chronicle.event_type_id`
|
|
32
|
-
*/
|
|
33
|
-
eventsAppended: ChronicleMeter.createCounter('chronicle.events.appended', {
|
|
34
|
-
description: 'Number of individual events appended to an event sequence.',
|
|
35
|
-
unit: '{event}'
|
|
36
|
-
}),
|
|
14
|
+
// Resolve instruments at recording time: the OTel metrics API does not proxy a meter
|
|
15
|
+
// acquired before the application installs its provider. SDKs cache these instruments.
|
|
16
|
+
function counter(name: string, description: string, unit: string): Counter {
|
|
17
|
+
return { add: (value, attributes, context) => metrics.getMeter(ChronicleMeterName, clientVersion)
|
|
18
|
+
.createCounter(name, { description, unit }).add(value, attributes, context) };
|
|
19
|
+
}
|
|
37
20
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
unit: '{operation}'
|
|
48
|
-
}),
|
|
21
|
+
function duration(name: string, unit: 's' | 'ms'): Histogram {
|
|
22
|
+
const scale = unit === 's' ? 0.001 : 1;
|
|
23
|
+
return { record: (value, attributes, context) => metrics.getMeter(ChronicleMeterName, clientVersion)
|
|
24
|
+
.createHistogram(name, {
|
|
25
|
+
description: 'Duration of completed event append RPCs, including returned rejections.',
|
|
26
|
+
unit,
|
|
27
|
+
advice: { explicitBucketBoundaries: [1, 5, 10, 25, 50, 100, 250, 500, 1000, 2500, 5000].map(value => value * scale) }
|
|
28
|
+
}).record(value, attributes, context) };
|
|
29
|
+
}
|
|
49
30
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
})
|
|
31
|
+
/** Shared-convention instruments. Durations are seconds; batch size is not a dimension. */
|
|
32
|
+
export const ChronicleConventionMetrics = {
|
|
33
|
+
eventsAppended: counter(names.metrics.eventsAppended, 'Number of individual events appended to an event sequence.', '{event}'),
|
|
34
|
+
batchAppendsPerformed: counter(names.metrics.batchAppendsPerformed, 'Number of batch-append operations.', '{operation}'),
|
|
35
|
+
eventStoreRetrievals: counter(names.metrics.eventStoreRetrievals, 'Number of event store retrieval operations.', '{operation}'),
|
|
36
|
+
appendDuration: duration(names.metrics.appendDuration, 's'),
|
|
37
|
+
appendManyDuration: duration(names.metrics.appendManyDuration, 's'),
|
|
38
|
+
constraintViolations: counter(names.metrics.constraintViolations, 'Number of constraint violations encountered during event appends.', '{violation}'),
|
|
39
|
+
appendErrors: counter(names.metrics.appendErrors, 'Number of errors encountered during event appends.', '{error}')
|
|
40
|
+
};
|
|
59
41
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
advice: {
|
|
70
|
-
explicitBucketBoundaries: [1, 5, 10, 25, 50, 100, 250, 500, 1000, 2500, 5000]
|
|
71
|
-
}
|
|
72
|
-
}),
|
|
42
|
+
/** Only the existing bounded-by-configuration dimensions belong on the new instruments. */
|
|
43
|
+
function sharedAttributes(attributes: Attributes = {}): Attributes {
|
|
44
|
+
const result: Attributes = {};
|
|
45
|
+
for (const name of ['eventStore', 'namespace', 'eventSequenceId', 'eventTypeId'] as const) {
|
|
46
|
+
const value = attributes[names.attributes[name]] ?? attributes[names.legacyAttributes[name]];
|
|
47
|
+
if (value !== undefined) result[names.attributes[name]] = value;
|
|
48
|
+
}
|
|
49
|
+
return result;
|
|
50
|
+
}
|
|
73
51
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
appendManyDuration: ChronicleMeter.createHistogram('chronicle.events.append_many_duration', {
|
|
81
|
-
description: 'Duration of batch event append operations.',
|
|
82
|
-
unit: 'ms',
|
|
83
|
-
advice: {
|
|
84
|
-
explicitBucketBoundaries: [1, 5, 10, 25, 50, 100, 250, 500, 1000, 2500, 5000]
|
|
85
|
-
}
|
|
86
|
-
}),
|
|
52
|
+
function bridgeCounter(legacy: Counter, shared: Counter): Counter {
|
|
53
|
+
return { add: (value, attributes, context) => {
|
|
54
|
+
legacy.add(value, attributes, context);
|
|
55
|
+
shared.add(value, sharedAttributes(attributes), context);
|
|
56
|
+
} };
|
|
57
|
+
}
|
|
87
58
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
constraintViolations: ChronicleMeter.createCounter('chronicle.events.constraint_violations', {
|
|
95
|
-
description: 'Number of constraint violations encountered during event appends.',
|
|
96
|
-
unit: '{violation}'
|
|
97
|
-
}),
|
|
59
|
+
function bridgeDuration(legacy: Histogram, shared: Histogram): Histogram {
|
|
60
|
+
return { record: (milliseconds, attributes, context) => {
|
|
61
|
+
legacy.record(milliseconds, attributes, context);
|
|
62
|
+
shared.record(milliseconds / 1000, sharedAttributes(attributes), context);
|
|
63
|
+
} };
|
|
64
|
+
}
|
|
98
65
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
66
|
+
/**
|
|
67
|
+
* Compatibility instruments: existing callers still record milliseconds and legacy attributes.
|
|
68
|
+
* Each measurement also records its shared-convention equivalent, without adding sensitive dimensions.
|
|
69
|
+
*/
|
|
70
|
+
export const ChronicleMetrics = {
|
|
71
|
+
eventsAppended: bridgeCounter(counter(names.legacyMetrics.eventsAppended,
|
|
72
|
+
'Number of individual events appended to an event sequence.', '{event}'), ChronicleConventionMetrics.eventsAppended),
|
|
73
|
+
batchAppendsPerformed: bridgeCounter(counter(names.legacyMetrics.batchAppendsPerformed,
|
|
74
|
+
'Number of batch-append operations.', '{operation}'), ChronicleConventionMetrics.batchAppendsPerformed),
|
|
75
|
+
eventStoreRetrievals: bridgeCounter(counter(names.legacyMetrics.eventStoreRetrievals,
|
|
76
|
+
'Number of event store retrieval operations.', '{operation}'), ChronicleConventionMetrics.eventStoreRetrievals),
|
|
77
|
+
appendDuration: bridgeDuration(duration(names.legacyMetrics.appendDuration, 'ms'), ChronicleConventionMetrics.appendDuration),
|
|
78
|
+
appendManyDuration: bridgeDuration(duration(names.legacyMetrics.appendManyDuration, 'ms'), ChronicleConventionMetrics.appendManyDuration),
|
|
79
|
+
constraintViolations: bridgeCounter(counter(names.legacyMetrics.constraintViolations,
|
|
80
|
+
'Number of constraint violations encountered during event appends.', '{violation}'), ChronicleConventionMetrics.constraintViolations),
|
|
81
|
+
appendErrors: bridgeCounter(counter(names.legacyMetrics.appendErrors,
|
|
82
|
+
'Number of errors encountered during event appends.', '{error}'), ChronicleConventionMetrics.appendErrors)
|
|
109
83
|
};
|
package/Tracing.ts
CHANGED
|
@@ -2,12 +2,14 @@
|
|
|
2
2
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
3
3
|
|
|
4
4
|
import { trace } from '@opentelemetry/api';
|
|
5
|
+
import { clientVersion } from './connection/clientVersion.js';
|
|
6
|
+
import { WellKnownTelemetryNames } from './WellKnownTelemetryNames.js';
|
|
5
7
|
|
|
6
8
|
/**
|
|
7
9
|
* The name of the Chronicle instrumentation library.
|
|
8
10
|
* Use this name to filter or configure Chronicle client spans in your observability backend.
|
|
9
11
|
*/
|
|
10
|
-
export const ChronicleInstrumentationName =
|
|
12
|
+
export const ChronicleInstrumentationName = WellKnownTelemetryNames.scope;
|
|
11
13
|
|
|
12
14
|
/**
|
|
13
15
|
* The OpenTelemetry tracer used by the Chronicle client for all instrumentation.
|
|
@@ -18,4 +20,4 @@ export const ChronicleInstrumentationName = '@cratis/chronicle';
|
|
|
18
20
|
* Chronicle spans will automatically flow through it.
|
|
19
21
|
* If no SDK is configured, the no-op tracer is used and no overhead is incurred.
|
|
20
22
|
*/
|
|
21
|
-
export const ChronicleTracer = trace.getTracer(ChronicleInstrumentationName);
|
|
23
|
+
export const ChronicleTracer = trace.getTracer(ChronicleInstrumentationName, clientVersion);
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
// Copyright (c) Cratis. All rights reserved.
|
|
2
|
+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
3
|
+
|
|
4
|
+
/** Public telemetry names. Legacy names remain available during the minor-release overlap. */
|
|
5
|
+
export const WellKnownTelemetryNames = {
|
|
6
|
+
scope: 'Cratis.Chronicle.Client',
|
|
7
|
+
legacyScope: '@cratis/chronicle',
|
|
8
|
+
attributes: {
|
|
9
|
+
correlationId: 'cratis.correlation_id',
|
|
10
|
+
eventStore: 'cratis.event_store.name',
|
|
11
|
+
namespace: 'cratis.event_store.namespace',
|
|
12
|
+
eventSequenceId: 'cratis.event_sequence.id',
|
|
13
|
+
sequenceNumber: 'cratis.event_sequence.number',
|
|
14
|
+
eventTypeId: 'cratis.event_type.id',
|
|
15
|
+
eventTypeGeneration: 'cratis.event_type.generation',
|
|
16
|
+
eventSourceType: 'cratis.event_source.type',
|
|
17
|
+
eventSourceId: 'cratis.event_source.id',
|
|
18
|
+
eventCount: 'cratis.event.count',
|
|
19
|
+
errorType: 'error.type',
|
|
20
|
+
exceptionType: 'exception.type'
|
|
21
|
+
},
|
|
22
|
+
legacyAttributes: {
|
|
23
|
+
eventStore: 'chronicle.event_store',
|
|
24
|
+
namespace: 'chronicle.namespace',
|
|
25
|
+
eventSequenceId: 'chronicle.event_sequence_id',
|
|
26
|
+
sequenceNumber: 'chronicle.sequence_number',
|
|
27
|
+
eventTypeId: 'chronicle.event_type_id',
|
|
28
|
+
eventTypeGeneration: 'chronicle.event_type_generation',
|
|
29
|
+
eventSourceId: 'chronicle.event_source_id',
|
|
30
|
+
eventCount: 'chronicle.events_count',
|
|
31
|
+
hasEvents: 'chronicle.has_events',
|
|
32
|
+
eventStreamType: 'chronicle.event_stream_type',
|
|
33
|
+
eventStreamId: 'chronicle.event_stream_id'
|
|
34
|
+
},
|
|
35
|
+
spans: {
|
|
36
|
+
append: 'chronicle.event_sequences.append',
|
|
37
|
+
appendMany: 'chronicle.event_sequences.append_many',
|
|
38
|
+
getTailSequenceNumber: 'chronicle.event_sequences.get_tail_sequence_number',
|
|
39
|
+
hasEventsFor: 'chronicle.event_sequences.has_events_for',
|
|
40
|
+
getForEventSourceIdAndEventTypes: 'chronicle.event_sequences.get_for_event_source_id_and_event_types',
|
|
41
|
+
getFromSequenceNumber: 'chronicle.event_sequences.get_from_sequence_number',
|
|
42
|
+
redact: 'chronicle.event_sequences.redact',
|
|
43
|
+
redactForEventSource: 'chronicle.event_sequences.redact_for_event_source',
|
|
44
|
+
completeStream: 'chronicle.event_sequences.complete_stream',
|
|
45
|
+
getEventStore: 'chronicle.client.get_event_store',
|
|
46
|
+
getEventStores: 'chronicle.client.get_event_stores',
|
|
47
|
+
getNamespaces: 'chronicle.event_store.get_namespaces'
|
|
48
|
+
},
|
|
49
|
+
metrics: {
|
|
50
|
+
eventsAppended: 'cratis.chronicle.event_sequence.appended',
|
|
51
|
+
batchAppendsPerformed: 'cratis.chronicle.event_sequence.batch_appends',
|
|
52
|
+
eventStoreRetrievals: 'cratis.chronicle.event_store.retrievals',
|
|
53
|
+
appendDuration: 'cratis.chronicle.event_sequence.append_duration',
|
|
54
|
+
appendManyDuration: 'cratis.chronicle.event_sequence.append_many_duration',
|
|
55
|
+
constraintViolations: 'cratis.chronicle.event_sequence.constraint_violations',
|
|
56
|
+
appendErrors: 'cratis.chronicle.event_sequence.append_errors'
|
|
57
|
+
},
|
|
58
|
+
legacyMetrics: {
|
|
59
|
+
eventsAppended: 'chronicle.events.appended',
|
|
60
|
+
batchAppendsPerformed: 'chronicle.events.batch_appends',
|
|
61
|
+
eventStoreRetrievals: 'chronicle.client.event_store_retrievals',
|
|
62
|
+
appendDuration: 'chronicle.events.append_duration',
|
|
63
|
+
appendManyDuration: 'chronicle.events.append_many_duration',
|
|
64
|
+
constraintViolations: 'chronicle.events.constraint_violations',
|
|
65
|
+
appendErrors: 'chronicle.events.append_errors'
|
|
66
|
+
}
|
|
67
|
+
} as const;
|