@cratis/chronicle 6.33.0 → 6.35.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.
Files changed (243) hide show
  1. package/ChronicleClient.ts +43 -35
  2. package/ChronicleOptions.ts +27 -1
  3. package/EventStore.ts +22 -12
  4. package/Metrics.ts +70 -96
  5. package/Tracing.ts +4 -2
  6. package/WellKnownTelemetryNames.ts +67 -0
  7. package/artifacts/validateArtifactSchemas.spec.ts +1 -1
  8. package/artifacts/withActivatedArtifact.ts +7 -5
  9. package/connection/ChronicleConnection.ts +18 -6
  10. package/connection/CompatibilityPreflight.ts +2 -1
  11. package/connection/KernelKeepAlive.ts +13 -7
  12. package/connection/TokenProvider.ts +3 -1
  13. package/connection/TraceContextMiddleware.ts +30 -0
  14. package/connection/for_ChronicleConnection/when_creating_clients/with_correlated_multi_host_callers.spec.ts +73 -0
  15. package/connection/for_OAuthTokenProvider/when_acquiring_tokens/with_http_instrumentation.spec.ts +102 -0
  16. package/connection/for_TraceContextMiddleware/when_calling/with_active_context.spec.ts +235 -0
  17. package/connection/for_TraceContextMiddleware/when_calling/with_grpc_instrumentation.spec.ts +102 -0
  18. package/correlation/CorrelationIdManager.ts +10 -0
  19. package/dist/ChronicleClient.d.ts.map +1 -1
  20. package/dist/ChronicleClient.js +45 -35
  21. package/dist/ChronicleClient.js.map +1 -1
  22. package/dist/ChronicleOptions.d.ts +8 -0
  23. package/dist/ChronicleOptions.d.ts.map +1 -1
  24. package/dist/ChronicleOptions.js +19 -1
  25. package/dist/ChronicleOptions.js.map +1 -1
  26. package/dist/EventStore.d.ts +3 -1
  27. package/dist/EventStore.d.ts.map +1 -1
  28. package/dist/EventStore.js +22 -12
  29. package/dist/EventStore.js.map +1 -1
  30. package/dist/Metrics.d.ts +23 -64
  31. package/dist/Metrics.d.ts.map +1 -1
  32. package/dist/Metrics.js +62 -92
  33. package/dist/Metrics.js.map +1 -1
  34. package/dist/Tracing.d.ts +1 -1
  35. package/dist/Tracing.d.ts.map +1 -1
  36. package/dist/Tracing.js +4 -2
  37. package/dist/Tracing.js.map +1 -1
  38. package/dist/WellKnownTelemetryNames.d.ts +65 -0
  39. package/dist/WellKnownTelemetryNames.d.ts.map +1 -0
  40. package/dist/WellKnownTelemetryNames.js +67 -0
  41. package/dist/WellKnownTelemetryNames.js.map +1 -0
  42. package/dist/artifacts/withActivatedArtifact.d.ts +2 -1
  43. package/dist/artifacts/withActivatedArtifact.d.ts.map +1 -1
  44. package/dist/artifacts/withActivatedArtifact.js +5 -4
  45. package/dist/artifacts/withActivatedArtifact.js.map +1 -1
  46. package/dist/connection/ChronicleConnection.d.ts +5 -0
  47. package/dist/connection/ChronicleConnection.d.ts.map +1 -1
  48. package/dist/connection/ChronicleConnection.js +13 -6
  49. package/dist/connection/ChronicleConnection.js.map +1 -1
  50. package/dist/connection/CompatibilityPreflight.d.ts.map +1 -1
  51. package/dist/connection/CompatibilityPreflight.js +2 -1
  52. package/dist/connection/CompatibilityPreflight.js.map +1 -1
  53. package/dist/connection/KernelKeepAlive.d.ts +3 -1
  54. package/dist/connection/KernelKeepAlive.d.ts.map +1 -1
  55. package/dist/connection/KernelKeepAlive.js +10 -7
  56. package/dist/connection/KernelKeepAlive.js.map +1 -1
  57. package/dist/connection/TokenProvider.d.ts.map +1 -1
  58. package/dist/connection/TokenProvider.js +3 -1
  59. package/dist/connection/TokenProvider.js.map +1 -1
  60. package/dist/connection/TraceContextMiddleware.d.ts +4 -0
  61. package/dist/connection/TraceContextMiddleware.d.ts.map +1 -0
  62. package/dist/connection/TraceContextMiddleware.js +30 -0
  63. package/dist/connection/TraceContextMiddleware.js.map +1 -0
  64. package/dist/correlation/CorrelationIdManager.d.ts +4 -0
  65. package/dist/correlation/CorrelationIdManager.d.ts.map +1 -1
  66. package/dist/correlation/CorrelationIdManager.js +8 -0
  67. package/dist/correlation/CorrelationIdManager.js.map +1 -1
  68. package/dist/eventSequences/EventLog.d.ts +2 -1
  69. package/dist/eventSequences/EventLog.d.ts.map +1 -1
  70. package/dist/eventSequences/EventLog.js +2 -2
  71. package/dist/eventSequences/EventLog.js.map +1 -1
  72. package/dist/eventSequences/EventSequence.d.ts +4 -1
  73. package/dist/eventSequences/EventSequence.d.ts.map +1 -1
  74. package/dist/eventSequences/EventSequence.js +63 -80
  75. package/dist/eventSequences/EventSequence.js.map +1 -1
  76. package/dist/eventStoreSubscriptions/EventStoreSubscriptions.d.ts.map +1 -1
  77. package/dist/eventStoreSubscriptions/EventStoreSubscriptions.js +3 -4
  78. package/dist/eventStoreSubscriptions/EventStoreSubscriptions.js.map +1 -1
  79. package/dist/events/handles.d.ts +12 -0
  80. package/dist/events/handles.d.ts.map +1 -0
  81. package/dist/events/handles.js +33 -0
  82. package/dist/events/handles.js.map +1 -0
  83. package/dist/events/index.d.ts +1 -0
  84. package/dist/events/index.d.ts.map +1 -1
  85. package/dist/events/index.js +1 -0
  86. package/dist/events/index.js.map +1 -1
  87. package/dist/index.d.ts +7 -1
  88. package/dist/index.d.ts.map +1 -1
  89. package/dist/index.js +4 -1
  90. package/dist/index.js.map +1 -1
  91. package/dist/logging/ChronicleLogEntry.d.ts +11 -0
  92. package/dist/logging/ChronicleLogEntry.d.ts.map +1 -0
  93. package/dist/logging/ChronicleLogEntry.js +4 -0
  94. package/dist/logging/ChronicleLogEntry.js.map +1 -0
  95. package/dist/logging/ChronicleLogLevel.d.ts +9 -0
  96. package/dist/logging/ChronicleLogLevel.d.ts.map +1 -0
  97. package/dist/logging/ChronicleLogLevel.js +12 -0
  98. package/dist/logging/ChronicleLogLevel.js.map +1 -0
  99. package/dist/logging/DiagChronicleLogger.d.ts +7 -0
  100. package/dist/logging/DiagChronicleLogger.d.ts.map +1 -0
  101. package/dist/logging/DiagChronicleLogger.js +10 -0
  102. package/dist/logging/DiagChronicleLogger.js.map +1 -0
  103. package/dist/logging/IChronicleLogger.d.ts +7 -0
  104. package/dist/logging/IChronicleLogger.d.ts.map +1 -0
  105. package/dist/logging/IChronicleLogger.js +4 -0
  106. package/dist/logging/IChronicleLogger.js.map +1 -0
  107. package/dist/logging/createLogger.d.ts +10 -0
  108. package/dist/logging/createLogger.d.ts.map +1 -0
  109. package/dist/logging/createLogger.js +55 -0
  110. package/dist/logging/createLogger.js.map +1 -0
  111. package/dist/observation/EventHandler.d.ts +7 -0
  112. package/dist/observation/EventHandler.d.ts.map +1 -0
  113. package/dist/observation/EventHandler.js +4 -0
  114. package/dist/observation/EventHandler.js.map +1 -0
  115. package/dist/observation/createHandlerInstanceValidator.d.ts +4 -0
  116. package/dist/observation/createHandlerInstanceValidator.d.ts.map +1 -0
  117. package/dist/observation/createHandlerInstanceValidator.js +40 -0
  118. package/dist/observation/createHandlerInstanceValidator.js.map +1 -0
  119. package/dist/observation/getEventHandlers.d.ts +5 -0
  120. package/dist/observation/getEventHandlers.d.ts.map +1 -0
  121. package/dist/observation/getEventHandlers.js +40 -0
  122. package/dist/observation/getEventHandlers.js.map +1 -0
  123. package/dist/observation/getInstanceMethods.d.ts +4 -0
  124. package/dist/observation/getInstanceMethods.d.ts.map +1 -0
  125. package/dist/observation/getInstanceMethods.js +29 -0
  126. package/dist/observation/getInstanceMethods.js.map +1 -0
  127. package/dist/projections/Projections.d.ts.map +1 -1
  128. package/dist/projections/Projections.js +4 -3
  129. package/dist/projections/Projections.js.map +1 -1
  130. package/dist/reactors/ReactorDispatcher.d.ts.map +1 -1
  131. package/dist/reactors/ReactorDispatcher.js +27 -32
  132. package/dist/reactors/ReactorDispatcher.js.map +1 -1
  133. package/dist/reactors/Reactors.d.ts +1 -0
  134. package/dist/reactors/Reactors.d.ts.map +1 -1
  135. package/dist/reactors/Reactors.js +49 -34
  136. package/dist/reactors/Reactors.js.map +1 -1
  137. package/dist/reactors/index.d.ts +1 -0
  138. package/dist/reactors/index.d.ts.map +1 -1
  139. package/dist/reactors/index.js +1 -0
  140. package/dist/reactors/index.js.map +1 -1
  141. package/dist/reducers/ReducerEventDispatcher.d.ts +1 -0
  142. package/dist/reducers/ReducerEventDispatcher.d.ts.map +1 -1
  143. package/dist/reducers/ReducerEventDispatcher.js +5 -17
  144. package/dist/reducers/ReducerEventDispatcher.js.map +1 -1
  145. package/dist/reducers/ReducerEventHandler.d.ts +3 -6
  146. package/dist/reducers/ReducerEventHandler.d.ts.map +1 -1
  147. package/dist/reducers/Reducers.d.ts +1 -0
  148. package/dist/reducers/Reducers.d.ts.map +1 -1
  149. package/dist/reducers/Reducers.js +47 -32
  150. package/dist/reducers/Reducers.js.map +1 -1
  151. package/dist/reducers/index.d.ts +1 -0
  152. package/dist/reducers/index.d.ts.map +1 -1
  153. package/dist/reducers/index.js +1 -0
  154. package/dist/reducers/index.js.map +1 -1
  155. package/dist/seeding/EventSeeding.d.ts.map +1 -1
  156. package/dist/seeding/EventSeeding.js +4 -3
  157. package/dist/seeding/EventSeeding.js.map +1 -1
  158. package/dist/telemetry/ChronicleTelemetryOptions.d.ts +11 -0
  159. package/dist/telemetry/ChronicleTelemetryOptions.d.ts.map +1 -0
  160. package/dist/telemetry/ChronicleTelemetryOptions.js +4 -0
  161. package/dist/telemetry/ChronicleTelemetryOptions.js.map +1 -0
  162. package/dist/telemetry/observeOperation.d.ts +6 -0
  163. package/dist/telemetry/observeOperation.d.ts.map +1 -0
  164. package/dist/telemetry/observeOperation.js +23 -0
  165. package/dist/telemetry/observeOperation.js.map +1 -0
  166. package/dist/telemetry/runInBackgroundContext.d.ts +3 -0
  167. package/dist/telemetry/runInBackgroundContext.d.ts.map +1 -0
  168. package/dist/telemetry/runInBackgroundContext.js +9 -0
  169. package/dist/telemetry/runInBackgroundContext.js.map +1 -0
  170. package/dist/telemetry/spanAttributes.d.ts +14 -0
  171. package/dist/telemetry/spanAttributes.d.ts.map +1 -0
  172. package/dist/telemetry/spanAttributes.js +47 -0
  173. package/dist/telemetry/spanAttributes.js.map +1 -0
  174. package/dist/testing/ReactorScenario.d.ts +1 -0
  175. package/dist/testing/ReactorScenario.d.ts.map +1 -1
  176. package/dist/testing/ReactorScenario.js +9 -1
  177. package/dist/testing/ReactorScenario.js.map +1 -1
  178. package/dist/testing/ReducerReadModelProcessor.d.ts.map +1 -1
  179. package/dist/testing/ReducerReadModelProcessor.js +1 -0
  180. package/dist/testing/ReducerReadModelProcessor.js.map +1 -1
  181. package/dist/tsconfig.tsbuildinfo +1 -1
  182. package/eventSequences/EventLog.ts +4 -2
  183. package/eventSequences/EventSequence.ts +64 -81
  184. package/eventStoreSubscriptions/EventStoreSubscriptions.ts +5 -5
  185. package/events/for_handles/when_decorating_a_method.legacy.spec.ts +91 -0
  186. package/events/for_handles/when_decorating_a_method.standard.spec.ts +102 -0
  187. package/events/handles.ts +37 -0
  188. package/events/index.ts +1 -0
  189. package/for_ChronicleClient/when_registering_artifacts/with_invalid_handler_mappings.spec.ts +142 -0
  190. package/for_ChronicleClient/when_starting_background_work/with_a_correlated_caller.spec.ts +150 -0
  191. package/for_ChronicleOptions/when_configuring_telemetry/with_event_source_identifiers.spec.ts +44 -0
  192. package/index.ts +7 -1
  193. package/logging/ChronicleLogEntry.ts +14 -0
  194. package/logging/ChronicleLogLevel.ts +11 -0
  195. package/logging/DiagChronicleLogger.ts +13 -0
  196. package/logging/IChronicleLogger.ts +10 -0
  197. package/logging/createLogger.ts +50 -0
  198. package/logging/for_ChronicleLogger/when_logging/with_client_owned_sinks.spec.ts +96 -0
  199. package/observation/EventHandler.ts +9 -0
  200. package/observation/createHandlerInstanceValidator.ts +42 -0
  201. package/observation/for_getEventHandlers/when_discovering_handlers.spec.ts +137 -0
  202. package/observation/for_getEventHandlers/when_reobserving_explicit_handlers.spec.ts +73 -0
  203. package/observation/getEventHandlers.ts +43 -0
  204. package/observation/getInstanceMethods.ts +29 -0
  205. package/package.json +8 -2
  206. package/projections/Projections.ts +4 -3
  207. package/reactors/ReactorDispatcher.ts +26 -30
  208. package/reactors/Reactors.ts +55 -37
  209. package/reactors/decorators.standard.spec.ts +8 -0
  210. package/reactors/for_ReactorDispatcher/when_selecting_explicit_handlers.spec.ts +64 -0
  211. package/reactors/for_Reactors/when_activating_a_field_override.spec.ts +62 -0
  212. package/reactors/for_Reactors/when_delivering/with_activation.spec.ts +14 -14
  213. package/reactors/for_Reactors/when_delivering_to_instance_handlers.spec.ts +108 -0
  214. package/reactors/for_Reactors/when_observing_explicit_handlers.legacy.spec.ts +77 -0
  215. package/reactors/for_Reactors/when_registering_explicit_handlers.spec.ts +53 -0
  216. package/reactors/index.ts +1 -0
  217. package/reducers/ReducerEventDispatcher.ts +5 -16
  218. package/reducers/ReducerEventHandler.ts +4 -6
  219. package/reducers/Reducers.ts +50 -35
  220. package/reducers/for_ReducerEventDispatcher/when_invoking_an_explicit_handler.spec.ts +51 -0
  221. package/reducers/for_ReducerEventDispatcher/when_invoking_instance_handlers.spec.ts +69 -0
  222. package/reducers/for_Reducers/when_activating_a_field_override.spec.ts +63 -0
  223. package/reducers/for_Reducers/when_observing_explicit_handlers.legacy.spec.ts +73 -0
  224. package/reducers/for_Reducers/when_registering_explicit_handlers.spec.ts +57 -0
  225. package/reducers/index.ts +1 -0
  226. package/seeding/EventSeeding.ts +6 -4
  227. package/telemetry/ChronicleTelemetryOptions.ts +8 -0
  228. package/telemetry/for_ChronicleTelemetry/given/a_telemetry_session.fixture.ts +36 -0
  229. package/telemetry/for_ChronicleTelemetry/given/an_event_sequence.fixture.ts +29 -0
  230. package/telemetry/for_ChronicleTelemetry/when_appending/with_shared_and_legacy_attributes.spec.ts +58 -0
  231. package/telemetry/for_ChronicleTelemetry/when_appending/without_an_sdk.spec.ts +15 -0
  232. package/telemetry/for_ChronicleTelemetry/when_documenting/with_public_names.spec.ts +15 -0
  233. package/telemetry/for_ChronicleTelemetry/when_recording_failures/with_sensitive_exception_details.spec.ts +34 -0
  234. package/telemetry/for_ChronicleTelemetry/when_recording_identifiers/with_per_client_privacy.spec.ts +92 -0
  235. package/telemetry/for_ChronicleTelemetry/when_recording_metrics/with_legacy_overlap.spec.ts +40 -0
  236. package/telemetry/for_ChronicleTelemetry/when_recording_sequence_numbers/with_integer_precision.spec.ts +23 -0
  237. package/telemetry/observeOperation.ts +25 -0
  238. package/telemetry/runInBackgroundContext.ts +10 -0
  239. package/telemetry/spanAttributes.ts +49 -0
  240. package/testing/ReactorScenario.ts +9 -1
  241. package/testing/ReducerReadModelProcessor.ts +1 -0
  242. package/testing/for_ReactorScenario/when_delivering_to_an_explicit_handler.spec.ts +100 -0
  243. package/testing/for_ReducerReadModelProcessor/when_an_instance_field_hides_a_handler.spec.ts +29 -0
@@ -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 { diag } from '@opentelemetry/api';
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 { ChronicleTracer } from './Tracing.js';
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 = diag.createComponentLogger({
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
- this._discoveryOperation = TypeDiscoverer.default.discover(options.discoveryPatterns);
84
- this._discoveryOperation.catch(error => {
85
- this._logger.error('Artifact file discovery failed', { error: String(error) });
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 ChronicleTracer.startActiveSpan('chronicle.client.get_event_store', async span => {
124
- span.setAttribute('chronicle.event_store', storeName.value);
125
- span.setAttribute('chronicle.namespace', namespaceName.value);
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,11 +146,17 @@ 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
- await this.registerArtifactsForStore(created, 'new-store');
149
- return created;
152
+ try {
153
+ await this.registerArtifactsForStore(created, 'new-store');
154
+ return created;
155
+ } catch (error) {
156
+ if (this._stores.get(key) === created) this._stores.delete(key);
157
+ created.disposeObservations();
158
+ throw error;
159
+ }
150
160
  });
151
161
 
152
162
  ChronicleMetrics.eventStoreRetrievals.add(1, {
@@ -156,12 +166,11 @@ export class ChronicleClient implements IChronicleClient {
156
166
  span.setStatus({ code: SpanStatusCode.OK });
157
167
  return store;
158
168
  } catch (error) {
159
- span.setStatus({ code: SpanStatusCode.ERROR, message: String(error) });
160
- span.recordException(error as Error);
169
+ recordSafeException(span, error);
161
170
  this._logger.error('Failed getting event store', {
162
171
  eventStore: storeName.value,
163
172
  namespace: namespaceName.value,
164
- error: this.toErrorMessage(error)
173
+ error
165
174
  });
166
175
  throw error;
167
176
  } finally {
@@ -172,7 +181,7 @@ export class ChronicleClient implements IChronicleClient {
172
181
 
173
182
  /** @inheritdoc */
174
183
  async getEventStores(): Promise<EventStoreName[]> {
175
- return ChronicleTracer.startActiveSpan('chronicle.client.get_event_stores', async span => {
184
+ return observeOperation(WellKnownTelemetryNames.spans.getEventStores, async span => {
176
185
  try {
177
186
  const response = await this.withReconnect('get_event_stores', async () => {
178
187
  await this.ensureConnected();
@@ -185,10 +194,9 @@ export class ChronicleClient implements IChronicleClient {
185
194
  span.setStatus({ code: SpanStatusCode.OK });
186
195
  return result;
187
196
  } catch (error) {
188
- span.setStatus({ code: SpanStatusCode.ERROR, message: String(error) });
189
- span.recordException(error as Error);
197
+ recordSafeException(span, error);
190
198
  this._logger.error('Failed retrieving event stores', {
191
- error: this.toErrorMessage(error)
199
+ error
192
200
  });
193
201
  throw error;
194
202
  } finally {
@@ -210,7 +218,7 @@ export class ChronicleClient implements IChronicleClient {
210
218
  if (this._lifecycle.isConnected) {
211
219
  void this._lifecycle.disconnected(error => {
212
220
  this._logger.error('Disconnected lifecycle callback failed during dispose', {
213
- error: this.toErrorMessage(error)
221
+ error
214
222
  });
215
223
  });
216
224
  }
@@ -244,7 +252,7 @@ export class ChronicleClient implements IChronicleClient {
244
252
  await this.startKernelKeepAlive();
245
253
  await this._lifecycle.connected(error => {
246
254
  this._logger.error('Connected lifecycle callback failed', {
247
- error: this.toErrorMessage(error)
255
+ error
248
256
  });
249
257
  });
250
258
  return;
@@ -280,7 +288,7 @@ export class ChronicleClient implements IChronicleClient {
280
288
  }
281
289
 
282
290
  if (!this._connectOperation) {
283
- this._connectOperation = this.connectWithRetry().finally(() => {
291
+ this._connectOperation = runInBackgroundContext(() => this.connectWithRetry()).finally(() => {
284
292
  this._connectOperation = undefined;
285
293
  });
286
294
  }
@@ -292,16 +300,16 @@ export class ChronicleClient implements IChronicleClient {
292
300
  if (this._connectionFailure) throw this._connectionFailure;
293
301
 
294
302
  if (!this._reconnectOperation) {
295
- this._reconnectOperation = (async () => {
303
+ this._reconnectOperation = runInBackgroundContext(async () => {
296
304
  this._logger.warn('Reconnecting to Chronicle kernel', {
297
305
  reason,
298
- error: this.toErrorMessage(error)
306
+ error
299
307
  });
300
308
 
301
309
  if (this._lifecycle.isConnected) {
302
310
  await this._lifecycle.disconnected(disconnectError => {
303
311
  this._logger.error('Disconnected lifecycle callback failed', {
304
- error: this.toErrorMessage(disconnectError)
312
+ error: disconnectError
305
313
  });
306
314
  });
307
315
  }
@@ -317,7 +325,7 @@ export class ChronicleClient implements IChronicleClient {
317
325
  await this.startKernelKeepAlive();
318
326
  await this._lifecycle.connected(connectedError => {
319
327
  this._logger.error('Connected lifecycle callback failed after reconnect', {
320
- error: this.toErrorMessage(connectedError)
328
+ error: connectedError
321
329
  });
322
330
  });
323
331
  return;
@@ -331,7 +339,7 @@ export class ChronicleClient implements IChronicleClient {
331
339
  await this.backOff(attempt, 'Reconnect attempt failed, retrying', reconnectError);
332
340
  }
333
341
  }
334
- })().finally(() => {
342
+ }).finally(() => {
335
343
  this._reconnectOperation = undefined;
336
344
  });
337
345
  }
@@ -351,7 +359,7 @@ export class ChronicleClient implements IChronicleClient {
351
359
  this._logger.warn(message, {
352
360
  attempt,
353
361
  delayMs,
354
- error: this.toErrorMessage(error)
362
+ error
355
363
  });
356
364
 
357
365
  await new Promise(resolve => setTimeout(resolve, delayMs));
@@ -437,9 +445,9 @@ export class ChronicleClient implements IChronicleClient {
437
445
  }
438
446
 
439
447
  private startConnectionWatchdog(): void {
440
- this._watchdogHandle = setInterval(() => {
448
+ this._watchdogHandle = runInBackgroundContext(() => setInterval(() => {
441
449
  void this.runHealthCheck().catch(error => this.backgroundConnectionFailed('watchdog-health-check', error));
442
- }, ChronicleClient._healthCheckIntervalMs);
450
+ }, ChronicleClient._healthCheckIntervalMs));
443
451
 
444
452
  this._watchdogHandle.unref?.();
445
453
  }
@@ -477,7 +485,7 @@ export class ChronicleClient implements IChronicleClient {
477
485
  }
478
486
 
479
487
  void this.reconnect(reason, error).catch(failure => this.backgroundConnectionFailed(reason, failure));
480
- });
488
+ }, {}, this.options.logger);
481
489
 
482
490
  await keepAlive.start(
483
491
  {
@@ -511,7 +519,7 @@ export class ChronicleClient implements IChronicleClient {
511
519
  this.failConnection(error instanceof Error ? error : new Error(String(error)));
512
520
  this._logger.error('Background connection recovery failed; create a new client after correcting the server', {
513
521
  reason,
514
- error: this.toErrorMessage(error)
522
+ error
515
523
  });
516
524
  }
517
525
 
@@ -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 { diag } from '@opentelemetry/api';
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';
@@ -21,6 +24,8 @@ import { IConstraints } from './events/constraints/IConstraints.js';
21
24
  import { Projections } from './projections/Projections.js';
22
25
  import { IProjections } from './projections/IProjections.js';
23
26
  import { Reactors } from './reactors/Reactors.js';
27
+ import { getReactorEventTypes } from './reactors/ReactorDispatcher.js';
28
+ import { getEventHandlers } from './observation/getEventHandlers.js';
24
29
  import type { ReactorResultHandler } from './reactors/ReactorResultHandler.js';
25
30
  import type { ClientArtifactsActivator } from './artifacts/ClientArtifactsActivator.js';
26
31
  import type { ReadModelNamingPolicy } from './readModels/ReadModelNamingPolicy.js';
@@ -31,7 +36,7 @@ import { IReadModels } from './readModels/IReadModels.js';
31
36
  import { ReadModels } from './readModels/ReadModels.js';
32
37
  import { EventSeeding } from './seeding/EventSeeding.js';
33
38
  import { IEventSeeding } from './seeding/IEventSeeding.js';
34
- import { ChronicleTracer } from './Tracing.js';
39
+ import { observeOperation } from './telemetry/observeOperation.js';
35
40
  import { DefaultClientArtifactsProvider } from './artifacts/DefaultClientArtifactsProvider.js';
36
41
  import type { IClientArtifactsProvider } from './artifacts/IClientArtifactsProvider.js';
37
42
  import { validateArtifactSchemas } from './artifacts/validateArtifactSchemas.js';
@@ -59,9 +64,7 @@ import { Observers } from './observation/Observers.js';
59
64
  * via gRPC using the provided {@link ChronicleConnection}.
60
65
  */
61
66
  export class EventStore implements IEventStore {
62
- private readonly _logger = diag.createComponentLogger({
63
- namespace: '@cratis/chronicle/EventStore'
64
- });
67
+ private readonly _logger: ReturnType<typeof createLogger>;
65
68
 
66
69
  readonly eventLog: IEventLog;
67
70
  readonly eventTypes: IEventTypes;
@@ -93,15 +96,17 @@ export class EventStore implements IEventStore {
93
96
  private readonly _artifacts: IClientArtifactsProvider = DefaultClientArtifactsProvider.default,
94
97
  reactorResultHandler?: ReactorResultHandler,
95
98
  artifactActivator?: ClientArtifactsActivator,
96
- readModelNamingPolicy?: ReadModelNamingPolicy
99
+ readModelNamingPolicy?: ReadModelNamingPolicy,
100
+ private readonly _telemetry?: ChronicleTelemetryOptions
97
101
  ) {
102
+ this._logger = createLogger('@cratis/chronicle/EventStore', _connection.logger);
98
103
  this.unitOfWorkManager = new UnitOfWorkManager(this);
99
104
 
100
105
  const artifacts = this._artifacts;
101
106
  this._constraints = new Constraints(name.value, _connection, artifacts);
102
107
  this.constraints = this._constraints;
103
108
  const resolveConstraintMessage = this._constraints.resolveMessageFor.bind(this._constraints);
104
- this.eventLog = new EventLog(name.value, namespace.value, _connection, this.unitOfWorkManager, resolveConstraintMessage);
109
+ this.eventLog = new EventLog(name.value, namespace.value, _connection, this.unitOfWorkManager, resolveConstraintMessage, _telemetry);
105
110
  this._sequences.set(EventSequenceId.eventLog.value, this.eventLog);
106
111
 
107
112
  this.eventTypes = new EventTypes(name.value, _connection, artifacts);
@@ -142,6 +147,12 @@ export class EventStore implements IEventStore {
142
147
  ]);
143
148
 
144
149
  validateArtifactSchemas(this._artifacts);
150
+ for (const type of this._artifacts.reactors) {
151
+ getReactorEventTypes(type, this._artifacts.eventTypes);
152
+ }
153
+ for (const type of this._artifacts.reducers) {
154
+ getEventHandlers(type, this._artifacts.eventTypes);
155
+ }
145
156
 
146
157
  this._logger.debug('Registering discovered artifacts', {
147
158
  eventStore: this.name.value,
@@ -180,7 +191,7 @@ export class EventStore implements IEventStore {
180
191
 
181
192
  const sequence = new EventSequence(
182
193
  id, this.name.value, this.namespace.value, this._connection, this.unitOfWorkManager,
183
- this._constraints.resolveMessageFor.bind(this._constraints)
194
+ this._constraints.resolveMessageFor.bind(this._constraints), this._telemetry
184
195
  );
185
196
  this._sequences.set(id.value, sequence);
186
197
  return sequence;
@@ -188,16 +199,15 @@ export class EventStore implements IEventStore {
188
199
 
189
200
  /** @inheritdoc */
190
201
  async getNamespaces(): Promise<EventStoreNamespaceName[]> {
191
- return ChronicleTracer.startActiveSpan('chronicle.event_store.get_namespaces', async span => {
192
- span.setAttribute('chronicle.event_store', this.name.value);
202
+ return observeOperation(WellKnownTelemetryNames.spans.getNamespaces, async span => {
203
+ setTelemetryAttribute(span, 'eventStore', this.name.value);
193
204
  try {
194
205
  const response = await this._connection.namespaces.allNamespaces({ EventStore: this.name.value });
195
206
  const result = ensureQuerySuccess('get namespaces', response).map(namespace => new EventStoreNamespaceName(namespace.Name));
196
207
  span.setStatus({ code: SpanStatusCode.OK });
197
208
  return result;
198
209
  } catch (error) {
199
- span.setStatus({ code: SpanStatusCode.ERROR, message: String(error) });
200
- span.recordException(error as Error);
210
+ recordSafeException(span, error);
201
211
  throw error;
202
212
  } finally {
203
213
  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
- * The name of the Chronicle metrics instrumentation library.
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
- * The OpenTelemetry meter used by the Chronicle client for all metric instrumentation.
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
- * Pre-built metric instruments for all Chronicle client operations.
24
- * These are created once and shared across all invocations.
25
- */
26
- export const ChronicleMetrics = {
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
- * Counts the number of batch-append operations performed on an event sequence.
40
- * Each call to appendMany counts as one batch regardless of how many events it contains.
41
- *
42
- * Attributes: `chronicle.event_store`, `chronicle.namespace`,
43
- * `chronicle.event_sequence_id`, `chronicle.events_count`
44
- */
45
- batchAppendsPerformed: ChronicleMeter.createCounter('chronicle.events.batch_appends', {
46
- description: 'Number of batch-append operations performed on an event sequence.',
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
- * Counts the number of event store retrieval operations.
52
- *
53
- * Attributes: `chronicle.event_store`, `chronicle.namespace`
54
- */
55
- eventStoreRetrievals: ChronicleMeter.createCounter('chronicle.client.event_store_retrievals', {
56
- description: 'Number of event store retrieval operations.',
57
- unit: '{operation}'
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
- * Measures the duration of append operations in milliseconds.
62
- *
63
- * Attributes: `chronicle.event_store`, `chronicle.namespace`,
64
- * `chronicle.event_sequence_id`, `chronicle.event_type_id`
65
- */
66
- appendDuration: ChronicleMeter.createHistogram('chronicle.events.append_duration', {
67
- description: 'Duration of individual event append operations.',
68
- unit: 'ms',
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
- * Measures the duration of batch-append operations in milliseconds.
76
- *
77
- * Attributes: `chronicle.event_store`, `chronicle.namespace`,
78
- * `chronicle.event_sequence_id`, `chronicle.events_count`
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
- * Counts the number of append constraint violations encountered.
90
- *
91
- * Attributes: `chronicle.event_store`, `chronicle.namespace`,
92
- * `chronicle.event_sequence_id`
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
- * Counts the number of append errors encountered.
101
- *
102
- * Attributes: `chronicle.event_store`, `chronicle.namespace`,
103
- * `chronicle.event_sequence_id`
104
- */
105
- appendErrors: ChronicleMeter.createCounter('chronicle.events.append_errors', {
106
- description: 'Number of errors encountered during event appends.',
107
- unit: '{error}'
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 = '@cratis/chronicle';
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);