@contractspec/lib.observability 3.7.5 → 3.7.7

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.
@@ -147,241 +147,6 @@ class RootCauseAnalyzer {
147
147
  }
148
148
  }
149
149
 
150
- // src/tracing/core.ts
151
- import {
152
- SpanStatusCode,
153
- trace
154
- } from "@opentelemetry/api";
155
- var DEFAULT_TRACER_NAME = "@contractspec/lib.observability";
156
- function getTracer(name = DEFAULT_TRACER_NAME) {
157
- return trace.getTracer(name);
158
- }
159
- async function traceAsync(name, fn, tracerName) {
160
- const tracer = getTracer(tracerName);
161
- return tracer.startActiveSpan(name, async (span) => {
162
- try {
163
- const result = await fn(span);
164
- span.setStatus({ code: SpanStatusCode.OK });
165
- return result;
166
- } catch (error) {
167
- span.recordException(error);
168
- span.setStatus({
169
- code: SpanStatusCode.ERROR,
170
- message: error instanceof Error ? error.message : String(error)
171
- });
172
- throw error;
173
- } finally {
174
- span.end();
175
- }
176
- });
177
- }
178
- function traceSync(name, fn, tracerName) {
179
- const tracer = getTracer(tracerName);
180
- return tracer.startActiveSpan(name, (span) => {
181
- try {
182
- const result = fn(span);
183
- span.setStatus({ code: SpanStatusCode.OK });
184
- return result;
185
- } catch (error) {
186
- span.recordException(error);
187
- span.setStatus({
188
- code: SpanStatusCode.ERROR,
189
- message: error instanceof Error ? error.message : String(error)
190
- });
191
- throw error;
192
- } finally {
193
- span.end();
194
- }
195
- });
196
- }
197
-
198
- // src/tracing/model-selection.span.ts
199
- async function traceModelSelection(fn, input) {
200
- const startMs = performance.now();
201
- return traceAsync("model.selection", async (span) => {
202
- const result = await fn();
203
- const durationMs = performance.now() - startMs;
204
- span.setAttribute("model.selected", input.modelId);
205
- span.setAttribute("model.provider", input.providerKey);
206
- span.setAttribute("model.score", input.score);
207
- span.setAttribute("model.alternatives_count", input.alternativesCount);
208
- span.setAttribute("model.selection_duration_ms", durationMs);
209
- span.setAttribute("model.reason", input.reason);
210
- if (input.dimension) {
211
- span.setAttribute("model.dimension", input.dimension);
212
- }
213
- if (input.constraints) {
214
- span.setAttribute("model.constraints", JSON.stringify(input.constraints));
215
- }
216
- return result;
217
- });
218
- }
219
- // src/telemetry/model-selection-telemetry.ts
220
- class ModelSelectionTelemetry {
221
- provider;
222
- eventName;
223
- constructor(provider, options) {
224
- this.provider = provider;
225
- this.eventName = options?.eventName ?? "$model_selection";
226
- }
227
- async trackSelection(distinctId, properties) {
228
- await this.provider.capture({
229
- distinctId,
230
- event: this.eventName,
231
- timestamp: new Date,
232
- properties: {
233
- $model_id: properties.modelId,
234
- $model_provider: properties.providerKey,
235
- $model_score: properties.score,
236
- $model_dimension: properties.dimension ?? null,
237
- $model_reason: properties.reason,
238
- $model_alternatives_count: properties.alternativesCount,
239
- $model_cost_estimate_input: properties.costEstimateInput ?? null,
240
- $model_cost_estimate_output: properties.costEstimateOutput ?? null,
241
- $model_selection_duration_ms: properties.selectionDurationMs ?? null
242
- }
243
- });
244
- }
245
- }
246
-
247
- // src/metrics/index.ts
248
- import {
249
- metrics
250
- } from "@opentelemetry/api";
251
- var DEFAULT_METER_NAME = "@contractspec/lib.observability";
252
- function getMeter(name = DEFAULT_METER_NAME) {
253
- return metrics.getMeter(name);
254
- }
255
- function createCounter(name, description, meterName) {
256
- return getMeter(meterName).createCounter(name, { description });
257
- }
258
- function createUpDownCounter(name, description, meterName) {
259
- return getMeter(meterName).createUpDownCounter(name, { description });
260
- }
261
- function createHistogram(name, description, meterName) {
262
- return getMeter(meterName).createHistogram(name, { description });
263
- }
264
- var standardMetrics = {
265
- httpRequests: createCounter("http_requests_total", "Total HTTP requests"),
266
- httpDuration: createHistogram("http_request_duration_seconds", "HTTP request duration"),
267
- operationErrors: createCounter("operation_errors_total", "Total operation errors"),
268
- workflowDuration: createHistogram("workflow_duration_seconds", "Workflow execution duration")
269
- };
270
-
271
- // src/logging/index.ts
272
- import { trace as trace2, context } from "@opentelemetry/api";
273
-
274
- class Logger {
275
- serviceName;
276
- constructor(serviceName) {
277
- this.serviceName = serviceName;
278
- }
279
- log(level, message, meta = {}) {
280
- const span = trace2.getSpan(context.active());
281
- const traceId = span?.spanContext().traceId;
282
- const spanId = span?.spanContext().spanId;
283
- const entry = {
284
- timestamp: new Date().toISOString(),
285
- service: this.serviceName,
286
- level,
287
- message,
288
- traceId,
289
- spanId,
290
- ...meta
291
- };
292
- console.log(JSON.stringify(entry));
293
- }
294
- debug(message, meta) {
295
- this.log("debug", message, meta);
296
- }
297
- info(message, meta) {
298
- this.log("info", message, meta);
299
- }
300
- warn(message, meta) {
301
- this.log("warn", message, meta);
302
- }
303
- error(message, meta) {
304
- this.log("error", message, meta);
305
- }
306
- }
307
- var logger = new Logger(process.env.OTEL_SERVICE_NAME || "unknown-service");
308
-
309
- // src/tracing/middleware.ts
310
- function createTracingMiddleware(options = {}) {
311
- return async (req, next) => {
312
- const method = req.method;
313
- const url = new URL(req.url);
314
- const path = url.pathname;
315
- standardMetrics.httpRequests.add(1, { method, path });
316
- const startTime = performance.now();
317
- return traceAsync(`HTTP ${method} ${path}`, async (span) => {
318
- span.setAttribute("http.method", method);
319
- span.setAttribute("http.url", req.url);
320
- try {
321
- const response = await next();
322
- span.setAttribute("http.status_code", response.status);
323
- const duration = (performance.now() - startTime) / 1000;
324
- standardMetrics.httpDuration.record(duration, {
325
- method,
326
- path,
327
- status: response.status.toString()
328
- });
329
- emitTelemetrySample({
330
- req,
331
- res: response,
332
- span,
333
- success: true,
334
- durationMs: duration * 1000,
335
- options
336
- });
337
- return response;
338
- } catch (error) {
339
- standardMetrics.operationErrors.add(1, { method, path });
340
- emitTelemetrySample({
341
- req,
342
- span,
343
- success: false,
344
- durationMs: performance.now() - startTime,
345
- error,
346
- options
347
- });
348
- throw error;
349
- }
350
- });
351
- };
352
- }
353
- function emitTelemetrySample({
354
- req,
355
- res,
356
- span,
357
- success,
358
- durationMs,
359
- error,
360
- options
361
- }) {
362
- if (!options.onSample || !options.resolveOperation)
363
- return;
364
- const operation = options.resolveOperation({ req, res });
365
- if (!operation)
366
- return;
367
- const sample = {
368
- operation,
369
- durationMs,
370
- success,
371
- timestamp: new Date,
372
- errorCode: !success && error instanceof Error ? error.name : success ? undefined : "unknown",
373
- tenantId: options.tenantResolver?.(req),
374
- actorId: options.actorResolver?.(req),
375
- traceId: span.spanContext().traceId,
376
- metadata: {
377
- method: req.method,
378
- path: new URL(req.url).pathname,
379
- status: res?.status
380
- }
381
- };
382
- options.onSample(sample);
383
- }
384
-
385
150
  // src/intent/aggregator.ts
386
151
  var DEFAULT_WINDOW_MS = 15 * 60 * 1000;
387
152
 
@@ -400,11 +165,11 @@ class IntentAggregator {
400
165
  const minTimestamp = now.getTime() - this.windowMs;
401
166
  const windowSamples = this.samples.filter((sample) => sample.timestamp.getTime() >= minTimestamp);
402
167
  this.samples.length = 0;
403
- const metrics2 = this.aggregateMetrics(windowSamples);
168
+ const metrics = this.aggregateMetrics(windowSamples);
404
169
  const sequences = this.buildSequences(windowSamples);
405
170
  const timestamps = windowSamples.map((sample) => sample.timestamp.getTime());
406
171
  return {
407
- metrics: metrics2,
172
+ metrics,
408
173
  sequences,
409
174
  sampleCount: windowSamples.length,
410
175
  windowStart: timestamps.length ? new Date(Math.min(...timestamps)) : undefined,
@@ -619,6 +384,68 @@ class IntentDetector {
619
384
  }
620
385
  }
621
386
 
387
+ // src/logging/index.ts
388
+ import { context, trace } from "@opentelemetry/api";
389
+
390
+ class Logger {
391
+ serviceName;
392
+ constructor(serviceName) {
393
+ this.serviceName = serviceName;
394
+ }
395
+ log(level, message, meta = {}) {
396
+ const span = trace.getSpan(context.active());
397
+ const traceId = span?.spanContext().traceId;
398
+ const spanId = span?.spanContext().spanId;
399
+ const entry = {
400
+ timestamp: new Date().toISOString(),
401
+ service: this.serviceName,
402
+ level,
403
+ message,
404
+ traceId,
405
+ spanId,
406
+ ...meta
407
+ };
408
+ console.log(JSON.stringify(entry));
409
+ }
410
+ debug(message, meta) {
411
+ this.log("debug", message, meta);
412
+ }
413
+ info(message, meta) {
414
+ this.log("info", message, meta);
415
+ }
416
+ warn(message, meta) {
417
+ this.log("warn", message, meta);
418
+ }
419
+ error(message, meta) {
420
+ this.log("error", message, meta);
421
+ }
422
+ }
423
+ var logger = new Logger(process.env.OTEL_SERVICE_NAME || "unknown-service");
424
+
425
+ // src/metrics/index.ts
426
+ import {
427
+ metrics
428
+ } from "@opentelemetry/api";
429
+ var DEFAULT_METER_NAME = "@contractspec/lib.observability";
430
+ function getMeter(name = DEFAULT_METER_NAME) {
431
+ return metrics.getMeter(name);
432
+ }
433
+ function createCounter(name, description, meterName) {
434
+ return getMeter(meterName).createCounter(name, { description });
435
+ }
436
+ function createUpDownCounter(name, description, meterName) {
437
+ return getMeter(meterName).createUpDownCounter(name, { description });
438
+ }
439
+ function createHistogram(name, description, meterName) {
440
+ return getMeter(meterName).createHistogram(name, { description });
441
+ }
442
+ var standardMetrics = {
443
+ httpRequests: createCounter("http_requests_total", "Total HTTP requests"),
444
+ httpDuration: createHistogram("http_request_duration_seconds", "HTTP request duration"),
445
+ operationErrors: createCounter("operation_errors_total", "Total operation errors"),
446
+ workflowDuration: createHistogram("workflow_duration_seconds", "Workflow execution duration")
447
+ };
448
+
622
449
  // src/pipeline/evolution-pipeline.ts
623
450
  import { EventEmitter } from "node:events";
624
451
  class EvolutionPipeline {
@@ -726,71 +553,41 @@ class LifecycleKpiPipeline {
726
553
  if (previous !== undefined) {
727
554
  this.stageUpDownCounter.add(-1, {
728
555
  stage: getStageLabel(previous),
729
- tenantId
730
- });
731
- }
732
- this.stageUpDownCounter.add(1, { stage: getStageLabel(stage), tenantId });
733
- this.currentStageByTenant.set(tenantId, stage);
734
- this.emitter.emit("event", {
735
- type: "stage.changed",
736
- payload: { tenantId, previousStage: previous, nextStage: stage }
737
- });
738
- }
739
- }
740
-
741
- // src/telemetry/posthog-telemetry.ts
742
- class PosthogTelemetryProvider {
743
- provider;
744
- eventPrefix;
745
- includeMetadata;
746
- constructor(provider, options = {}) {
747
- this.provider = provider;
748
- this.eventPrefix = options.eventPrefix ?? "observability";
749
- this.includeMetadata = options.includeMetadata ?? false;
750
- }
751
- async captureSample(sample) {
752
- await this.provider.capture({
753
- distinctId: sample.actorId ?? sample.tenantId ?? "unknown",
754
- event: `${this.eventPrefix}.operation`,
755
- timestamp: sample.timestamp,
756
- properties: {
757
- operation: sample.operation.name,
758
- version: sample.operation.version,
759
- durationMs: sample.durationMs,
760
- success: sample.success,
761
- errorCode: sample.errorCode ?? null,
762
- tenantId: sample.tenantId ?? null,
763
- traceId: sample.traceId ?? null,
764
- ...this.includeMetadata && sample.metadata ? { metadata: sample.metadata } : {}
765
- }
556
+ tenantId
557
+ });
558
+ }
559
+ this.stageUpDownCounter.add(1, { stage: getStageLabel(stage), tenantId });
560
+ this.currentStageByTenant.set(tenantId, stage);
561
+ this.emitter.emit("event", {
562
+ type: "stage.changed",
563
+ payload: { tenantId, previousStage: previous, nextStage: stage }
766
564
  });
767
565
  }
768
- async captureSnapshot(snapshot) {
566
+ }
567
+
568
+ // src/telemetry/model-selection-telemetry.ts
569
+ class ModelSelectionTelemetry {
570
+ provider;
571
+ eventName;
572
+ constructor(provider, options) {
573
+ this.provider = provider;
574
+ this.eventName = options?.eventName ?? "$model_selection";
575
+ }
576
+ async trackSelection(distinctId, properties) {
769
577
  await this.provider.capture({
770
- distinctId: "system",
771
- event: `${this.eventPrefix}.window`,
772
- timestamp: snapshot.windowEnd ?? new Date,
578
+ distinctId,
579
+ event: this.eventName,
580
+ timestamp: new Date,
773
581
  properties: {
774
- sampleCount: snapshot.sampleCount,
775
- metricsCount: snapshot.metrics.length,
776
- sequencesCount: snapshot.sequences.length,
777
- windowStart: snapshot.windowStart?.toISOString() ?? null,
778
- windowEnd: snapshot.windowEnd?.toISOString() ?? null,
779
- ...this.includeMetadata ? {
780
- metrics: snapshot.metrics.map((metric) => ({
781
- operation: metric.operation.name,
782
- version: metric.operation.version,
783
- totalCalls: metric.totalCalls,
784
- successRate: metric.successRate,
785
- errorRate: metric.errorRate,
786
- averageLatencyMs: metric.averageLatencyMs,
787
- p95LatencyMs: metric.p95LatencyMs,
788
- p99LatencyMs: metric.p99LatencyMs,
789
- maxLatencyMs: metric.maxLatencyMs,
790
- topErrors: metric.topErrors
791
- })),
792
- sequences: snapshot.sequences
793
- } : {}
582
+ $model_id: properties.modelId,
583
+ $model_provider: properties.providerKey,
584
+ $model_score: properties.score,
585
+ $model_dimension: properties.dimension ?? null,
586
+ $model_reason: properties.reason,
587
+ $model_alternatives_count: properties.alternativesCount,
588
+ $model_cost_estimate_input: properties.costEstimateInput ?? null,
589
+ $model_cost_estimate_output: properties.costEstimateOutput ?? null,
590
+ $model_selection_duration_ms: properties.selectionDurationMs ?? null
794
591
  }
795
592
  });
796
593
  }
@@ -1101,6 +898,209 @@ function toDate(value) {
1101
898
  function isRecord(value) {
1102
899
  return typeof value === "object" && value !== null;
1103
900
  }
901
+
902
+ // src/telemetry/posthog-telemetry.ts
903
+ class PosthogTelemetryProvider {
904
+ provider;
905
+ eventPrefix;
906
+ includeMetadata;
907
+ constructor(provider, options = {}) {
908
+ this.provider = provider;
909
+ this.eventPrefix = options.eventPrefix ?? "observability";
910
+ this.includeMetadata = options.includeMetadata ?? false;
911
+ }
912
+ async captureSample(sample) {
913
+ await this.provider.capture({
914
+ distinctId: sample.actorId ?? sample.tenantId ?? "unknown",
915
+ event: `${this.eventPrefix}.operation`,
916
+ timestamp: sample.timestamp,
917
+ properties: {
918
+ operation: sample.operation.name,
919
+ version: sample.operation.version,
920
+ durationMs: sample.durationMs,
921
+ success: sample.success,
922
+ errorCode: sample.errorCode ?? null,
923
+ tenantId: sample.tenantId ?? null,
924
+ traceId: sample.traceId ?? null,
925
+ ...this.includeMetadata && sample.metadata ? { metadata: sample.metadata } : {}
926
+ }
927
+ });
928
+ }
929
+ async captureSnapshot(snapshot) {
930
+ await this.provider.capture({
931
+ distinctId: "system",
932
+ event: `${this.eventPrefix}.window`,
933
+ timestamp: snapshot.windowEnd ?? new Date,
934
+ properties: {
935
+ sampleCount: snapshot.sampleCount,
936
+ metricsCount: snapshot.metrics.length,
937
+ sequencesCount: snapshot.sequences.length,
938
+ windowStart: snapshot.windowStart?.toISOString() ?? null,
939
+ windowEnd: snapshot.windowEnd?.toISOString() ?? null,
940
+ ...this.includeMetadata ? {
941
+ metrics: snapshot.metrics.map((metric) => ({
942
+ operation: metric.operation.name,
943
+ version: metric.operation.version,
944
+ totalCalls: metric.totalCalls,
945
+ successRate: metric.successRate,
946
+ errorRate: metric.errorRate,
947
+ averageLatencyMs: metric.averageLatencyMs,
948
+ p95LatencyMs: metric.p95LatencyMs,
949
+ p99LatencyMs: metric.p99LatencyMs,
950
+ maxLatencyMs: metric.maxLatencyMs,
951
+ topErrors: metric.topErrors
952
+ })),
953
+ sequences: snapshot.sequences
954
+ } : {}
955
+ }
956
+ });
957
+ }
958
+ }
959
+
960
+ // src/tracing/core.ts
961
+ import {
962
+ SpanStatusCode,
963
+ trace as trace2
964
+ } from "@opentelemetry/api";
965
+ var DEFAULT_TRACER_NAME = "@contractspec/lib.observability";
966
+ function getTracer(name = DEFAULT_TRACER_NAME) {
967
+ return trace2.getTracer(name);
968
+ }
969
+ async function traceAsync(name, fn, tracerName) {
970
+ const tracer = getTracer(tracerName);
971
+ return tracer.startActiveSpan(name, async (span) => {
972
+ try {
973
+ const result = await fn(span);
974
+ span.setStatus({ code: SpanStatusCode.OK });
975
+ return result;
976
+ } catch (error) {
977
+ span.recordException(error);
978
+ span.setStatus({
979
+ code: SpanStatusCode.ERROR,
980
+ message: error instanceof Error ? error.message : String(error)
981
+ });
982
+ throw error;
983
+ } finally {
984
+ span.end();
985
+ }
986
+ });
987
+ }
988
+ function traceSync(name, fn, tracerName) {
989
+ const tracer = getTracer(tracerName);
990
+ return tracer.startActiveSpan(name, (span) => {
991
+ try {
992
+ const result = fn(span);
993
+ span.setStatus({ code: SpanStatusCode.OK });
994
+ return result;
995
+ } catch (error) {
996
+ span.recordException(error);
997
+ span.setStatus({
998
+ code: SpanStatusCode.ERROR,
999
+ message: error instanceof Error ? error.message : String(error)
1000
+ });
1001
+ throw error;
1002
+ } finally {
1003
+ span.end();
1004
+ }
1005
+ });
1006
+ }
1007
+
1008
+ // src/tracing/model-selection.span.ts
1009
+ async function traceModelSelection(fn, input) {
1010
+ const startMs = performance.now();
1011
+ return traceAsync("model.selection", async (span) => {
1012
+ const result = await fn();
1013
+ const durationMs = performance.now() - startMs;
1014
+ span.setAttribute("model.selected", input.modelId);
1015
+ span.setAttribute("model.provider", input.providerKey);
1016
+ span.setAttribute("model.score", input.score);
1017
+ span.setAttribute("model.alternatives_count", input.alternativesCount);
1018
+ span.setAttribute("model.selection_duration_ms", durationMs);
1019
+ span.setAttribute("model.reason", input.reason);
1020
+ if (input.dimension) {
1021
+ span.setAttribute("model.dimension", input.dimension);
1022
+ }
1023
+ if (input.constraints) {
1024
+ span.setAttribute("model.constraints", JSON.stringify(input.constraints));
1025
+ }
1026
+ return result;
1027
+ });
1028
+ }
1029
+ // src/tracing/middleware.ts
1030
+ function createTracingMiddleware(options = {}) {
1031
+ return async (req, next) => {
1032
+ const method = req.method;
1033
+ const url = new URL(req.url);
1034
+ const path = url.pathname;
1035
+ standardMetrics.httpRequests.add(1, { method, path });
1036
+ const startTime = performance.now();
1037
+ return traceAsync(`HTTP ${method} ${path}`, async (span) => {
1038
+ span.setAttribute("http.method", method);
1039
+ span.setAttribute("http.url", req.url);
1040
+ try {
1041
+ const response = await next();
1042
+ span.setAttribute("http.status_code", response.status);
1043
+ const duration = (performance.now() - startTime) / 1000;
1044
+ standardMetrics.httpDuration.record(duration, {
1045
+ method,
1046
+ path,
1047
+ status: response.status.toString()
1048
+ });
1049
+ emitTelemetrySample({
1050
+ req,
1051
+ res: response,
1052
+ span,
1053
+ success: true,
1054
+ durationMs: duration * 1000,
1055
+ options
1056
+ });
1057
+ return response;
1058
+ } catch (error) {
1059
+ standardMetrics.operationErrors.add(1, { method, path });
1060
+ emitTelemetrySample({
1061
+ req,
1062
+ span,
1063
+ success: false,
1064
+ durationMs: performance.now() - startTime,
1065
+ error,
1066
+ options
1067
+ });
1068
+ throw error;
1069
+ }
1070
+ });
1071
+ };
1072
+ }
1073
+ function emitTelemetrySample({
1074
+ req,
1075
+ res,
1076
+ span,
1077
+ success,
1078
+ durationMs,
1079
+ error,
1080
+ options
1081
+ }) {
1082
+ if (!options.onSample || !options.resolveOperation)
1083
+ return;
1084
+ const operation = options.resolveOperation({ req, res });
1085
+ if (!operation)
1086
+ return;
1087
+ const sample = {
1088
+ operation,
1089
+ durationMs,
1090
+ success,
1091
+ timestamp: new Date,
1092
+ errorCode: !success && error instanceof Error ? error.name : success ? undefined : "unknown",
1093
+ tenantId: options.tenantResolver?.(req),
1094
+ actorId: options.actorResolver?.(req),
1095
+ traceId: span.spanContext().traceId,
1096
+ metadata: {
1097
+ method: req.method,
1098
+ path: new URL(req.url).pathname,
1099
+ status: res?.status
1100
+ }
1101
+ };
1102
+ options.onSample(sample);
1103
+ }
1104
1104
  export {
1105
1105
  traceSync,
1106
1106
  traceModelSelection,
@@ -1,5 +1,5 @@
1
1
  // src/logging/index.ts
2
- import { trace, context } from "@opentelemetry/api";
2
+ import { context, trace } from "@opentelemetry/api";
3
3
 
4
4
  class Logger {
5
5
  serviceName;
@@ -1,3 +1,27 @@
1
+ // src/metrics/index.ts
2
+ import {
3
+ metrics
4
+ } from "@opentelemetry/api";
5
+ var DEFAULT_METER_NAME = "@contractspec/lib.observability";
6
+ function getMeter(name = DEFAULT_METER_NAME) {
7
+ return metrics.getMeter(name);
8
+ }
9
+ function createCounter(name, description, meterName) {
10
+ return getMeter(meterName).createCounter(name, { description });
11
+ }
12
+ function createUpDownCounter(name, description, meterName) {
13
+ return getMeter(meterName).createUpDownCounter(name, { description });
14
+ }
15
+ function createHistogram(name, description, meterName) {
16
+ return getMeter(meterName).createHistogram(name, { description });
17
+ }
18
+ var standardMetrics = {
19
+ httpRequests: createCounter("http_requests_total", "Total HTTP requests"),
20
+ httpDuration: createHistogram("http_request_duration_seconds", "HTTP request duration"),
21
+ operationErrors: createCounter("operation_errors_total", "Total operation errors"),
22
+ workflowDuration: createHistogram("workflow_duration_seconds", "Workflow execution duration")
23
+ };
24
+
1
25
  // src/tracing/core.ts
2
26
  import {
3
27
  SpanStatusCode,
@@ -67,30 +91,6 @@ async function traceModelSelection(fn, input) {
67
91
  return result;
68
92
  });
69
93
  }
70
- // src/metrics/index.ts
71
- import {
72
- metrics
73
- } from "@opentelemetry/api";
74
- var DEFAULT_METER_NAME = "@contractspec/lib.observability";
75
- function getMeter(name = DEFAULT_METER_NAME) {
76
- return metrics.getMeter(name);
77
- }
78
- function createCounter(name, description, meterName) {
79
- return getMeter(meterName).createCounter(name, { description });
80
- }
81
- function createUpDownCounter(name, description, meterName) {
82
- return getMeter(meterName).createUpDownCounter(name, { description });
83
- }
84
- function createHistogram(name, description, meterName) {
85
- return getMeter(meterName).createHistogram(name, { description });
86
- }
87
- var standardMetrics = {
88
- httpRequests: createCounter("http_requests_total", "Total HTTP requests"),
89
- httpDuration: createHistogram("http_request_duration_seconds", "HTTP request duration"),
90
- operationErrors: createCounter("operation_errors_total", "Total operation errors"),
91
- workflowDuration: createHistogram("workflow_duration_seconds", "Workflow execution duration")
92
- };
93
-
94
94
  // src/tracing/middleware.ts
95
95
  function createTracingMiddleware(options = {}) {
96
96
  return async (req, next) => {