@maroonedsoftware/telemetry 0.0.0-stage → 0.1.1

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 (44) hide show
  1. package/AGENTS.md +179 -0
  2. package/LICENSE +21 -0
  3. package/README.md +124 -2
  4. package/dist/chunk-7QVYU63E.js +7 -0
  5. package/dist/chunk-7QVYU63E.js.map +1 -0
  6. package/dist/chunk-E7OXUL3D.js +25 -0
  7. package/dist/chunk-E7OXUL3D.js.map +1 -0
  8. package/dist/finished.span.d.ts +44 -0
  9. package/dist/finished.span.d.ts.map +1 -0
  10. package/dist/index.d.ts +8 -0
  11. package/dist/index.d.ts.map +1 -0
  12. package/dist/index.js +426 -0
  13. package/dist/index.js.map +1 -0
  14. package/dist/kysely.d.ts +2 -0
  15. package/dist/kysely.d.ts.map +1 -0
  16. package/dist/kysely.js +237 -0
  17. package/dist/kysely.js.map +1 -0
  18. package/dist/metric.aggregate.d.ts +41 -0
  19. package/dist/metric.aggregate.d.ts.map +1 -0
  20. package/dist/metric.bucket.d.ts +25 -0
  21. package/dist/metric.bucket.d.ts.map +1 -0
  22. package/dist/metric.labels.d.ts +18 -0
  23. package/dist/metric.labels.d.ts.map +1 -0
  24. package/dist/metric.resolution.d.ts +19 -0
  25. package/dist/metric.resolution.d.ts.map +1 -0
  26. package/dist/metrics.recorder.d.ts +96 -0
  27. package/dist/metrics.recorder.d.ts.map +1 -0
  28. package/dist/metrics.store.d.ts +143 -0
  29. package/dist/metrics.store.d.ts.map +1 -0
  30. package/dist/otlp.d.ts +4 -0
  31. package/dist/otlp.d.ts.map +1 -0
  32. package/dist/otlp.export.d.ts +8 -0
  33. package/dist/otlp.export.d.ts.map +1 -0
  34. package/dist/otlp.ids.d.ts +16 -0
  35. package/dist/otlp.ids.d.ts.map +1 -0
  36. package/dist/otlp.js +237 -0
  37. package/dist/otlp.js.map +1 -0
  38. package/dist/otlp.metrics.bridge.d.ts +64 -0
  39. package/dist/otlp.metrics.bridge.d.ts.map +1 -0
  40. package/dist/otlp.metrics.receiver.d.ts +79 -0
  41. package/dist/otlp.metrics.receiver.d.ts.map +1 -0
  42. package/dist/otlp.span.bridge.d.ts +44 -0
  43. package/dist/otlp.span.bridge.d.ts.map +1 -0
  44. package/package.json +103 -3
@@ -0,0 +1,8 @@
1
+ import { ExportResult } from '@opentelemetry/core';
2
+ /**
3
+ * Runs an OTel exporter's callback-style `export` as a promise that rejects on failure.
4
+ *
5
+ * @param run - Calls the exporter with the given callback.
6
+ */
7
+ export declare const exportAsPromise: (run: (done: (result: ExportResult) => void) => void) => Promise<void>;
8
+ //# sourceMappingURL=otlp.export.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"otlp.export.d.ts","sourceRoot":"","sources":["../src/otlp.export.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAoB,MAAM,qBAAqB,CAAC;AAErE;;;;GAIG;AACH,eAAO,MAAM,eAAe,GAAI,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,EAAE,YAAY,KAAK,IAAI,KAAK,IAAI,KAAG,OAAO,CAAC,IAAI,CAS9F,CAAC"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * An OTLP trace id (32 lowercase hex characters) for an app's own trace id.
3
+ *
4
+ * An id already in that form is kept as it is. Anything else is hashed, so the same app id always
5
+ * maps to the same trace id, and spans exported in different batches still land in one trace.
6
+ *
7
+ * @param id - The app's trace id.
8
+ */
9
+ export declare const otlpTraceId: (id: string) => string;
10
+ /**
11
+ * An OTLP span id (16 lowercase hex characters) for an app's own span id. Same rules as {@link otlpTraceId}.
12
+ *
13
+ * @param id - The app's span id.
14
+ */
15
+ export declare const otlpSpanId: (id: string) => string;
16
+ //# sourceMappingURL=otlp.ids.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"otlp.ids.d.ts","sourceRoot":"","sources":["../src/otlp.ids.ts"],"names":[],"mappings":"AAOA;;;;;;;GAOG;AACH,eAAO,MAAM,WAAW,GAAI,IAAI,MAAM,KAAG,MAAkD,CAAC;AAE5F;;;;GAIG;AACH,eAAO,MAAM,UAAU,GAAI,IAAI,MAAM,KAAG,MAAiD,CAAC"}
package/dist/otlp.js ADDED
@@ -0,0 +1,237 @@
1
+ import {
2
+ __name
3
+ } from "./chunk-7QVYU63E.js";
4
+
5
+ // src/otlp.ids.ts
6
+ import { createHash } from "crypto";
7
+ var TRACE_ID = /^[0-9a-f]{32}$/;
8
+ var SPAN_ID = /^[0-9a-f]{16}$/;
9
+ var hexOf = /* @__PURE__ */ __name((id, length) => createHash("sha256").update(id).digest("hex").slice(0, length), "hexOf");
10
+ var otlpTraceId = /* @__PURE__ */ __name((id) => TRACE_ID.test(id) ? id : hexOf(id, 32), "otlpTraceId");
11
+ var otlpSpanId = /* @__PURE__ */ __name((id) => SPAN_ID.test(id) ? id : hexOf(id, 16), "otlpSpanId");
12
+
13
+ // src/otlp.metrics.bridge.ts
14
+ import { ValueType } from "@opentelemetry/api";
15
+ import { millisToHrTime } from "@opentelemetry/core";
16
+ import { defaultResource } from "@opentelemetry/resources";
17
+ import { AggregationTemporality, DataPointType } from "@opentelemetry/sdk-metrics";
18
+
19
+ // src/otlp.export.ts
20
+ import { ExportResultCode } from "@opentelemetry/core";
21
+ var exportAsPromise = /* @__PURE__ */ __name((run) => new Promise((resolve, reject) => {
22
+ run((result) => {
23
+ if (result.code === ExportResultCode.SUCCESS) {
24
+ resolve();
25
+ } else {
26
+ reject(result.error ?? new Error("OTLP export failed"));
27
+ }
28
+ });
29
+ }), "exportAsPromise");
30
+
31
+ // src/otlp.metrics.bridge.ts
32
+ var MINUTE_MS = 6e4;
33
+ var OtlpMetricsBridge = class {
34
+ static {
35
+ __name(this, "OtlpMetricsBridge");
36
+ }
37
+ exporter;
38
+ resource;
39
+ scope;
40
+ kindOf;
41
+ /**
42
+ * @param options - The exporter, resource, scope and kind picker.
43
+ */
44
+ constructor(options) {
45
+ this.exporter = options.exporter;
46
+ this.resource = options.resource ?? defaultResource();
47
+ this.scope = options.scope ?? "@maroonedsoftware/telemetry";
48
+ this.kindOf = options.kindOf ?? (() => "gauge");
49
+ }
50
+ /**
51
+ * Exports the buckets, one OTel metric per name.
52
+ *
53
+ * @param buckets - What a recorder drained.
54
+ * @throws Whatever the exporter reports when it fails.
55
+ */
56
+ async export(buckets) {
57
+ if (buckets.length === 0) {
58
+ return;
59
+ }
60
+ const byName = /* @__PURE__ */ new Map();
61
+ for (const bucket of buckets) {
62
+ byName.set(bucket.name, [
63
+ ...byName.get(bucket.name) ?? [],
64
+ bucket
65
+ ]);
66
+ }
67
+ const metrics = [
68
+ ...byName.entries()
69
+ ].map(([name, group]) => this.metricOf(name, group));
70
+ await exportAsPromise((done) => this.exporter.export({
71
+ resource: this.resource,
72
+ scopeMetrics: [
73
+ {
74
+ scope: {
75
+ name: this.scope
76
+ },
77
+ metrics
78
+ }
79
+ ]
80
+ }, done));
81
+ }
82
+ /** Flushes and closes the exporter. */
83
+ async shutdown() {
84
+ await this.exporter.shutdown();
85
+ }
86
+ metricOf(name, buckets) {
87
+ const descriptor = {
88
+ name,
89
+ description: "",
90
+ unit: "",
91
+ valueType: ValueType.DOUBLE
92
+ };
93
+ const timing = /* @__PURE__ */ __name((bucket) => ({
94
+ startTime: millisToHrTime(bucket.start.toMillis()),
95
+ endTime: millisToHrTime(bucket.start.toMillis() + MINUTE_MS),
96
+ attributes: {
97
+ ...bucket.labels
98
+ }
99
+ }), "timing");
100
+ switch (this.kindOf(name)) {
101
+ case "counter":
102
+ return {
103
+ descriptor,
104
+ aggregationTemporality: AggregationTemporality.DELTA,
105
+ dataPointType: DataPointType.SUM,
106
+ isMonotonic: true,
107
+ dataPoints: buckets.map((bucket) => ({
108
+ ...timing(bucket),
109
+ value: bucket.aggregate.sum
110
+ }))
111
+ };
112
+ case "histogram":
113
+ return {
114
+ descriptor,
115
+ aggregationTemporality: AggregationTemporality.DELTA,
116
+ dataPointType: DataPointType.HISTOGRAM,
117
+ dataPoints: buckets.map((bucket) => ({
118
+ ...timing(bucket),
119
+ value: {
120
+ buckets: {
121
+ boundaries: [],
122
+ counts: [
123
+ bucket.aggregate.count
124
+ ]
125
+ },
126
+ count: bucket.aggregate.count,
127
+ sum: bucket.aggregate.sum,
128
+ min: bucket.aggregate.min,
129
+ max: bucket.aggregate.max
130
+ }
131
+ }))
132
+ };
133
+ case "gauge":
134
+ return {
135
+ descriptor,
136
+ aggregationTemporality: AggregationTemporality.CUMULATIVE,
137
+ dataPointType: DataPointType.GAUGE,
138
+ dataPoints: buckets.map((bucket) => ({
139
+ ...timing(bucket),
140
+ value: bucket.aggregate.last
141
+ }))
142
+ };
143
+ }
144
+ }
145
+ };
146
+
147
+ // src/otlp.span.bridge.ts
148
+ import { SpanKind, SpanStatusCode, TraceFlags } from "@opentelemetry/api";
149
+ import { hrTimeDuration, millisToHrTime as millisToHrTime2 } from "@opentelemetry/core";
150
+ import { defaultResource as defaultResource2 } from "@opentelemetry/resources";
151
+ var OtlpSpanBridge = class {
152
+ static {
153
+ __name(this, "OtlpSpanBridge");
154
+ }
155
+ exporter;
156
+ resource;
157
+ scope;
158
+ /**
159
+ * @param options - The exporter, resource and scope.
160
+ */
161
+ constructor(options) {
162
+ this.exporter = options.exporter;
163
+ this.resource = options.resource ?? defaultResource2();
164
+ this.scope = options.scope ?? "@maroonedsoftware/telemetry";
165
+ }
166
+ /**
167
+ * Exports the spans.
168
+ *
169
+ * @param spans - Finished work, in any order.
170
+ * @throws Whatever the exporter reports when it fails.
171
+ */
172
+ async export(spans) {
173
+ if (spans.length === 0) {
174
+ return;
175
+ }
176
+ await exportAsPromise((done) => this.exporter.export(spans.map((span) => this.readableOf(span)), done));
177
+ }
178
+ /** Flushes and closes the exporter. */
179
+ async shutdown() {
180
+ await this.exporter.shutdown();
181
+ }
182
+ readableOf(span) {
183
+ const traceId = otlpTraceId(span.traceId);
184
+ const context = {
185
+ traceId,
186
+ spanId: otlpSpanId(span.spanId),
187
+ traceFlags: TraceFlags.SAMPLED
188
+ };
189
+ const startTime = millisToHrTime2(span.start.toMillis());
190
+ const endTime = millisToHrTime2(span.end.toMillis());
191
+ return {
192
+ name: span.name,
193
+ kind: SpanKind.INTERNAL,
194
+ spanContext: /* @__PURE__ */ __name(() => context, "spanContext"),
195
+ parentSpanContext: span.parentSpanId === void 0 ? void 0 : {
196
+ traceId,
197
+ spanId: otlpSpanId(span.parentSpanId),
198
+ traceFlags: TraceFlags.SAMPLED
199
+ },
200
+ startTime,
201
+ endTime,
202
+ duration: hrTimeDuration(startTime, endTime),
203
+ status: span.ok ? {
204
+ code: SpanStatusCode.OK
205
+ } : {
206
+ code: SpanStatusCode.ERROR,
207
+ message: span.error
208
+ },
209
+ attributes: {
210
+ ...span.attributes
211
+ },
212
+ links: (span.links ?? []).map((link) => ({
213
+ context: {
214
+ traceId: otlpTraceId(link.traceId),
215
+ spanId: otlpSpanId(link.spanId),
216
+ traceFlags: TraceFlags.SAMPLED
217
+ }
218
+ })),
219
+ events: [],
220
+ ended: true,
221
+ resource: this.resource,
222
+ instrumentationScope: {
223
+ name: this.scope
224
+ },
225
+ droppedAttributesCount: 0,
226
+ droppedEventsCount: 0,
227
+ droppedLinksCount: 0
228
+ };
229
+ }
230
+ };
231
+ export {
232
+ OtlpMetricsBridge,
233
+ OtlpSpanBridge,
234
+ otlpSpanId,
235
+ otlpTraceId
236
+ };
237
+ //# sourceMappingURL=otlp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/otlp.ids.ts","../src/otlp.metrics.bridge.ts","../src/otlp.export.ts","../src/otlp.span.bridge.ts"],"sourcesContent":["import { createHash } from 'node:crypto';\n\nconst TRACE_ID = /^[0-9a-f]{32}$/;\nconst SPAN_ID = /^[0-9a-f]{16}$/;\n\nconst hexOf = (id: string, length: number): string => createHash('sha256').update(id).digest('hex').slice(0, length);\n\n/**\n * An OTLP trace id (32 lowercase hex characters) for an app's own trace id.\n *\n * An id already in that form is kept as it is. Anything else is hashed, so the same app id always\n * maps to the same trace id, and spans exported in different batches still land in one trace.\n *\n * @param id - The app's trace id.\n */\nexport const otlpTraceId = (id: string): string => (TRACE_ID.test(id) ? id : hexOf(id, 32));\n\n/**\n * An OTLP span id (16 lowercase hex characters) for an app's own span id. Same rules as {@link otlpTraceId}.\n *\n * @param id - The app's span id.\n */\nexport const otlpSpanId = (id: string): string => (SPAN_ID.test(id) ? id : hexOf(id, 16));\n","import { ValueType } from '@opentelemetry/api';\nimport { millisToHrTime } from '@opentelemetry/core';\nimport { defaultResource, Resource } from '@opentelemetry/resources';\nimport { AggregationTemporality, DataPointType, MetricData, PushMetricExporter } from '@opentelemetry/sdk-metrics';\nimport { MetricBucket } from './metric.bucket.js';\nimport { exportAsPromise } from './otlp.export.js';\n\n/**\n * How a metric is sent over OTLP. The stored aggregate is the same for all three; this only says\n * which part of it a collector should see.\n *\n * - `gauge` sends `last`.\n * - `counter` sends `sum` as a monotonic delta sum.\n * - `histogram` sends `count`, `sum`, `min` and `max` as a delta histogram with no bucket boundaries.\n */\nexport type MetricKind = 'gauge' | 'counter' | 'histogram';\n\n/**\n * How an {@link OtlpMetricsBridge} is built.\n */\nexport interface OtlpMetricsBridgeOptions {\n /** Where the metrics go: an `OTLPMetricExporter`, or `InMemoryMetricExporter` in tests. */\n exporter: PushMetricExporter;\n /** Says who is sending. Defaults to the SDK's default resource. */\n resource?: Resource;\n /** The instrumentation scope name. Defaults to `@maroonedsoftware/telemetry`. */\n scope?: string;\n /** Picks each metric's kind by name. Defaults to `gauge` for everything. */\n kindOf?: (name: string) => MetricKind;\n}\n\nconst MINUTE_MS = 60_000;\n\n/**\n * Sends drained minute buckets to an OTLP exporter as already-aggregated data.\n *\n * It does not go through a `MeterProvider`: the buckets are already aggregates, and recording them\n * into SDK instruments would aggregate them a second time. Each bucket becomes one data point\n * spanning its minute, with delta temporality, so a collector that wants cumulative series (a\n * Prometheus exporter, say) needs its `deltatocumulative` processor.\n *\n * @example\n * ```typescript\n * const bridge = new OtlpMetricsBridge({\n * exporter: new OTLPMetricExporter({ url }),\n * resource: resourceFromAttributes({ 'service.name': 'my.app' }),\n * kindOf: name => (name.endsWith('.ms') ? 'histogram' : 'gauge'),\n * });\n * await bridge.export(buckets);\n * ```\n */\nexport class OtlpMetricsBridge {\n private readonly exporter: PushMetricExporter;\n private readonly resource: Resource;\n private readonly scope: string;\n private readonly kindOf: (name: string) => MetricKind;\n\n /**\n * @param options - The exporter, resource, scope and kind picker.\n */\n constructor(options: OtlpMetricsBridgeOptions) {\n this.exporter = options.exporter;\n this.resource = options.resource ?? defaultResource();\n this.scope = options.scope ?? '@maroonedsoftware/telemetry';\n this.kindOf = options.kindOf ?? (() => 'gauge');\n }\n\n /**\n * Exports the buckets, one OTel metric per name.\n *\n * @param buckets - What a recorder drained.\n * @throws Whatever the exporter reports when it fails.\n */\n async export(buckets: readonly MetricBucket[]): Promise<void> {\n if (buckets.length === 0) {\n return;\n }\n const byName = new Map<string, MetricBucket[]>();\n for (const bucket of buckets) {\n byName.set(bucket.name, [...(byName.get(bucket.name) ?? []), bucket]);\n }\n const metrics = [...byName.entries()].map(([name, group]) => this.metricOf(name, group));\n await exportAsPromise(done => this.exporter.export({ resource: this.resource, scopeMetrics: [{ scope: { name: this.scope }, metrics }] }, done));\n }\n\n /** Flushes and closes the exporter. */\n async shutdown(): Promise<void> {\n await this.exporter.shutdown();\n }\n\n private metricOf(name: string, buckets: MetricBucket[]): MetricData {\n const descriptor = { name, description: '', unit: '', valueType: ValueType.DOUBLE };\n const timing = (bucket: MetricBucket) => ({\n startTime: millisToHrTime(bucket.start.toMillis()),\n endTime: millisToHrTime(bucket.start.toMillis() + MINUTE_MS),\n attributes: { ...bucket.labels },\n });\n switch (this.kindOf(name)) {\n case 'counter':\n return {\n descriptor,\n aggregationTemporality: AggregationTemporality.DELTA,\n dataPointType: DataPointType.SUM,\n isMonotonic: true,\n dataPoints: buckets.map(bucket => ({ ...timing(bucket), value: bucket.aggregate.sum })),\n };\n case 'histogram':\n return {\n descriptor,\n aggregationTemporality: AggregationTemporality.DELTA,\n dataPointType: DataPointType.HISTOGRAM,\n dataPoints: buckets.map(bucket => ({\n ...timing(bucket),\n value: {\n buckets: { boundaries: [], counts: [bucket.aggregate.count] },\n count: bucket.aggregate.count,\n sum: bucket.aggregate.sum,\n min: bucket.aggregate.min,\n max: bucket.aggregate.max,\n },\n })),\n };\n case 'gauge':\n return {\n descriptor,\n aggregationTemporality: AggregationTemporality.CUMULATIVE,\n dataPointType: DataPointType.GAUGE,\n dataPoints: buckets.map(bucket => ({ ...timing(bucket), value: bucket.aggregate.last })),\n };\n }\n }\n}\n","import { ExportResult, ExportResultCode } from '@opentelemetry/core';\n\n/**\n * Runs an OTel exporter's callback-style `export` as a promise that rejects on failure.\n *\n * @param run - Calls the exporter with the given callback.\n */\nexport const exportAsPromise = (run: (done: (result: ExportResult) => void) => void): Promise<void> =>\n new Promise((resolve, reject) => {\n run(result => {\n if (result.code === ExportResultCode.SUCCESS) {\n resolve();\n } else {\n reject(result.error ?? new Error('OTLP export failed'));\n }\n });\n });\n","import { SpanKind, SpanStatusCode, TraceFlags } from '@opentelemetry/api';\nimport { hrTimeDuration, millisToHrTime } from '@opentelemetry/core';\nimport { defaultResource, Resource } from '@opentelemetry/resources';\nimport { ReadableSpan, SpanExporter } from '@opentelemetry/sdk-trace';\nimport { FinishedSpan } from './finished.span.js';\nimport { otlpSpanId, otlpTraceId } from './otlp.ids.js';\nimport { exportAsPromise } from './otlp.export.js';\n\n/**\n * How an {@link OtlpSpanBridge} is built.\n */\nexport interface OtlpSpanBridgeOptions {\n /** Where the spans go: an `OTLPTraceExporter`, or `InMemorySpanExporter` in tests. */\n exporter: SpanExporter;\n /** Says who is sending. Defaults to the SDK's default resource. */\n resource?: Resource;\n /** The instrumentation scope name. Defaults to `@maroonedsoftware/telemetry`. */\n scope?: string;\n}\n\n/**\n * Sends {@link FinishedSpan}s to an OTel span exporter.\n *\n * The spans are built as finished `ReadableSpan`s with the times the app recorded, rather than\n * started and ended on a live tracer, so work timed before this bridge existed (or in a process\n * with no tracer at all) exports with its real start and end. Ids are derived with\n * {@link otlpTraceId} and {@link otlpSpanId}, so the same app id always lands in the same trace.\n *\n * The caller batches: hand it whatever accumulated since the last call.\n */\nexport class OtlpSpanBridge {\n private readonly exporter: SpanExporter;\n private readonly resource: Resource;\n private readonly scope: string;\n\n /**\n * @param options - The exporter, resource and scope.\n */\n constructor(options: OtlpSpanBridgeOptions) {\n this.exporter = options.exporter;\n this.resource = options.resource ?? defaultResource();\n this.scope = options.scope ?? '@maroonedsoftware/telemetry';\n }\n\n /**\n * Exports the spans.\n *\n * @param spans - Finished work, in any order.\n * @throws Whatever the exporter reports when it fails.\n */\n async export(spans: readonly FinishedSpan[]): Promise<void> {\n if (spans.length === 0) {\n return;\n }\n await exportAsPromise(done =>\n this.exporter.export(\n spans.map(span => this.readableOf(span)),\n done,\n ),\n );\n }\n\n /** Flushes and closes the exporter. */\n async shutdown(): Promise<void> {\n await this.exporter.shutdown();\n }\n\n private readableOf(span: FinishedSpan): ReadableSpan {\n const traceId = otlpTraceId(span.traceId);\n const context = { traceId, spanId: otlpSpanId(span.spanId), traceFlags: TraceFlags.SAMPLED };\n const startTime = millisToHrTime(span.start.toMillis());\n const endTime = millisToHrTime(span.end.toMillis());\n return {\n name: span.name,\n kind: SpanKind.INTERNAL,\n spanContext: () => context,\n parentSpanContext:\n span.parentSpanId === undefined ? undefined : { traceId, spanId: otlpSpanId(span.parentSpanId), traceFlags: TraceFlags.SAMPLED },\n startTime,\n endTime,\n duration: hrTimeDuration(startTime, endTime),\n status: span.ok ? { code: SpanStatusCode.OK } : { code: SpanStatusCode.ERROR, message: span.error },\n attributes: { ...span.attributes },\n links: (span.links ?? []).map(link => ({\n context: { traceId: otlpTraceId(link.traceId), spanId: otlpSpanId(link.spanId), traceFlags: TraceFlags.SAMPLED },\n })),\n events: [],\n ended: true,\n resource: this.resource,\n instrumentationScope: { name: this.scope },\n droppedAttributesCount: 0,\n droppedEventsCount: 0,\n droppedLinksCount: 0,\n };\n }\n}\n"],"mappings":"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","names":["createHash","TRACE_ID","SPAN_ID","hexOf","id","length","createHash","update","digest","slice","otlpTraceId","test","otlpSpanId","ValueType","millisToHrTime","defaultResource","AggregationTemporality","DataPointType","ExportResultCode","exportAsPromise","run","Promise","resolve","reject","result","code","ExportResultCode","SUCCESS","error","Error","MINUTE_MS","OtlpMetricsBridge","exporter","resource","scope","kindOf","options","defaultResource","export","buckets","length","byName","Map","bucket","set","name","get","metrics","entries","map","group","metricOf","exportAsPromise","done","scopeMetrics","shutdown","descriptor","description","unit","valueType","ValueType","DOUBLE","timing","startTime","millisToHrTime","start","toMillis","endTime","attributes","labels","aggregationTemporality","AggregationTemporality","DELTA","dataPointType","DataPointType","SUM","isMonotonic","dataPoints","value","aggregate","sum","HISTOGRAM","boundaries","counts","count","min","max","CUMULATIVE","GAUGE","last","SpanKind","SpanStatusCode","TraceFlags","hrTimeDuration","millisToHrTime","defaultResource","OtlpSpanBridge","exporter","resource","scope","options","defaultResource","export","spans","length","exportAsPromise","done","map","span","readableOf","shutdown","traceId","otlpTraceId","context","spanId","otlpSpanId","traceFlags","TraceFlags","SAMPLED","startTime","millisToHrTime","start","toMillis","endTime","end","name","kind","SpanKind","INTERNAL","spanContext","parentSpanContext","parentSpanId","undefined","duration","hrTimeDuration","status","ok","code","SpanStatusCode","OK","ERROR","message","error","attributes","links","link","events","ended","instrumentationScope","droppedAttributesCount","droppedEventsCount","droppedLinksCount"]}
@@ -0,0 +1,64 @@
1
+ import { Resource } from '@opentelemetry/resources';
2
+ import { PushMetricExporter } from '@opentelemetry/sdk-metrics';
3
+ import { MetricBucket } from './metric.bucket.js';
4
+ /**
5
+ * How a metric is sent over OTLP. The stored aggregate is the same for all three; this only says
6
+ * which part of it a collector should see.
7
+ *
8
+ * - `gauge` sends `last`.
9
+ * - `counter` sends `sum` as a monotonic delta sum.
10
+ * - `histogram` sends `count`, `sum`, `min` and `max` as a delta histogram with no bucket boundaries.
11
+ */
12
+ export type MetricKind = 'gauge' | 'counter' | 'histogram';
13
+ /**
14
+ * How an {@link OtlpMetricsBridge} is built.
15
+ */
16
+ export interface OtlpMetricsBridgeOptions {
17
+ /** Where the metrics go: an `OTLPMetricExporter`, or `InMemoryMetricExporter` in tests. */
18
+ exporter: PushMetricExporter;
19
+ /** Says who is sending. Defaults to the SDK's default resource. */
20
+ resource?: Resource;
21
+ /** The instrumentation scope name. Defaults to `@maroonedsoftware/telemetry`. */
22
+ scope?: string;
23
+ /** Picks each metric's kind by name. Defaults to `gauge` for everything. */
24
+ kindOf?: (name: string) => MetricKind;
25
+ }
26
+ /**
27
+ * Sends drained minute buckets to an OTLP exporter as already-aggregated data.
28
+ *
29
+ * It does not go through a `MeterProvider`: the buckets are already aggregates, and recording them
30
+ * into SDK instruments would aggregate them a second time. Each bucket becomes one data point
31
+ * spanning its minute, with delta temporality, so a collector that wants cumulative series (a
32
+ * Prometheus exporter, say) needs its `deltatocumulative` processor.
33
+ *
34
+ * @example
35
+ * ```typescript
36
+ * const bridge = new OtlpMetricsBridge({
37
+ * exporter: new OTLPMetricExporter({ url }),
38
+ * resource: resourceFromAttributes({ 'service.name': 'my.app' }),
39
+ * kindOf: name => (name.endsWith('.ms') ? 'histogram' : 'gauge'),
40
+ * });
41
+ * await bridge.export(buckets);
42
+ * ```
43
+ */
44
+ export declare class OtlpMetricsBridge {
45
+ private readonly exporter;
46
+ private readonly resource;
47
+ private readonly scope;
48
+ private readonly kindOf;
49
+ /**
50
+ * @param options - The exporter, resource, scope and kind picker.
51
+ */
52
+ constructor(options: OtlpMetricsBridgeOptions);
53
+ /**
54
+ * Exports the buckets, one OTel metric per name.
55
+ *
56
+ * @param buckets - What a recorder drained.
57
+ * @throws Whatever the exporter reports when it fails.
58
+ */
59
+ export(buckets: readonly MetricBucket[]): Promise<void>;
60
+ /** Flushes and closes the exporter. */
61
+ shutdown(): Promise<void>;
62
+ private metricOf;
63
+ }
64
+ //# sourceMappingURL=otlp.metrics.bridge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"otlp.metrics.bridge.d.ts","sourceRoot":"","sources":["../src/otlp.metrics.bridge.ts"],"names":[],"mappings":"AAEA,OAAO,EAAmB,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACrE,OAAO,EAAqD,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AACnH,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAGlD;;;;;;;GAOG;AACH,MAAM,MAAM,UAAU,GAAG,OAAO,GAAG,SAAS,GAAG,WAAW,CAAC;AAE3D;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC,2FAA2F;IAC3F,QAAQ,EAAE,kBAAkB,CAAC;IAC7B,mEAAmE;IACnE,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,iFAAiF;IACjF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,4EAA4E;IAC5E,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,UAAU,CAAC;CACvC;AAID;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAqB;IAC9C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAW;IACpC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;IAC/B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA+B;IAEtD;;OAEG;gBACS,OAAO,EAAE,wBAAwB;IAO7C;;;;;OAKG;IACG,MAAM,CAAC,OAAO,EAAE,SAAS,YAAY,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAY7D,uCAAuC;IACjC,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAI/B,OAAO,CAAC,QAAQ;CAyCjB"}
@@ -0,0 +1,79 @@
1
+ import { DateTime } from 'luxon';
2
+ import { MetricBucket } from './metric.bucket.js';
3
+ /**
4
+ * Thrown when a body is not an OTLP metrics export at all. A body that is one but carries parts this
5
+ * receiver cannot use is not an error; those parts are counted in {@link OtlpReceiveResult}.
6
+ */
7
+ export declare class OtlpPayloadError extends Error {
8
+ constructor(message: string);
9
+ }
10
+ /**
11
+ * How an {@link OtlpMetricsReceiver} bounds what it keeps.
12
+ */
13
+ export interface OtlpMetricsReceiverOptions {
14
+ /** Distinct label sets kept per metric name. Further series are dropped. Defaults to 50. */
15
+ maxSeriesPerName?: number;
16
+ /** Distinct metric names kept. Further names are dropped. Defaults to 500. */
17
+ maxNames?: number;
18
+ }
19
+ /**
20
+ * What one {@link OtlpMetricsReceiver.receive} call produced.
21
+ */
22
+ export interface OtlpReceiveResult {
23
+ /** Minute buckets, ready for a store. */
24
+ buckets: MetricBucket[];
25
+ /** Data points dropped by the series or name cap. */
26
+ dropped: number;
27
+ /** Data points of kinds this receiver does not read (exponential histograms, summaries), or malformed. */
28
+ unsupported: number;
29
+ }
30
+ /**
31
+ * Turns OTLP/JSON metric exports (the body of `POST /v1/metrics` with `Content-Type: application/json`)
32
+ * into minute buckets.
33
+ *
34
+ * - A **gauge** point, or a **non-monotonic sum** (an up-down counter), is one observation of its value.
35
+ * - A **monotonic sum** contributes its increase. A delta point is the increase; a cumulative point is
36
+ * the difference from the previous point of the same series, so the first point of a series (and the
37
+ * first after the sender restarts, which shows as a new start time or a smaller total) only sets the
38
+ * baseline.
39
+ * - A **histogram** contributes its count and sum the same way, with `min` and `max` when a delta point
40
+ * carries them. A cumulative histogram's extremes cover the sender's whole life, so they are replaced
41
+ * by the interval's mean.
42
+ * - Exponential histograms and summaries are counted as unsupported.
43
+ *
44
+ * Labels are the point's attributes over the resource's `service.name`. Each name keeps at most
45
+ * `maxSeriesPerName` label sets and the receiver at most `maxNames` names, for its whole life: a
46
+ * sender that puts a request id in an attribute cannot grow the table without bound.
47
+ *
48
+ * Keep one instance per process. It holds the cumulative baselines, so a fresh instance costs every
49
+ * cumulative series one point.
50
+ */
51
+ export declare class OtlpMetricsReceiver {
52
+ private readonly maxSeriesPerName;
53
+ private readonly maxNames;
54
+ private readonly series;
55
+ private readonly cumulative;
56
+ /**
57
+ * @param options - The series and name caps.
58
+ */
59
+ constructor(options?: OtlpMetricsReceiverOptions);
60
+ /**
61
+ * Reads one export request.
62
+ *
63
+ * @param body - The parsed JSON body.
64
+ * @param now - Used for points with no timestamp. Defaults to now.
65
+ * @throws {@link OtlpPayloadError} when the body has no `resourceMetrics` array.
66
+ */
67
+ receive(body: unknown, now?: DateTime): OtlpReceiveResult;
68
+ /** Whether a series may be kept, registering it if it is new and there is room. */
69
+ private admit;
70
+ /**
71
+ * The increase of a cumulative series since its previous point, or `undefined` when this point only
72
+ * sets the baseline (first sight, a new start time, or a total that went backwards).
73
+ *
74
+ * @param sum - The point's running total.
75
+ * @param count - The point's running observation count, for a histogram; zero for a sum.
76
+ */
77
+ private increase;
78
+ }
79
+ //# sourceMappingURL=otlp.metrics.receiver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"otlp.metrics.receiver.d.ts","sourceRoot":"","sources":["../src/otlp.metrics.receiver.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAEjC,OAAO,EAAE,YAAY,EAAY,MAAM,oBAAoB,CAAC;AAG5D;;;GAGG;AACH,qBAAa,gBAAiB,SAAQ,KAAK;gBAC7B,OAAO,EAAE,MAAM;CAI5B;AAED;;GAEG;AACH,MAAM,WAAW,0BAA0B;IACzC,4FAA4F;IAC5F,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,8EAA8E;IAC9E,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,yCAAyC;IACzC,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,qDAAqD;IACrD,OAAO,EAAE,MAAM,CAAC;IAChB,0GAA0G;IAC1G,WAAW,EAAE,MAAM,CAAC;CACrB;AAoFD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;IAC1C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAkC;IACzD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAsC;IAEjE;;OAEG;gBACS,OAAO,GAAE,0BAA+B;IAKpD;;;;;;OAMG;IACH,OAAO,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,GAAE,QAAyB,GAAG,iBAAiB;IAwGzE,mFAAmF;IACnF,OAAO,CAAC,KAAK;IAmBb;;;;;;OAMG;IACH,OAAO,CAAC,QAAQ;CAQjB"}
@@ -0,0 +1,44 @@
1
+ import { Resource } from '@opentelemetry/resources';
2
+ import { SpanExporter } from '@opentelemetry/sdk-trace';
3
+ import { FinishedSpan } from './finished.span.js';
4
+ /**
5
+ * How an {@link OtlpSpanBridge} is built.
6
+ */
7
+ export interface OtlpSpanBridgeOptions {
8
+ /** Where the spans go: an `OTLPTraceExporter`, or `InMemorySpanExporter` in tests. */
9
+ exporter: SpanExporter;
10
+ /** Says who is sending. Defaults to the SDK's default resource. */
11
+ resource?: Resource;
12
+ /** The instrumentation scope name. Defaults to `@maroonedsoftware/telemetry`. */
13
+ scope?: string;
14
+ }
15
+ /**
16
+ * Sends {@link FinishedSpan}s to an OTel span exporter.
17
+ *
18
+ * The spans are built as finished `ReadableSpan`s with the times the app recorded, rather than
19
+ * started and ended on a live tracer, so work timed before this bridge existed (or in a process
20
+ * with no tracer at all) exports with its real start and end. Ids are derived with
21
+ * {@link otlpTraceId} and {@link otlpSpanId}, so the same app id always lands in the same trace.
22
+ *
23
+ * The caller batches: hand it whatever accumulated since the last call.
24
+ */
25
+ export declare class OtlpSpanBridge {
26
+ private readonly exporter;
27
+ private readonly resource;
28
+ private readonly scope;
29
+ /**
30
+ * @param options - The exporter, resource and scope.
31
+ */
32
+ constructor(options: OtlpSpanBridgeOptions);
33
+ /**
34
+ * Exports the spans.
35
+ *
36
+ * @param spans - Finished work, in any order.
37
+ * @throws Whatever the exporter reports when it fails.
38
+ */
39
+ export(spans: readonly FinishedSpan[]): Promise<void>;
40
+ /** Flushes and closes the exporter. */
41
+ shutdown(): Promise<void>;
42
+ private readableOf;
43
+ }
44
+ //# sourceMappingURL=otlp.span.bridge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"otlp.span.bridge.d.ts","sourceRoot":"","sources":["../src/otlp.span.bridge.ts"],"names":[],"mappings":"AAEA,OAAO,EAAmB,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACrE,OAAO,EAAgB,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACtE,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAIlD;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,sFAAsF;IACtF,QAAQ,EAAE,YAAY,CAAC;IACvB,mEAAmE;IACnE,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,iFAAiF;IACjF,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;;;GASG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAe;IACxC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAW;IACpC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;IAE/B;;OAEG;gBACS,OAAO,EAAE,qBAAqB;IAM1C;;;;;OAKG;IACG,MAAM,CAAC,KAAK,EAAE,SAAS,YAAY,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAY3D,uCAAuC;IACjC,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAI/B,OAAO,CAAC,UAAU;CA4BnB"}
package/package.json CHANGED
@@ -1,6 +1,106 @@
1
1
  {
2
2
  "name": "@maroonedsoftware/telemetry",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
3
+ "version": "0.1.1",
4
+ "description": "Minute-bucket metrics for ServerKit: an in-process recorder and gauge registry, a Kysely store with hourly rollups, and OpenTelemetry bridges.",
5
+ "author": {
6
+ "name": "Marooned Software",
7
+ "url": "https://github.com/MaroonedSoftware/serverkit"
8
+ },
9
+ "bugs": {
10
+ "url": "https://github.com/MaroonedSoftware/serverkit/issues"
11
+ },
12
+ "homepage": "https://github.com/MaroonedSoftware/serverkit/packages/telemetry#readme",
13
+ "keywords": [
14
+ "backend",
15
+ "metrics",
16
+ "telemetry",
17
+ "opentelemetry",
18
+ "otlp",
19
+ "serverkit",
20
+ "typescript"
21
+ ],
22
+ "repository": {
23
+ "type": "git",
24
+ "url": "git+https://github.com/MaroonedSoftware/serverkit.git"
25
+ },
26
+ "private": false,
27
+ "type": "module",
28
+ "main": "./dist/index.js",
29
+ "module": "./dist/index.js",
30
+ "types": "./dist/index.d.ts",
31
+ "exports": {
32
+ ".": {
33
+ "types": "./dist/index.d.ts",
34
+ "import": "./dist/index.js"
35
+ },
36
+ "./kysely": {
37
+ "types": "./dist/kysely.d.ts",
38
+ "import": "./dist/kysely.js"
39
+ },
40
+ "./otlp": {
41
+ "types": "./dist/otlp.d.ts",
42
+ "import": "./dist/otlp.js"
43
+ },
44
+ "./package.json": "./package.json"
45
+ },
46
+ "license": "MIT",
47
+ "files": [
48
+ "AGENTS.md",
49
+ "dist/**"
50
+ ],
51
+ "dependencies": {
52
+ "injectkit": "^1.7.1",
53
+ "luxon": "^3.7.2"
54
+ },
55
+ "peerDependencies": {
56
+ "@opentelemetry/api": "^1.9.0",
57
+ "@opentelemetry/core": "^2.12.0",
58
+ "@opentelemetry/resources": "^2.12.0",
59
+ "@opentelemetry/sdk-metrics": "^2.12.0",
60
+ "@opentelemetry/sdk-trace": "^2.12.0",
61
+ "kysely": "^0.29.5"
62
+ },
63
+ "peerDependenciesMeta": {
64
+ "@opentelemetry/api": {
65
+ "optional": true
66
+ },
67
+ "@opentelemetry/core": {
68
+ "optional": true
69
+ },
70
+ "@opentelemetry/resources": {
71
+ "optional": true
72
+ },
73
+ "@opentelemetry/sdk-metrics": {
74
+ "optional": true
75
+ },
76
+ "@opentelemetry/sdk-trace": {
77
+ "optional": true
78
+ },
79
+ "kysely": {
80
+ "optional": true
81
+ }
82
+ },
83
+ "devDependencies": {
84
+ "@opentelemetry/api": "^1.9.1",
85
+ "@opentelemetry/core": "^2.12.0",
86
+ "@opentelemetry/otlp-transformer": "^0.223.0",
87
+ "@opentelemetry/resources": "^2.12.0",
88
+ "@opentelemetry/sdk-metrics": "^2.12.0",
89
+ "@opentelemetry/sdk-trace": "^2.12.0",
90
+ "@types/luxon": "^3.7.5",
91
+ "kysely": "^0.29.5",
92
+ "@repo/config-eslint": "0.2.1",
93
+ "@repo/config-typescript": "0.1.0"
94
+ },
95
+ "engines": {
96
+ "node": ">=22"
97
+ },
98
+ "scripts": {
99
+ "build": "tsup src/index.ts src/kysely.ts src/otlp.ts --format esm --sourcemap && tsc --emitDeclarationOnly --declaration",
100
+ "build:ci": "eslint --max-warnings=0 && pnpm run build",
101
+ "lint": "eslint --fix",
102
+ "format": "prettier --write .",
103
+ "test": "vitest run",
104
+ "test:ci": "vitest run --coverage"
105
+ }
6
106
  }