autotel-hono 0.4.28 → 0.4.30
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +153 -196
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +39 -36
- package/dist/index.d.cts.map +1 -0
- package/dist/index.d.ts +39 -36
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +152 -194
- package/dist/index.js.map +1 -1
- package/package.json +7 -6
package/dist/index.cjs
CHANGED
|
@@ -1,213 +1,170 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
7.5,
|
|
26
|
-
10
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
let autotel = require("autotel");
|
|
3
|
+
let hono_factory = require("hono/factory");
|
|
4
|
+
let hono_route = require("hono/route");
|
|
5
|
+
//#region src/metrics.ts
|
|
6
|
+
/** OTel HTTP server metric names (stable convention names) */
|
|
7
|
+
const METRIC_HTTP_SERVER_REQUEST_DURATION = "http.server.request.duration";
|
|
8
|
+
const METRIC_HTTP_SERVER_ACTIVE_REQUESTS = "http.server.active_requests";
|
|
9
|
+
/** Recommended bucket boundaries for request duration (seconds) */
|
|
10
|
+
const HTTP_DURATION_BUCKETS = [
|
|
11
|
+
.005,
|
|
12
|
+
.01,
|
|
13
|
+
.025,
|
|
14
|
+
.05,
|
|
15
|
+
.075,
|
|
16
|
+
.1,
|
|
17
|
+
.25,
|
|
18
|
+
.5,
|
|
19
|
+
.75,
|
|
20
|
+
1,
|
|
21
|
+
2.5,
|
|
22
|
+
5,
|
|
23
|
+
7.5,
|
|
24
|
+
10
|
|
27
25
|
];
|
|
28
26
|
function createRequestDurationTracker(config) {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
advice: { explicitBucketBoundaries: HTTP_DURATION_BUCKETS }
|
|
39
|
-
}
|
|
40
|
-
);
|
|
41
|
-
return {
|
|
42
|
-
record(durationSeconds, attrs) {
|
|
43
|
-
histogram.record(durationSeconds, attrs);
|
|
44
|
-
}
|
|
45
|
-
};
|
|
27
|
+
if (config.captureRequestDuration === false) return { record: () => {} };
|
|
28
|
+
const histogram = config.meter.createHistogram(METRIC_HTTP_SERVER_REQUEST_DURATION, {
|
|
29
|
+
description: "Duration of HTTP server requests in seconds",
|
|
30
|
+
unit: "s",
|
|
31
|
+
advice: { explicitBucketBoundaries: HTTP_DURATION_BUCKETS }
|
|
32
|
+
});
|
|
33
|
+
return { record(durationSeconds, attrs) {
|
|
34
|
+
histogram.record(durationSeconds, attrs);
|
|
35
|
+
} };
|
|
46
36
|
}
|
|
47
37
|
function createActiveRequestsTracker(config) {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
increment(attrs) {
|
|
59
|
-
counter.add(1, attrs);
|
|
60
|
-
},
|
|
61
|
-
decrement(attrs) {
|
|
62
|
-
counter.add(-1, attrs);
|
|
63
|
-
}
|
|
64
|
-
};
|
|
38
|
+
if (config.captureActiveRequests === false) return;
|
|
39
|
+
const counter = config.meter.createUpDownCounter(METRIC_HTTP_SERVER_ACTIVE_REQUESTS, { description: "Number of active (in-flight) HTTP server requests" });
|
|
40
|
+
return {
|
|
41
|
+
increment(attrs) {
|
|
42
|
+
counter.add(1, attrs);
|
|
43
|
+
},
|
|
44
|
+
decrement(attrs) {
|
|
45
|
+
counter.add(-1, attrs);
|
|
46
|
+
}
|
|
47
|
+
};
|
|
65
48
|
}
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
49
|
+
//#endregion
|
|
50
|
+
//#region src/index.ts
|
|
51
|
+
const INSTRUMENTATION_SCOPE_NAME = "autotel-hono";
|
|
69
52
|
function now() {
|
|
70
|
-
|
|
71
|
-
return p?.now() ?? Date.now();
|
|
53
|
+
return globalThis.performance?.now() ?? Date.now();
|
|
72
54
|
}
|
|
73
55
|
function normalizeConfig(config = {}) {
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
56
|
+
const reqHeadersSrc = [...config.captureRequestHeaders ?? []];
|
|
57
|
+
const resHeadersSrc = [...config.captureResponseHeaders ?? []];
|
|
58
|
+
const requestHeaderSet = new Set(reqHeadersSrc.map((h) => h.toLowerCase()));
|
|
59
|
+
const responseHeaderSet = new Set(resHeadersSrc.map((h) => h.toLowerCase()));
|
|
60
|
+
return {
|
|
61
|
+
...config,
|
|
62
|
+
requestHeaderSet,
|
|
63
|
+
responseHeaderSet,
|
|
64
|
+
captureActiveRequests: config.captureActiveRequests ?? true,
|
|
65
|
+
captureRequestDuration: config.captureRequestDuration ?? true
|
|
66
|
+
};
|
|
85
67
|
}
|
|
86
68
|
function resolveTracer(config) {
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
config.tracerName ?? INSTRUMENTATION_SCOPE_NAME,
|
|
92
|
-
config.serviceVersion
|
|
93
|
-
);
|
|
94
|
-
}
|
|
95
|
-
return autotel.getTracer(config.tracerName ?? INSTRUMENTATION_SCOPE_NAME, config.serviceVersion);
|
|
69
|
+
if (config.disableTracing) return void 0;
|
|
70
|
+
if (config.tracer) return config.tracer;
|
|
71
|
+
if (config.tracerProvider) return config.tracerProvider.getTracer(config.tracerName ?? INSTRUMENTATION_SCOPE_NAME, config.serviceVersion);
|
|
72
|
+
return (0, autotel.getTracer)(config.tracerName ?? INSTRUMENTATION_SCOPE_NAME, config.serviceVersion);
|
|
96
73
|
}
|
|
97
74
|
function resolveMeter(config) {
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
INSTRUMENTATION_SCOPE_NAME,
|
|
102
|
-
config.serviceVersion
|
|
103
|
-
);
|
|
104
|
-
}
|
|
105
|
-
return autotel.getMeter();
|
|
75
|
+
if (config.meter) return config.meter;
|
|
76
|
+
if (config.meterProvider) return config.meterProvider.getMeter(INSTRUMENTATION_SCOPE_NAME, config.serviceVersion);
|
|
77
|
+
return (0, autotel.getMeter)();
|
|
106
78
|
}
|
|
107
79
|
function otel(userConfig = {}) {
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
try {
|
|
195
|
-
for (const [k, v] of Object.entries(deferredRequestHeaderAttributes)) {
|
|
196
|
-
span.setAttribute(k, v);
|
|
197
|
-
}
|
|
198
|
-
await next();
|
|
199
|
-
finalize(span, c.error);
|
|
200
|
-
} catch (error) {
|
|
201
|
-
finalize(span, error);
|
|
202
|
-
throw error;
|
|
203
|
-
} finally {
|
|
204
|
-
span.end(config.getTime?.());
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
);
|
|
208
|
-
});
|
|
80
|
+
const config = normalizeConfig(userConfig);
|
|
81
|
+
const tracer = resolveTracer(config);
|
|
82
|
+
const metricsConfig = {
|
|
83
|
+
meter: resolveMeter(config),
|
|
84
|
+
captureRequestDuration: config.captureRequestDuration,
|
|
85
|
+
captureActiveRequests: config.captureActiveRequests
|
|
86
|
+
};
|
|
87
|
+
const requestDuration = createRequestDurationTracker(metricsConfig);
|
|
88
|
+
const activeReqs = createActiveRequestsTracker(metricsConfig);
|
|
89
|
+
const spanName = (c) => config.spanNameFactory?.(c) ?? `${c.req.method} ${(0, hono_route.routePath)(c)}`;
|
|
90
|
+
return (0, hono_factory.createMiddleware)(async (c, next) => {
|
|
91
|
+
const method = c.req.method;
|
|
92
|
+
const stableAttrs = {
|
|
93
|
+
[autotel.HTTPAttributes.requestMethod]: method,
|
|
94
|
+
[autotel.ServiceAttributes.name]: config.serviceName,
|
|
95
|
+
[autotel.ServiceAttributes.version]: config.serviceVersion
|
|
96
|
+
};
|
|
97
|
+
activeReqs?.increment(stableAttrs);
|
|
98
|
+
const startTime = now();
|
|
99
|
+
const deferredRequestHeaderAttributes = {};
|
|
100
|
+
const reqHeaders = c.req.raw.headers;
|
|
101
|
+
for (const [rawName, value] of reqHeaders.entries()) {
|
|
102
|
+
const name = rawName.toLowerCase();
|
|
103
|
+
if (config.requestHeaderSet.has(name)) deferredRequestHeaderAttributes[(0, autotel.httpRequestHeaderAttribute)(name)] = typeof value === "string" ? value : value[0] ?? "";
|
|
104
|
+
}
|
|
105
|
+
const finalize = (span, error) => {
|
|
106
|
+
try {
|
|
107
|
+
const status = c.res.status;
|
|
108
|
+
if (span) {
|
|
109
|
+
for (const [name, value] of c.res.headers.entries()) {
|
|
110
|
+
const lower = name.toLowerCase();
|
|
111
|
+
if (config.responseHeaderSet.has(lower)) span.setAttribute((0, autotel.httpResponseHeaderAttribute)(lower), value);
|
|
112
|
+
}
|
|
113
|
+
span.setAttribute(autotel.HTTPAttributes.responseStatusCode, status);
|
|
114
|
+
if (status >= 500) span.setStatus({ code: autotel.SpanStatusCode.ERROR });
|
|
115
|
+
if (error) {
|
|
116
|
+
try {
|
|
117
|
+
span.recordException(error);
|
|
118
|
+
} catch {}
|
|
119
|
+
span.setStatus({ code: autotel.SpanStatusCode.ERROR });
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
} finally {
|
|
123
|
+
activeReqs?.decrement(stableAttrs);
|
|
124
|
+
span?.setAttribute(autotel.HTTPAttributes.route, (0, hono_route.routePath)(c));
|
|
125
|
+
span?.updateName(spanName(c));
|
|
126
|
+
const durationSeconds = (now() - startTime) / 1e3;
|
|
127
|
+
requestDuration.record(durationSeconds, {
|
|
128
|
+
...stableAttrs,
|
|
129
|
+
[autotel.HTTPAttributes.route]: (0, hono_route.routePath)(c),
|
|
130
|
+
[autotel.HTTPAttributes.responseStatusCode]: c.res.status
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
if (!tracer) {
|
|
135
|
+
try {
|
|
136
|
+
await next();
|
|
137
|
+
finalize();
|
|
138
|
+
} catch (error) {
|
|
139
|
+
finalize(void 0, error);
|
|
140
|
+
throw error;
|
|
141
|
+
}
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
const parent = autotel.propagation.extract(autotel.context.active(), c.req.header());
|
|
145
|
+
return tracer.startActiveSpan(spanName(c), {
|
|
146
|
+
kind: autotel.SpanKind.SERVER,
|
|
147
|
+
startTime: config.getTime?.(),
|
|
148
|
+
attributes: {
|
|
149
|
+
...stableAttrs,
|
|
150
|
+
[autotel.URLAttributes.full]: c.req.url,
|
|
151
|
+
[autotel.HTTPAttributes.route]: (0, hono_route.routePath)(c)
|
|
152
|
+
}
|
|
153
|
+
}, parent, async (span) => {
|
|
154
|
+
try {
|
|
155
|
+
for (const [k, v] of Object.entries(deferredRequestHeaderAttributes)) span.setAttribute(k, v);
|
|
156
|
+
await next();
|
|
157
|
+
finalize(span, c.error);
|
|
158
|
+
} catch (error) {
|
|
159
|
+
finalize(span, error);
|
|
160
|
+
throw error;
|
|
161
|
+
} finally {
|
|
162
|
+
span.end(config.getTime?.());
|
|
163
|
+
}
|
|
164
|
+
});
|
|
165
|
+
});
|
|
209
166
|
}
|
|
210
|
-
|
|
167
|
+
//#endregion
|
|
211
168
|
exports.otel = otel;
|
|
212
|
-
|
|
169
|
+
|
|
213
170
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/metrics.ts","../src/index.ts"],"names":["getTracer","getMeter","routePath","createMiddleware","HTTPAttributes","ServiceAttributes","httpRequestHeaderAttribute","httpResponseHeaderAttribute","SpanStatusCode","propagation","otelContext","SpanKind","URLAttributes"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * HTTP server metrics per OTel semantic conventions.\n *\n * Lazy-initialized request duration histogram and active-requests up/down counter.\n */\n\ntype AttributeValue = string | number | boolean | undefined;\nexport type Attributes = Record<string, AttributeValue>;\n\ntype Histogram = {\n record: (value: number, attrs?: Attributes) => void;\n};\n\ntype UpDownCounter = {\n add: (value: number, attrs?: Attributes) => void;\n};\n\nexport type Meter = {\n createHistogram: (\n name: string,\n options?: {\n description?: string;\n unit?: string;\n advice?: { explicitBucketBoundaries?: number[] };\n },\n ) => Histogram;\n createUpDownCounter: (\n name: string,\n options?: {\n description?: string;\n },\n ) => UpDownCounter;\n};\n\n/** OTel HTTP server metric names (stable convention names) */\nconst METRIC_HTTP_SERVER_REQUEST_DURATION = 'http.server.request.duration';\nconst METRIC_HTTP_SERVER_ACTIVE_REQUESTS = 'http.server.active_requests';\n\n/** Recommended bucket boundaries for request duration (seconds) */\nconst HTTP_DURATION_BUCKETS = [\n 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10,\n];\n\nexport type HttpMetricsConfig = {\n meter: Meter;\n captureRequestDuration?: boolean;\n captureActiveRequests?: boolean;\n};\n\nexport function createRequestDurationTracker(config: HttpMetricsConfig): {\n record: (durationSeconds: number, attrs: Attributes) => void;\n} {\n if (config.captureRequestDuration === false) {\n return { record: () => {} };\n }\n const histogram = config.meter.createHistogram(\n METRIC_HTTP_SERVER_REQUEST_DURATION,\n {\n description: 'Duration of HTTP server requests in seconds',\n unit: 's',\n advice: { explicitBucketBoundaries: HTTP_DURATION_BUCKETS },\n },\n );\n return {\n record(durationSeconds: number, attrs: Attributes) {\n histogram.record(durationSeconds, attrs);\n },\n };\n}\n\nexport function createActiveRequestsTracker(config: HttpMetricsConfig): {\n increment: (attrs: Attributes) => void;\n decrement: (attrs: Attributes) => void;\n} | undefined {\n if (config.captureActiveRequests === false) {\n return undefined;\n }\n const counter = config.meter.createUpDownCounter(\n METRIC_HTTP_SERVER_ACTIVE_REQUESTS,\n {\n description: 'Number of active (in-flight) HTTP server requests',\n },\n );\n return {\n increment(attrs: Attributes) {\n counter.add(1, attrs);\n },\n decrement(attrs: Attributes) {\n counter.add(-1, attrs);\n },\n };\n}\n","import type { Span, Tracer } from 'autotel';\nimport {\n getTracer,\n getMeter,\n context as otelContext,\n propagation,\n SpanKind,\n SpanStatusCode,\n HTTPAttributes,\n URLAttributes,\n ServiceAttributes,\n httpRequestHeaderAttribute,\n httpResponseHeaderAttribute,\n} from 'autotel';\nimport type { MiddlewareHandler, Context } from 'hono';\nimport { createMiddleware } from 'hono/factory';\nimport { routePath } from 'hono/route';\nimport {\n createRequestDurationTracker,\n createActiveRequestsTracker,\n type HttpMetricsConfig,\n} from './metrics';\n\nconst INSTRUMENTATION_SCOPE_NAME = 'autotel-hono';\n\ntype TimeInput = number | [number, number];\ntype TracerProvider = { getTracer(name: string, version?: string): Tracer };\ntype Meter = HttpMetricsConfig['meter'];\ntype MeterProvider = { getMeter(name: string, version?: string): Meter };\n\nfunction now(): number {\n const p = (globalThis as unknown as { performance?: { now(): number } })\n .performance;\n return p?.now() ?? Date.now();\n}\n\nexport type OtelConfig = {\n tracer?: Tracer;\n tracerProvider?: TracerProvider;\n meter?: Meter;\n meterProvider?: MeterProvider;\n tracerName?: string;\n spanNameFactory?: (c: Context) => string;\n captureRequestHeaders?: string[];\n captureResponseHeaders?: string[];\n captureActiveRequests?: boolean;\n captureRequestDuration?: boolean;\n serviceName?: string;\n serviceVersion?: string;\n disableTracing?: boolean;\n getTime?(): TimeInput;\n};\n\ntype NormalizedOtelConfig = OtelConfig & {\n requestHeaderSet: Set<string>;\n responseHeaderSet: Set<string>;\n captureActiveRequests: boolean;\n captureRequestDuration: boolean;\n};\n\nfunction normalizeConfig(config: OtelConfig = {}): NormalizedOtelConfig {\n const reqHeadersSrc = [...(config.captureRequestHeaders ?? [])];\n const resHeadersSrc = [...(config.captureResponseHeaders ?? [])];\n const requestHeaderSet = new Set(reqHeadersSrc.map((h) => h.toLowerCase()));\n const responseHeaderSet = new Set(resHeadersSrc.map((h) => h.toLowerCase()));\n return {\n ...config,\n requestHeaderSet,\n responseHeaderSet,\n captureActiveRequests: config.captureActiveRequests ?? true,\n captureRequestDuration: config.captureRequestDuration ?? true,\n };\n}\n\nfunction resolveTracer(config: NormalizedOtelConfig): Tracer | undefined {\n if (config.disableTracing) return undefined;\n if (config.tracer) return config.tracer;\n if (config.tracerProvider) {\n return config.tracerProvider.getTracer(\n config.tracerName ?? INSTRUMENTATION_SCOPE_NAME,\n config.serviceVersion,\n );\n }\n return getTracer(config.tracerName ?? INSTRUMENTATION_SCOPE_NAME, config.serviceVersion);\n}\n\nfunction resolveMeter(config: NormalizedOtelConfig): Meter {\n if (config.meter) return config.meter;\n if (config.meterProvider) {\n return config.meterProvider.getMeter(\n INSTRUMENTATION_SCOPE_NAME,\n config.serviceVersion,\n );\n }\n return getMeter();\n}\n\nexport function otel(userConfig: OtelConfig = {}): MiddlewareHandler {\n const config = normalizeConfig(userConfig);\n const tracer = resolveTracer(config);\n const meter = resolveMeter(config);\n\n const metricsConfig: HttpMetricsConfig = {\n meter,\n captureRequestDuration: config.captureRequestDuration,\n captureActiveRequests: config.captureActiveRequests,\n };\n const requestDuration = createRequestDurationTracker(metricsConfig);\n const activeReqs = createActiveRequestsTracker(metricsConfig);\n\n const spanName = (c: Context) =>\n config.spanNameFactory?.(c) ?? `${c.req.method} ${routePath(c)}`;\n\n return createMiddleware(async (c, next) => {\n const method = c.req.method;\n\n const stableAttrs: Record<string, string | number | undefined> = {\n [HTTPAttributes.requestMethod]: method,\n [ServiceAttributes.name]: config.serviceName,\n [ServiceAttributes.version]: config.serviceVersion,\n };\n\n activeReqs?.increment(stableAttrs);\n const startTime = now();\n\n const deferredRequestHeaderAttributes: Record<string, string> = {};\n const reqHeaders = c.req.raw.headers;\n for (const [rawName, value] of reqHeaders.entries()) {\n const name = rawName.toLowerCase();\n if (config.requestHeaderSet.has(name)) {\n deferredRequestHeaderAttributes[httpRequestHeaderAttribute(name)] =\n typeof value === 'string' ? value : value[0] ?? '';\n }\n }\n\n const finalize = (span?: Span, error?: unknown) => {\n try {\n const status = c.res.status;\n\n if (span) {\n for (const [name, value] of c.res.headers.entries()) {\n const lower = name.toLowerCase();\n if (config.responseHeaderSet.has(lower)) {\n span.setAttribute(httpResponseHeaderAttribute(lower), value);\n }\n }\n span.setAttribute(HTTPAttributes.responseStatusCode, status);\n if (status >= 500) {\n span.setStatus({ code: SpanStatusCode.ERROR });\n }\n if (error) {\n try {\n span.recordException(error as Error);\n } catch {\n // Ignore errors when recording exception\n }\n span.setStatus({ code: SpanStatusCode.ERROR });\n }\n }\n } finally {\n activeReqs?.decrement(stableAttrs);\n span?.setAttribute(HTTPAttributes.route, routePath(c));\n span?.updateName(spanName(c));\n const durationSeconds = (now() - startTime) / 1000;\n requestDuration.record(durationSeconds, {\n ...stableAttrs,\n [HTTPAttributes.route]: routePath(c),\n [HTTPAttributes.responseStatusCode]: c.res.status,\n });\n }\n };\n\n if (!tracer) {\n try {\n await next();\n finalize();\n } catch (error) {\n finalize(undefined, error);\n throw error;\n }\n return;\n }\n\n const parent = propagation.extract(otelContext.active(), c.req.header());\n return tracer.startActiveSpan(\n spanName(c),\n {\n kind: SpanKind.SERVER,\n startTime: config.getTime?.(),\n attributes: {\n ...stableAttrs,\n [URLAttributes.full]: c.req.url,\n [HTTPAttributes.route]: routePath(c),\n },\n },\n parent,\n async (span) => {\n try {\n for (const [k, v] of Object.entries(deferredRequestHeaderAttributes)) {\n span.setAttribute(k, v);\n }\n await next();\n finalize(span, c.error);\n } catch (error) {\n finalize(span, error);\n throw error;\n } finally {\n span.end(config.getTime?.());\n }\n },\n );\n });\n}\n"]}
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["HTTPAttributes","ServiceAttributes","SpanStatusCode","propagation","otelContext","SpanKind","URLAttributes"],"sources":["../src/metrics.ts","../src/index.ts"],"sourcesContent":["/**\n * HTTP server metrics per OTel semantic conventions.\n *\n * Lazy-initialized request duration histogram and active-requests up/down counter.\n */\n\ntype AttributeValue = string | number | boolean | undefined;\nexport type Attributes = Record<string, AttributeValue>;\n\ntype Histogram = {\n record: (value: number, attrs?: Attributes) => void;\n};\n\ntype UpDownCounter = {\n add: (value: number, attrs?: Attributes) => void;\n};\n\nexport type Meter = {\n createHistogram: (\n name: string,\n options?: {\n description?: string;\n unit?: string;\n advice?: { explicitBucketBoundaries?: number[] };\n },\n ) => Histogram;\n createUpDownCounter: (\n name: string,\n options?: {\n description?: string;\n },\n ) => UpDownCounter;\n};\n\n/** OTel HTTP server metric names (stable convention names) */\nconst METRIC_HTTP_SERVER_REQUEST_DURATION = 'http.server.request.duration';\nconst METRIC_HTTP_SERVER_ACTIVE_REQUESTS = 'http.server.active_requests';\n\n/** Recommended bucket boundaries for request duration (seconds) */\nconst HTTP_DURATION_BUCKETS = [\n 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10,\n];\n\nexport type HttpMetricsConfig = {\n meter: Meter;\n captureRequestDuration?: boolean;\n captureActiveRequests?: boolean;\n};\n\nexport function createRequestDurationTracker(config: HttpMetricsConfig): {\n record: (durationSeconds: number, attrs: Attributes) => void;\n} {\n if (config.captureRequestDuration === false) {\n return { record: () => {} };\n }\n const histogram = config.meter.createHistogram(\n METRIC_HTTP_SERVER_REQUEST_DURATION,\n {\n description: 'Duration of HTTP server requests in seconds',\n unit: 's',\n advice: { explicitBucketBoundaries: HTTP_DURATION_BUCKETS },\n },\n );\n return {\n record(durationSeconds: number, attrs: Attributes) {\n histogram.record(durationSeconds, attrs);\n },\n };\n}\n\nexport function createActiveRequestsTracker(config: HttpMetricsConfig): {\n increment: (attrs: Attributes) => void;\n decrement: (attrs: Attributes) => void;\n} | undefined {\n if (config.captureActiveRequests === false) {\n return undefined;\n }\n const counter = config.meter.createUpDownCounter(\n METRIC_HTTP_SERVER_ACTIVE_REQUESTS,\n {\n description: 'Number of active (in-flight) HTTP server requests',\n },\n );\n return {\n increment(attrs: Attributes) {\n counter.add(1, attrs);\n },\n decrement(attrs: Attributes) {\n counter.add(-1, attrs);\n },\n };\n}\n","import type { Span, Tracer } from 'autotel';\nimport {\n getTracer,\n getMeter,\n context as otelContext,\n propagation,\n SpanKind,\n SpanStatusCode,\n HTTPAttributes,\n URLAttributes,\n ServiceAttributes,\n httpRequestHeaderAttribute,\n httpResponseHeaderAttribute,\n} from 'autotel';\nimport type { MiddlewareHandler, Context } from 'hono';\nimport { createMiddleware } from 'hono/factory';\nimport { routePath } from 'hono/route';\nimport {\n createRequestDurationTracker,\n createActiveRequestsTracker,\n type HttpMetricsConfig,\n} from './metrics';\n\nconst INSTRUMENTATION_SCOPE_NAME = 'autotel-hono';\n\ntype TimeInput = number | [number, number];\ntype TracerProvider = { getTracer(name: string, version?: string): Tracer };\ntype Meter = HttpMetricsConfig['meter'];\ntype MeterProvider = { getMeter(name: string, version?: string): Meter };\n\nfunction now(): number {\n const p = (globalThis as unknown as { performance?: { now(): number } })\n .performance;\n return p?.now() ?? Date.now();\n}\n\nexport type OtelConfig = {\n tracer?: Tracer;\n tracerProvider?: TracerProvider;\n meter?: Meter;\n meterProvider?: MeterProvider;\n tracerName?: string;\n spanNameFactory?: (c: Context) => string;\n captureRequestHeaders?: string[];\n captureResponseHeaders?: string[];\n captureActiveRequests?: boolean;\n captureRequestDuration?: boolean;\n serviceName?: string;\n serviceVersion?: string;\n disableTracing?: boolean;\n getTime?(): TimeInput;\n};\n\ntype NormalizedOtelConfig = OtelConfig & {\n requestHeaderSet: Set<string>;\n responseHeaderSet: Set<string>;\n captureActiveRequests: boolean;\n captureRequestDuration: boolean;\n};\n\nfunction normalizeConfig(config: OtelConfig = {}): NormalizedOtelConfig {\n const reqHeadersSrc = [...(config.captureRequestHeaders ?? [])];\n const resHeadersSrc = [...(config.captureResponseHeaders ?? [])];\n const requestHeaderSet = new Set(reqHeadersSrc.map((h) => h.toLowerCase()));\n const responseHeaderSet = new Set(resHeadersSrc.map((h) => h.toLowerCase()));\n return {\n ...config,\n requestHeaderSet,\n responseHeaderSet,\n captureActiveRequests: config.captureActiveRequests ?? true,\n captureRequestDuration: config.captureRequestDuration ?? true,\n };\n}\n\nfunction resolveTracer(config: NormalizedOtelConfig): Tracer | undefined {\n if (config.disableTracing) return undefined;\n if (config.tracer) return config.tracer;\n if (config.tracerProvider) {\n return config.tracerProvider.getTracer(\n config.tracerName ?? INSTRUMENTATION_SCOPE_NAME,\n config.serviceVersion,\n );\n }\n return getTracer(config.tracerName ?? INSTRUMENTATION_SCOPE_NAME, config.serviceVersion);\n}\n\nfunction resolveMeter(config: NormalizedOtelConfig): Meter {\n if (config.meter) return config.meter;\n if (config.meterProvider) {\n return config.meterProvider.getMeter(\n INSTRUMENTATION_SCOPE_NAME,\n config.serviceVersion,\n );\n }\n return getMeter();\n}\n\nexport function otel(userConfig: OtelConfig = {}): MiddlewareHandler {\n const config = normalizeConfig(userConfig);\n const tracer = resolveTracer(config);\n const meter = resolveMeter(config);\n\n const metricsConfig: HttpMetricsConfig = {\n meter,\n captureRequestDuration: config.captureRequestDuration,\n captureActiveRequests: config.captureActiveRequests,\n };\n const requestDuration = createRequestDurationTracker(metricsConfig);\n const activeReqs = createActiveRequestsTracker(metricsConfig);\n\n const spanName = (c: Context) =>\n config.spanNameFactory?.(c) ?? `${c.req.method} ${routePath(c)}`;\n\n return createMiddleware(async (c, next) => {\n const method = c.req.method;\n\n const stableAttrs: Record<string, string | number | undefined> = {\n [HTTPAttributes.requestMethod]: method,\n [ServiceAttributes.name]: config.serviceName,\n [ServiceAttributes.version]: config.serviceVersion,\n };\n\n activeReqs?.increment(stableAttrs);\n const startTime = now();\n\n const deferredRequestHeaderAttributes: Record<string, string> = {};\n const reqHeaders = c.req.raw.headers;\n for (const [rawName, value] of reqHeaders.entries()) {\n const name = rawName.toLowerCase();\n if (config.requestHeaderSet.has(name)) {\n deferredRequestHeaderAttributes[httpRequestHeaderAttribute(name)] =\n typeof value === 'string' ? value : value[0] ?? '';\n }\n }\n\n const finalize = (span?: Span, error?: unknown) => {\n try {\n const status = c.res.status;\n\n if (span) {\n for (const [name, value] of c.res.headers.entries()) {\n const lower = name.toLowerCase();\n if (config.responseHeaderSet.has(lower)) {\n span.setAttribute(httpResponseHeaderAttribute(lower), value);\n }\n }\n span.setAttribute(HTTPAttributes.responseStatusCode, status);\n if (status >= 500) {\n span.setStatus({ code: SpanStatusCode.ERROR });\n }\n if (error) {\n try {\n span.recordException(error as Error);\n } catch {\n // Ignore errors when recording exception\n }\n span.setStatus({ code: SpanStatusCode.ERROR });\n }\n }\n } finally {\n activeReqs?.decrement(stableAttrs);\n span?.setAttribute(HTTPAttributes.route, routePath(c));\n span?.updateName(spanName(c));\n const durationSeconds = (now() - startTime) / 1000;\n requestDuration.record(durationSeconds, {\n ...stableAttrs,\n [HTTPAttributes.route]: routePath(c),\n [HTTPAttributes.responseStatusCode]: c.res.status,\n });\n }\n };\n\n if (!tracer) {\n try {\n await next();\n finalize();\n } catch (error) {\n finalize(undefined, error);\n throw error;\n }\n return;\n }\n\n const parent = propagation.extract(otelContext.active(), c.req.header());\n return tracer.startActiveSpan(\n spanName(c),\n {\n kind: SpanKind.SERVER,\n startTime: config.getTime?.(),\n attributes: {\n ...stableAttrs,\n [URLAttributes.full]: c.req.url,\n [HTTPAttributes.route]: routePath(c),\n },\n },\n parent,\n async (span) => {\n try {\n for (const [k, v] of Object.entries(deferredRequestHeaderAttributes)) {\n span.setAttribute(k, v);\n }\n await next();\n finalize(span, c.error);\n } catch (error) {\n finalize(span, error);\n throw error;\n } finally {\n span.end(config.getTime?.());\n }\n },\n );\n });\n}\n"],"mappings":"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"}
|
package/dist/index.d.cts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { Tracer } from
|
|
2
|
-
import { Context, MiddlewareHandler } from
|
|
1
|
+
import { Tracer } from "autotel";
|
|
2
|
+
import { Context, MiddlewareHandler } from "hono";
|
|
3
3
|
|
|
4
|
+
//#region src/metrics.d.ts
|
|
4
5
|
/**
|
|
5
6
|
* HTTP server metrics per OTel semantic conventions.
|
|
6
7
|
*
|
|
@@ -9,53 +10,55 @@ import { Context, MiddlewareHandler } from 'hono';
|
|
|
9
10
|
type AttributeValue = string | number | boolean | undefined;
|
|
10
11
|
type Attributes = Record<string, AttributeValue>;
|
|
11
12
|
type Histogram = {
|
|
12
|
-
|
|
13
|
+
record: (value: number, attrs?: Attributes) => void;
|
|
13
14
|
};
|
|
14
15
|
type UpDownCounter = {
|
|
15
|
-
|
|
16
|
+
add: (value: number, attrs?: Attributes) => void;
|
|
16
17
|
};
|
|
17
18
|
type Meter$1 = {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
19
|
+
createHistogram: (name: string, options?: {
|
|
20
|
+
description?: string;
|
|
21
|
+
unit?: string;
|
|
22
|
+
advice?: {
|
|
23
|
+
explicitBucketBoundaries?: number[];
|
|
24
|
+
};
|
|
25
|
+
}) => Histogram;
|
|
26
|
+
createUpDownCounter: (name: string, options?: {
|
|
27
|
+
description?: string;
|
|
28
|
+
}) => UpDownCounter;
|
|
28
29
|
};
|
|
29
30
|
type HttpMetricsConfig = {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
31
|
+
meter: Meter$1;
|
|
32
|
+
captureRequestDuration?: boolean;
|
|
33
|
+
captureActiveRequests?: boolean;
|
|
33
34
|
};
|
|
34
|
-
|
|
35
|
+
//#endregion
|
|
36
|
+
//#region src/index.d.ts
|
|
35
37
|
type TimeInput = number | [number, number];
|
|
36
38
|
type TracerProvider = {
|
|
37
|
-
|
|
39
|
+
getTracer(name: string, version?: string): Tracer;
|
|
38
40
|
};
|
|
39
41
|
type Meter = HttpMetricsConfig['meter'];
|
|
40
42
|
type MeterProvider = {
|
|
41
|
-
|
|
43
|
+
getMeter(name: string, version?: string): Meter;
|
|
42
44
|
};
|
|
43
45
|
type OtelConfig = {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
46
|
+
tracer?: Tracer;
|
|
47
|
+
tracerProvider?: TracerProvider;
|
|
48
|
+
meter?: Meter;
|
|
49
|
+
meterProvider?: MeterProvider;
|
|
50
|
+
tracerName?: string;
|
|
51
|
+
spanNameFactory?: (c: Context) => string;
|
|
52
|
+
captureRequestHeaders?: string[];
|
|
53
|
+
captureResponseHeaders?: string[];
|
|
54
|
+
captureActiveRequests?: boolean;
|
|
55
|
+
captureRequestDuration?: boolean;
|
|
56
|
+
serviceName?: string;
|
|
57
|
+
serviceVersion?: string;
|
|
58
|
+
disableTracing?: boolean;
|
|
59
|
+
getTime?(): TimeInput;
|
|
58
60
|
};
|
|
59
61
|
declare function otel(userConfig?: OtelConfig): MiddlewareHandler;
|
|
60
|
-
|
|
61
|
-
export {
|
|
62
|
+
//#endregion
|
|
63
|
+
export { OtelConfig, otel };
|
|
64
|
+
//# sourceMappingURL=index.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.cts","names":[],"sources":["../src/metrics.ts","../src/index.ts"],"mappings":";;;;;;;;;KAMK,cAAA;AAAA,KACO,UAAA,GAAa,MAAM,SAAS,cAAA;AAAA,KAEnC,SAAA;EACH,MAAA,GAAS,KAAA,UAAe,KAAA,GAAQ,UAAU;AAAA;AAAA,KAGvC,aAAA;EACH,GAAA,GAAM,KAAA,UAAe,KAAA,GAAQ,UAAU;AAAA;AAAA,KAG7B,OAAA;EACV,eAAA,GACE,IAAA,UACA,OAAA;IACE,WAAA;IACA,IAAA;IACA,MAAA;MAAW,wBAAA;IAAA;EAAA,MAEV,SAAA;EACL,mBAAA,GACE,IAAA,UACA,OAAA;IACE,WAAA;EAAA,MAEC,aAAa;AAAA;AAAA,KAYR,iBAAA;EACV,KAAA,EAAO,OAAK;EACZ,sBAAA;EACA,qBAAA;AAAA;;;KCrBG,SAAA;AAAA,KACA,cAAA;EAAmB,SAAA,CAAU,IAAA,UAAc,OAAA,YAAmB,MAAM;AAAA;AAAA,KACpE,KAAA,GAAQ,iBAAiB;AAAA,KACzB,aAAA;EAAkB,QAAA,CAAS,IAAA,UAAc,OAAA,YAAmB,KAAK;AAAA;AAAA,KAQ1D,UAAA;EACV,MAAA,GAAS,MAAA;EACT,cAAA,GAAiB,cAAA;EACjB,KAAA,GAAQ,KAAA;EACR,aAAA,GAAgB,aAAA;EAChB,UAAA;EACA,eAAA,IAAmB,CAAA,EAAG,OAAA;EACtB,qBAAA;EACA,sBAAA;EACA,qBAAA;EACA,sBAAA;EACA,WAAA;EACA,cAAA;EACA,cAAA;EACA,OAAA,KAAY,SAAA;AAAA;AAAA,iBA+CE,IAAA,CAAK,UAAA,GAAY,UAAA,GAAkB,iBAAiB"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { Tracer } from
|
|
2
|
-
import { Context, MiddlewareHandler } from
|
|
1
|
+
import { Tracer } from "autotel";
|
|
2
|
+
import { Context, MiddlewareHandler } from "hono";
|
|
3
3
|
|
|
4
|
+
//#region src/metrics.d.ts
|
|
4
5
|
/**
|
|
5
6
|
* HTTP server metrics per OTel semantic conventions.
|
|
6
7
|
*
|
|
@@ -9,53 +10,55 @@ import { Context, MiddlewareHandler } from 'hono';
|
|
|
9
10
|
type AttributeValue = string | number | boolean | undefined;
|
|
10
11
|
type Attributes = Record<string, AttributeValue>;
|
|
11
12
|
type Histogram = {
|
|
12
|
-
|
|
13
|
+
record: (value: number, attrs?: Attributes) => void;
|
|
13
14
|
};
|
|
14
15
|
type UpDownCounter = {
|
|
15
|
-
|
|
16
|
+
add: (value: number, attrs?: Attributes) => void;
|
|
16
17
|
};
|
|
17
18
|
type Meter$1 = {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
19
|
+
createHistogram: (name: string, options?: {
|
|
20
|
+
description?: string;
|
|
21
|
+
unit?: string;
|
|
22
|
+
advice?: {
|
|
23
|
+
explicitBucketBoundaries?: number[];
|
|
24
|
+
};
|
|
25
|
+
}) => Histogram;
|
|
26
|
+
createUpDownCounter: (name: string, options?: {
|
|
27
|
+
description?: string;
|
|
28
|
+
}) => UpDownCounter;
|
|
28
29
|
};
|
|
29
30
|
type HttpMetricsConfig = {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
31
|
+
meter: Meter$1;
|
|
32
|
+
captureRequestDuration?: boolean;
|
|
33
|
+
captureActiveRequests?: boolean;
|
|
33
34
|
};
|
|
34
|
-
|
|
35
|
+
//#endregion
|
|
36
|
+
//#region src/index.d.ts
|
|
35
37
|
type TimeInput = number | [number, number];
|
|
36
38
|
type TracerProvider = {
|
|
37
|
-
|
|
39
|
+
getTracer(name: string, version?: string): Tracer;
|
|
38
40
|
};
|
|
39
41
|
type Meter = HttpMetricsConfig['meter'];
|
|
40
42
|
type MeterProvider = {
|
|
41
|
-
|
|
43
|
+
getMeter(name: string, version?: string): Meter;
|
|
42
44
|
};
|
|
43
45
|
type OtelConfig = {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
46
|
+
tracer?: Tracer;
|
|
47
|
+
tracerProvider?: TracerProvider;
|
|
48
|
+
meter?: Meter;
|
|
49
|
+
meterProvider?: MeterProvider;
|
|
50
|
+
tracerName?: string;
|
|
51
|
+
spanNameFactory?: (c: Context) => string;
|
|
52
|
+
captureRequestHeaders?: string[];
|
|
53
|
+
captureResponseHeaders?: string[];
|
|
54
|
+
captureActiveRequests?: boolean;
|
|
55
|
+
captureRequestDuration?: boolean;
|
|
56
|
+
serviceName?: string;
|
|
57
|
+
serviceVersion?: string;
|
|
58
|
+
disableTracing?: boolean;
|
|
59
|
+
getTime?(): TimeInput;
|
|
58
60
|
};
|
|
59
61
|
declare function otel(userConfig?: OtelConfig): MiddlewareHandler;
|
|
60
|
-
|
|
61
|
-
export {
|
|
62
|
+
//#endregion
|
|
63
|
+
export { OtelConfig, otel };
|
|
64
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/metrics.ts","../src/index.ts"],"mappings":";;;;;;;;;KAMK,cAAA;AAAA,KACO,UAAA,GAAa,MAAM,SAAS,cAAA;AAAA,KAEnC,SAAA;EACH,MAAA,GAAS,KAAA,UAAe,KAAA,GAAQ,UAAU;AAAA;AAAA,KAGvC,aAAA;EACH,GAAA,GAAM,KAAA,UAAe,KAAA,GAAQ,UAAU;AAAA;AAAA,KAG7B,OAAA;EACV,eAAA,GACE,IAAA,UACA,OAAA;IACE,WAAA;IACA,IAAA;IACA,MAAA;MAAW,wBAAA;IAAA;EAAA,MAEV,SAAA;EACL,mBAAA,GACE,IAAA,UACA,OAAA;IACE,WAAA;EAAA,MAEC,aAAa;AAAA;AAAA,KAYR,iBAAA;EACV,KAAA,EAAO,OAAK;EACZ,sBAAA;EACA,qBAAA;AAAA;;;KCrBG,SAAA;AAAA,KACA,cAAA;EAAmB,SAAA,CAAU,IAAA,UAAc,OAAA,YAAmB,MAAM;AAAA;AAAA,KACpE,KAAA,GAAQ,iBAAiB;AAAA,KACzB,aAAA;EAAkB,QAAA,CAAS,IAAA,UAAc,OAAA,YAAmB,KAAK;AAAA;AAAA,KAQ1D,UAAA;EACV,MAAA,GAAS,MAAA;EACT,cAAA,GAAiB,cAAA;EACjB,KAAA,GAAQ,KAAA;EACR,aAAA,GAAgB,aAAA;EAChB,UAAA;EACA,eAAA,IAAmB,CAAA,EAAG,OAAA;EACtB,qBAAA;EACA,sBAAA;EACA,qBAAA;EACA,sBAAA;EACA,WAAA;EACA,cAAA;EACA,cAAA;EACA,OAAA,KAAY,SAAA;AAAA;AAAA,iBA+CE,IAAA,CAAK,UAAA,GAAY,UAAA,GAAkB,iBAAiB"}
|
package/dist/index.js
CHANGED
|
@@ -1,211 +1,169 @@
|
|
|
1
|
-
import { ServiceAttributes,
|
|
2
|
-
import { createMiddleware } from
|
|
3
|
-
import { routePath } from
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
10
|
|
1
|
+
import { HTTPAttributes, ServiceAttributes, SpanKind, SpanStatusCode, URLAttributes, context, getMeter, getTracer, httpRequestHeaderAttribute, httpResponseHeaderAttribute, propagation } from "autotel";
|
|
2
|
+
import { createMiddleware } from "hono/factory";
|
|
3
|
+
import { routePath } from "hono/route";
|
|
4
|
+
//#region src/metrics.ts
|
|
5
|
+
/** OTel HTTP server metric names (stable convention names) */
|
|
6
|
+
const METRIC_HTTP_SERVER_REQUEST_DURATION = "http.server.request.duration";
|
|
7
|
+
const METRIC_HTTP_SERVER_ACTIVE_REQUESTS = "http.server.active_requests";
|
|
8
|
+
/** Recommended bucket boundaries for request duration (seconds) */
|
|
9
|
+
const HTTP_DURATION_BUCKETS = [
|
|
10
|
+
.005,
|
|
11
|
+
.01,
|
|
12
|
+
.025,
|
|
13
|
+
.05,
|
|
14
|
+
.075,
|
|
15
|
+
.1,
|
|
16
|
+
.25,
|
|
17
|
+
.5,
|
|
18
|
+
.75,
|
|
19
|
+
1,
|
|
20
|
+
2.5,
|
|
21
|
+
5,
|
|
22
|
+
7.5,
|
|
23
|
+
10
|
|
25
24
|
];
|
|
26
25
|
function createRequestDurationTracker(config) {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
advice: { explicitBucketBoundaries: HTTP_DURATION_BUCKETS }
|
|
37
|
-
}
|
|
38
|
-
);
|
|
39
|
-
return {
|
|
40
|
-
record(durationSeconds, attrs) {
|
|
41
|
-
histogram.record(durationSeconds, attrs);
|
|
42
|
-
}
|
|
43
|
-
};
|
|
26
|
+
if (config.captureRequestDuration === false) return { record: () => {} };
|
|
27
|
+
const histogram = config.meter.createHistogram(METRIC_HTTP_SERVER_REQUEST_DURATION, {
|
|
28
|
+
description: "Duration of HTTP server requests in seconds",
|
|
29
|
+
unit: "s",
|
|
30
|
+
advice: { explicitBucketBoundaries: HTTP_DURATION_BUCKETS }
|
|
31
|
+
});
|
|
32
|
+
return { record(durationSeconds, attrs) {
|
|
33
|
+
histogram.record(durationSeconds, attrs);
|
|
34
|
+
} };
|
|
44
35
|
}
|
|
45
36
|
function createActiveRequestsTracker(config) {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
increment(attrs) {
|
|
57
|
-
counter.add(1, attrs);
|
|
58
|
-
},
|
|
59
|
-
decrement(attrs) {
|
|
60
|
-
counter.add(-1, attrs);
|
|
61
|
-
}
|
|
62
|
-
};
|
|
37
|
+
if (config.captureActiveRequests === false) return;
|
|
38
|
+
const counter = config.meter.createUpDownCounter(METRIC_HTTP_SERVER_ACTIVE_REQUESTS, { description: "Number of active (in-flight) HTTP server requests" });
|
|
39
|
+
return {
|
|
40
|
+
increment(attrs) {
|
|
41
|
+
counter.add(1, attrs);
|
|
42
|
+
},
|
|
43
|
+
decrement(attrs) {
|
|
44
|
+
counter.add(-1, attrs);
|
|
45
|
+
}
|
|
46
|
+
};
|
|
63
47
|
}
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
48
|
+
//#endregion
|
|
49
|
+
//#region src/index.ts
|
|
50
|
+
const INSTRUMENTATION_SCOPE_NAME = "autotel-hono";
|
|
67
51
|
function now() {
|
|
68
|
-
|
|
69
|
-
return p?.now() ?? Date.now();
|
|
52
|
+
return globalThis.performance?.now() ?? Date.now();
|
|
70
53
|
}
|
|
71
54
|
function normalizeConfig(config = {}) {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
55
|
+
const reqHeadersSrc = [...config.captureRequestHeaders ?? []];
|
|
56
|
+
const resHeadersSrc = [...config.captureResponseHeaders ?? []];
|
|
57
|
+
const requestHeaderSet = new Set(reqHeadersSrc.map((h) => h.toLowerCase()));
|
|
58
|
+
const responseHeaderSet = new Set(resHeadersSrc.map((h) => h.toLowerCase()));
|
|
59
|
+
return {
|
|
60
|
+
...config,
|
|
61
|
+
requestHeaderSet,
|
|
62
|
+
responseHeaderSet,
|
|
63
|
+
captureActiveRequests: config.captureActiveRequests ?? true,
|
|
64
|
+
captureRequestDuration: config.captureRequestDuration ?? true
|
|
65
|
+
};
|
|
83
66
|
}
|
|
84
67
|
function resolveTracer(config) {
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
config.tracerName ?? INSTRUMENTATION_SCOPE_NAME,
|
|
90
|
-
config.serviceVersion
|
|
91
|
-
);
|
|
92
|
-
}
|
|
93
|
-
return getTracer(config.tracerName ?? INSTRUMENTATION_SCOPE_NAME, config.serviceVersion);
|
|
68
|
+
if (config.disableTracing) return void 0;
|
|
69
|
+
if (config.tracer) return config.tracer;
|
|
70
|
+
if (config.tracerProvider) return config.tracerProvider.getTracer(config.tracerName ?? INSTRUMENTATION_SCOPE_NAME, config.serviceVersion);
|
|
71
|
+
return getTracer(config.tracerName ?? INSTRUMENTATION_SCOPE_NAME, config.serviceVersion);
|
|
94
72
|
}
|
|
95
73
|
function resolveMeter(config) {
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
INSTRUMENTATION_SCOPE_NAME,
|
|
100
|
-
config.serviceVersion
|
|
101
|
-
);
|
|
102
|
-
}
|
|
103
|
-
return getMeter();
|
|
74
|
+
if (config.meter) return config.meter;
|
|
75
|
+
if (config.meterProvider) return config.meterProvider.getMeter(INSTRUMENTATION_SCOPE_NAME, config.serviceVersion);
|
|
76
|
+
return getMeter();
|
|
104
77
|
}
|
|
105
78
|
function otel(userConfig = {}) {
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
try {
|
|
193
|
-
for (const [k, v] of Object.entries(deferredRequestHeaderAttributes)) {
|
|
194
|
-
span.setAttribute(k, v);
|
|
195
|
-
}
|
|
196
|
-
await next();
|
|
197
|
-
finalize(span, c.error);
|
|
198
|
-
} catch (error) {
|
|
199
|
-
finalize(span, error);
|
|
200
|
-
throw error;
|
|
201
|
-
} finally {
|
|
202
|
-
span.end(config.getTime?.());
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
);
|
|
206
|
-
});
|
|
79
|
+
const config = normalizeConfig(userConfig);
|
|
80
|
+
const tracer = resolveTracer(config);
|
|
81
|
+
const metricsConfig = {
|
|
82
|
+
meter: resolveMeter(config),
|
|
83
|
+
captureRequestDuration: config.captureRequestDuration,
|
|
84
|
+
captureActiveRequests: config.captureActiveRequests
|
|
85
|
+
};
|
|
86
|
+
const requestDuration = createRequestDurationTracker(metricsConfig);
|
|
87
|
+
const activeReqs = createActiveRequestsTracker(metricsConfig);
|
|
88
|
+
const spanName = (c) => config.spanNameFactory?.(c) ?? `${c.req.method} ${routePath(c)}`;
|
|
89
|
+
return createMiddleware(async (c, next) => {
|
|
90
|
+
const method = c.req.method;
|
|
91
|
+
const stableAttrs = {
|
|
92
|
+
[HTTPAttributes.requestMethod]: method,
|
|
93
|
+
[ServiceAttributes.name]: config.serviceName,
|
|
94
|
+
[ServiceAttributes.version]: config.serviceVersion
|
|
95
|
+
};
|
|
96
|
+
activeReqs?.increment(stableAttrs);
|
|
97
|
+
const startTime = now();
|
|
98
|
+
const deferredRequestHeaderAttributes = {};
|
|
99
|
+
const reqHeaders = c.req.raw.headers;
|
|
100
|
+
for (const [rawName, value] of reqHeaders.entries()) {
|
|
101
|
+
const name = rawName.toLowerCase();
|
|
102
|
+
if (config.requestHeaderSet.has(name)) deferredRequestHeaderAttributes[httpRequestHeaderAttribute(name)] = typeof value === "string" ? value : value[0] ?? "";
|
|
103
|
+
}
|
|
104
|
+
const finalize = (span, error) => {
|
|
105
|
+
try {
|
|
106
|
+
const status = c.res.status;
|
|
107
|
+
if (span) {
|
|
108
|
+
for (const [name, value] of c.res.headers.entries()) {
|
|
109
|
+
const lower = name.toLowerCase();
|
|
110
|
+
if (config.responseHeaderSet.has(lower)) span.setAttribute(httpResponseHeaderAttribute(lower), value);
|
|
111
|
+
}
|
|
112
|
+
span.setAttribute(HTTPAttributes.responseStatusCode, status);
|
|
113
|
+
if (status >= 500) span.setStatus({ code: SpanStatusCode.ERROR });
|
|
114
|
+
if (error) {
|
|
115
|
+
try {
|
|
116
|
+
span.recordException(error);
|
|
117
|
+
} catch {}
|
|
118
|
+
span.setStatus({ code: SpanStatusCode.ERROR });
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
} finally {
|
|
122
|
+
activeReqs?.decrement(stableAttrs);
|
|
123
|
+
span?.setAttribute(HTTPAttributes.route, routePath(c));
|
|
124
|
+
span?.updateName(spanName(c));
|
|
125
|
+
const durationSeconds = (now() - startTime) / 1e3;
|
|
126
|
+
requestDuration.record(durationSeconds, {
|
|
127
|
+
...stableAttrs,
|
|
128
|
+
[HTTPAttributes.route]: routePath(c),
|
|
129
|
+
[HTTPAttributes.responseStatusCode]: c.res.status
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
if (!tracer) {
|
|
134
|
+
try {
|
|
135
|
+
await next();
|
|
136
|
+
finalize();
|
|
137
|
+
} catch (error) {
|
|
138
|
+
finalize(void 0, error);
|
|
139
|
+
throw error;
|
|
140
|
+
}
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
const parent = propagation.extract(context.active(), c.req.header());
|
|
144
|
+
return tracer.startActiveSpan(spanName(c), {
|
|
145
|
+
kind: SpanKind.SERVER,
|
|
146
|
+
startTime: config.getTime?.(),
|
|
147
|
+
attributes: {
|
|
148
|
+
...stableAttrs,
|
|
149
|
+
[URLAttributes.full]: c.req.url,
|
|
150
|
+
[HTTPAttributes.route]: routePath(c)
|
|
151
|
+
}
|
|
152
|
+
}, parent, async (span) => {
|
|
153
|
+
try {
|
|
154
|
+
for (const [k, v] of Object.entries(deferredRequestHeaderAttributes)) span.setAttribute(k, v);
|
|
155
|
+
await next();
|
|
156
|
+
finalize(span, c.error);
|
|
157
|
+
} catch (error) {
|
|
158
|
+
finalize(span, error);
|
|
159
|
+
throw error;
|
|
160
|
+
} finally {
|
|
161
|
+
span.end(config.getTime?.());
|
|
162
|
+
}
|
|
163
|
+
});
|
|
164
|
+
});
|
|
207
165
|
}
|
|
208
|
-
|
|
166
|
+
//#endregion
|
|
209
167
|
export { otel };
|
|
210
|
-
|
|
168
|
+
|
|
211
169
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/metrics.ts","../src/index.ts"],"names":["otelContext"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * HTTP server metrics per OTel semantic conventions.\n *\n * Lazy-initialized request duration histogram and active-requests up/down counter.\n */\n\ntype AttributeValue = string | number | boolean | undefined;\nexport type Attributes = Record<string, AttributeValue>;\n\ntype Histogram = {\n record: (value: number, attrs?: Attributes) => void;\n};\n\ntype UpDownCounter = {\n add: (value: number, attrs?: Attributes) => void;\n};\n\nexport type Meter = {\n createHistogram: (\n name: string,\n options?: {\n description?: string;\n unit?: string;\n advice?: { explicitBucketBoundaries?: number[] };\n },\n ) => Histogram;\n createUpDownCounter: (\n name: string,\n options?: {\n description?: string;\n },\n ) => UpDownCounter;\n};\n\n/** OTel HTTP server metric names (stable convention names) */\nconst METRIC_HTTP_SERVER_REQUEST_DURATION = 'http.server.request.duration';\nconst METRIC_HTTP_SERVER_ACTIVE_REQUESTS = 'http.server.active_requests';\n\n/** Recommended bucket boundaries for request duration (seconds) */\nconst HTTP_DURATION_BUCKETS = [\n 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10,\n];\n\nexport type HttpMetricsConfig = {\n meter: Meter;\n captureRequestDuration?: boolean;\n captureActiveRequests?: boolean;\n};\n\nexport function createRequestDurationTracker(config: HttpMetricsConfig): {\n record: (durationSeconds: number, attrs: Attributes) => void;\n} {\n if (config.captureRequestDuration === false) {\n return { record: () => {} };\n }\n const histogram = config.meter.createHistogram(\n METRIC_HTTP_SERVER_REQUEST_DURATION,\n {\n description: 'Duration of HTTP server requests in seconds',\n unit: 's',\n advice: { explicitBucketBoundaries: HTTP_DURATION_BUCKETS },\n },\n );\n return {\n record(durationSeconds: number, attrs: Attributes) {\n histogram.record(durationSeconds, attrs);\n },\n };\n}\n\nexport function createActiveRequestsTracker(config: HttpMetricsConfig): {\n increment: (attrs: Attributes) => void;\n decrement: (attrs: Attributes) => void;\n} | undefined {\n if (config.captureActiveRequests === false) {\n return undefined;\n }\n const counter = config.meter.createUpDownCounter(\n METRIC_HTTP_SERVER_ACTIVE_REQUESTS,\n {\n description: 'Number of active (in-flight) HTTP server requests',\n },\n );\n return {\n increment(attrs: Attributes) {\n counter.add(1, attrs);\n },\n decrement(attrs: Attributes) {\n counter.add(-1, attrs);\n },\n };\n}\n","import type { Span, Tracer } from 'autotel';\nimport {\n getTracer,\n getMeter,\n context as otelContext,\n propagation,\n SpanKind,\n SpanStatusCode,\n HTTPAttributes,\n URLAttributes,\n ServiceAttributes,\n httpRequestHeaderAttribute,\n httpResponseHeaderAttribute,\n} from 'autotel';\nimport type { MiddlewareHandler, Context } from 'hono';\nimport { createMiddleware } from 'hono/factory';\nimport { routePath } from 'hono/route';\nimport {\n createRequestDurationTracker,\n createActiveRequestsTracker,\n type HttpMetricsConfig,\n} from './metrics';\n\nconst INSTRUMENTATION_SCOPE_NAME = 'autotel-hono';\n\ntype TimeInput = number | [number, number];\ntype TracerProvider = { getTracer(name: string, version?: string): Tracer };\ntype Meter = HttpMetricsConfig['meter'];\ntype MeterProvider = { getMeter(name: string, version?: string): Meter };\n\nfunction now(): number {\n const p = (globalThis as unknown as { performance?: { now(): number } })\n .performance;\n return p?.now() ?? Date.now();\n}\n\nexport type OtelConfig = {\n tracer?: Tracer;\n tracerProvider?: TracerProvider;\n meter?: Meter;\n meterProvider?: MeterProvider;\n tracerName?: string;\n spanNameFactory?: (c: Context) => string;\n captureRequestHeaders?: string[];\n captureResponseHeaders?: string[];\n captureActiveRequests?: boolean;\n captureRequestDuration?: boolean;\n serviceName?: string;\n serviceVersion?: string;\n disableTracing?: boolean;\n getTime?(): TimeInput;\n};\n\ntype NormalizedOtelConfig = OtelConfig & {\n requestHeaderSet: Set<string>;\n responseHeaderSet: Set<string>;\n captureActiveRequests: boolean;\n captureRequestDuration: boolean;\n};\n\nfunction normalizeConfig(config: OtelConfig = {}): NormalizedOtelConfig {\n const reqHeadersSrc = [...(config.captureRequestHeaders ?? [])];\n const resHeadersSrc = [...(config.captureResponseHeaders ?? [])];\n const requestHeaderSet = new Set(reqHeadersSrc.map((h) => h.toLowerCase()));\n const responseHeaderSet = new Set(resHeadersSrc.map((h) => h.toLowerCase()));\n return {\n ...config,\n requestHeaderSet,\n responseHeaderSet,\n captureActiveRequests: config.captureActiveRequests ?? true,\n captureRequestDuration: config.captureRequestDuration ?? true,\n };\n}\n\nfunction resolveTracer(config: NormalizedOtelConfig): Tracer | undefined {\n if (config.disableTracing) return undefined;\n if (config.tracer) return config.tracer;\n if (config.tracerProvider) {\n return config.tracerProvider.getTracer(\n config.tracerName ?? INSTRUMENTATION_SCOPE_NAME,\n config.serviceVersion,\n );\n }\n return getTracer(config.tracerName ?? INSTRUMENTATION_SCOPE_NAME, config.serviceVersion);\n}\n\nfunction resolveMeter(config: NormalizedOtelConfig): Meter {\n if (config.meter) return config.meter;\n if (config.meterProvider) {\n return config.meterProvider.getMeter(\n INSTRUMENTATION_SCOPE_NAME,\n config.serviceVersion,\n );\n }\n return getMeter();\n}\n\nexport function otel(userConfig: OtelConfig = {}): MiddlewareHandler {\n const config = normalizeConfig(userConfig);\n const tracer = resolveTracer(config);\n const meter = resolveMeter(config);\n\n const metricsConfig: HttpMetricsConfig = {\n meter,\n captureRequestDuration: config.captureRequestDuration,\n captureActiveRequests: config.captureActiveRequests,\n };\n const requestDuration = createRequestDurationTracker(metricsConfig);\n const activeReqs = createActiveRequestsTracker(metricsConfig);\n\n const spanName = (c: Context) =>\n config.spanNameFactory?.(c) ?? `${c.req.method} ${routePath(c)}`;\n\n return createMiddleware(async (c, next) => {\n const method = c.req.method;\n\n const stableAttrs: Record<string, string | number | undefined> = {\n [HTTPAttributes.requestMethod]: method,\n [ServiceAttributes.name]: config.serviceName,\n [ServiceAttributes.version]: config.serviceVersion,\n };\n\n activeReqs?.increment(stableAttrs);\n const startTime = now();\n\n const deferredRequestHeaderAttributes: Record<string, string> = {};\n const reqHeaders = c.req.raw.headers;\n for (const [rawName, value] of reqHeaders.entries()) {\n const name = rawName.toLowerCase();\n if (config.requestHeaderSet.has(name)) {\n deferredRequestHeaderAttributes[httpRequestHeaderAttribute(name)] =\n typeof value === 'string' ? value : value[0] ?? '';\n }\n }\n\n const finalize = (span?: Span, error?: unknown) => {\n try {\n const status = c.res.status;\n\n if (span) {\n for (const [name, value] of c.res.headers.entries()) {\n const lower = name.toLowerCase();\n if (config.responseHeaderSet.has(lower)) {\n span.setAttribute(httpResponseHeaderAttribute(lower), value);\n }\n }\n span.setAttribute(HTTPAttributes.responseStatusCode, status);\n if (status >= 500) {\n span.setStatus({ code: SpanStatusCode.ERROR });\n }\n if (error) {\n try {\n span.recordException(error as Error);\n } catch {\n // Ignore errors when recording exception\n }\n span.setStatus({ code: SpanStatusCode.ERROR });\n }\n }\n } finally {\n activeReqs?.decrement(stableAttrs);\n span?.setAttribute(HTTPAttributes.route, routePath(c));\n span?.updateName(spanName(c));\n const durationSeconds = (now() - startTime) / 1000;\n requestDuration.record(durationSeconds, {\n ...stableAttrs,\n [HTTPAttributes.route]: routePath(c),\n [HTTPAttributes.responseStatusCode]: c.res.status,\n });\n }\n };\n\n if (!tracer) {\n try {\n await next();\n finalize();\n } catch (error) {\n finalize(undefined, error);\n throw error;\n }\n return;\n }\n\n const parent = propagation.extract(otelContext.active(), c.req.header());\n return tracer.startActiveSpan(\n spanName(c),\n {\n kind: SpanKind.SERVER,\n startTime: config.getTime?.(),\n attributes: {\n ...stableAttrs,\n [URLAttributes.full]: c.req.url,\n [HTTPAttributes.route]: routePath(c),\n },\n },\n parent,\n async (span) => {\n try {\n for (const [k, v] of Object.entries(deferredRequestHeaderAttributes)) {\n span.setAttribute(k, v);\n }\n await next();\n finalize(span, c.error);\n } catch (error) {\n finalize(span, error);\n throw error;\n } finally {\n span.end(config.getTime?.());\n }\n },\n );\n });\n}\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","names":["otelContext"],"sources":["../src/metrics.ts","../src/index.ts"],"sourcesContent":["/**\n * HTTP server metrics per OTel semantic conventions.\n *\n * Lazy-initialized request duration histogram and active-requests up/down counter.\n */\n\ntype AttributeValue = string | number | boolean | undefined;\nexport type Attributes = Record<string, AttributeValue>;\n\ntype Histogram = {\n record: (value: number, attrs?: Attributes) => void;\n};\n\ntype UpDownCounter = {\n add: (value: number, attrs?: Attributes) => void;\n};\n\nexport type Meter = {\n createHistogram: (\n name: string,\n options?: {\n description?: string;\n unit?: string;\n advice?: { explicitBucketBoundaries?: number[] };\n },\n ) => Histogram;\n createUpDownCounter: (\n name: string,\n options?: {\n description?: string;\n },\n ) => UpDownCounter;\n};\n\n/** OTel HTTP server metric names (stable convention names) */\nconst METRIC_HTTP_SERVER_REQUEST_DURATION = 'http.server.request.duration';\nconst METRIC_HTTP_SERVER_ACTIVE_REQUESTS = 'http.server.active_requests';\n\n/** Recommended bucket boundaries for request duration (seconds) */\nconst HTTP_DURATION_BUCKETS = [\n 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10,\n];\n\nexport type HttpMetricsConfig = {\n meter: Meter;\n captureRequestDuration?: boolean;\n captureActiveRequests?: boolean;\n};\n\nexport function createRequestDurationTracker(config: HttpMetricsConfig): {\n record: (durationSeconds: number, attrs: Attributes) => void;\n} {\n if (config.captureRequestDuration === false) {\n return { record: () => {} };\n }\n const histogram = config.meter.createHistogram(\n METRIC_HTTP_SERVER_REQUEST_DURATION,\n {\n description: 'Duration of HTTP server requests in seconds',\n unit: 's',\n advice: { explicitBucketBoundaries: HTTP_DURATION_BUCKETS },\n },\n );\n return {\n record(durationSeconds: number, attrs: Attributes) {\n histogram.record(durationSeconds, attrs);\n },\n };\n}\n\nexport function createActiveRequestsTracker(config: HttpMetricsConfig): {\n increment: (attrs: Attributes) => void;\n decrement: (attrs: Attributes) => void;\n} | undefined {\n if (config.captureActiveRequests === false) {\n return undefined;\n }\n const counter = config.meter.createUpDownCounter(\n METRIC_HTTP_SERVER_ACTIVE_REQUESTS,\n {\n description: 'Number of active (in-flight) HTTP server requests',\n },\n );\n return {\n increment(attrs: Attributes) {\n counter.add(1, attrs);\n },\n decrement(attrs: Attributes) {\n counter.add(-1, attrs);\n },\n };\n}\n","import type { Span, Tracer } from 'autotel';\nimport {\n getTracer,\n getMeter,\n context as otelContext,\n propagation,\n SpanKind,\n SpanStatusCode,\n HTTPAttributes,\n URLAttributes,\n ServiceAttributes,\n httpRequestHeaderAttribute,\n httpResponseHeaderAttribute,\n} from 'autotel';\nimport type { MiddlewareHandler, Context } from 'hono';\nimport { createMiddleware } from 'hono/factory';\nimport { routePath } from 'hono/route';\nimport {\n createRequestDurationTracker,\n createActiveRequestsTracker,\n type HttpMetricsConfig,\n} from './metrics';\n\nconst INSTRUMENTATION_SCOPE_NAME = 'autotel-hono';\n\ntype TimeInput = number | [number, number];\ntype TracerProvider = { getTracer(name: string, version?: string): Tracer };\ntype Meter = HttpMetricsConfig['meter'];\ntype MeterProvider = { getMeter(name: string, version?: string): Meter };\n\nfunction now(): number {\n const p = (globalThis as unknown as { performance?: { now(): number } })\n .performance;\n return p?.now() ?? Date.now();\n}\n\nexport type OtelConfig = {\n tracer?: Tracer;\n tracerProvider?: TracerProvider;\n meter?: Meter;\n meterProvider?: MeterProvider;\n tracerName?: string;\n spanNameFactory?: (c: Context) => string;\n captureRequestHeaders?: string[];\n captureResponseHeaders?: string[];\n captureActiveRequests?: boolean;\n captureRequestDuration?: boolean;\n serviceName?: string;\n serviceVersion?: string;\n disableTracing?: boolean;\n getTime?(): TimeInput;\n};\n\ntype NormalizedOtelConfig = OtelConfig & {\n requestHeaderSet: Set<string>;\n responseHeaderSet: Set<string>;\n captureActiveRequests: boolean;\n captureRequestDuration: boolean;\n};\n\nfunction normalizeConfig(config: OtelConfig = {}): NormalizedOtelConfig {\n const reqHeadersSrc = [...(config.captureRequestHeaders ?? [])];\n const resHeadersSrc = [...(config.captureResponseHeaders ?? [])];\n const requestHeaderSet = new Set(reqHeadersSrc.map((h) => h.toLowerCase()));\n const responseHeaderSet = new Set(resHeadersSrc.map((h) => h.toLowerCase()));\n return {\n ...config,\n requestHeaderSet,\n responseHeaderSet,\n captureActiveRequests: config.captureActiveRequests ?? true,\n captureRequestDuration: config.captureRequestDuration ?? true,\n };\n}\n\nfunction resolveTracer(config: NormalizedOtelConfig): Tracer | undefined {\n if (config.disableTracing) return undefined;\n if (config.tracer) return config.tracer;\n if (config.tracerProvider) {\n return config.tracerProvider.getTracer(\n config.tracerName ?? INSTRUMENTATION_SCOPE_NAME,\n config.serviceVersion,\n );\n }\n return getTracer(config.tracerName ?? INSTRUMENTATION_SCOPE_NAME, config.serviceVersion);\n}\n\nfunction resolveMeter(config: NormalizedOtelConfig): Meter {\n if (config.meter) return config.meter;\n if (config.meterProvider) {\n return config.meterProvider.getMeter(\n INSTRUMENTATION_SCOPE_NAME,\n config.serviceVersion,\n );\n }\n return getMeter();\n}\n\nexport function otel(userConfig: OtelConfig = {}): MiddlewareHandler {\n const config = normalizeConfig(userConfig);\n const tracer = resolveTracer(config);\n const meter = resolveMeter(config);\n\n const metricsConfig: HttpMetricsConfig = {\n meter,\n captureRequestDuration: config.captureRequestDuration,\n captureActiveRequests: config.captureActiveRequests,\n };\n const requestDuration = createRequestDurationTracker(metricsConfig);\n const activeReqs = createActiveRequestsTracker(metricsConfig);\n\n const spanName = (c: Context) =>\n config.spanNameFactory?.(c) ?? `${c.req.method} ${routePath(c)}`;\n\n return createMiddleware(async (c, next) => {\n const method = c.req.method;\n\n const stableAttrs: Record<string, string | number | undefined> = {\n [HTTPAttributes.requestMethod]: method,\n [ServiceAttributes.name]: config.serviceName,\n [ServiceAttributes.version]: config.serviceVersion,\n };\n\n activeReqs?.increment(stableAttrs);\n const startTime = now();\n\n const deferredRequestHeaderAttributes: Record<string, string> = {};\n const reqHeaders = c.req.raw.headers;\n for (const [rawName, value] of reqHeaders.entries()) {\n const name = rawName.toLowerCase();\n if (config.requestHeaderSet.has(name)) {\n deferredRequestHeaderAttributes[httpRequestHeaderAttribute(name)] =\n typeof value === 'string' ? value : value[0] ?? '';\n }\n }\n\n const finalize = (span?: Span, error?: unknown) => {\n try {\n const status = c.res.status;\n\n if (span) {\n for (const [name, value] of c.res.headers.entries()) {\n const lower = name.toLowerCase();\n if (config.responseHeaderSet.has(lower)) {\n span.setAttribute(httpResponseHeaderAttribute(lower), value);\n }\n }\n span.setAttribute(HTTPAttributes.responseStatusCode, status);\n if (status >= 500) {\n span.setStatus({ code: SpanStatusCode.ERROR });\n }\n if (error) {\n try {\n span.recordException(error as Error);\n } catch {\n // Ignore errors when recording exception\n }\n span.setStatus({ code: SpanStatusCode.ERROR });\n }\n }\n } finally {\n activeReqs?.decrement(stableAttrs);\n span?.setAttribute(HTTPAttributes.route, routePath(c));\n span?.updateName(spanName(c));\n const durationSeconds = (now() - startTime) / 1000;\n requestDuration.record(durationSeconds, {\n ...stableAttrs,\n [HTTPAttributes.route]: routePath(c),\n [HTTPAttributes.responseStatusCode]: c.res.status,\n });\n }\n };\n\n if (!tracer) {\n try {\n await next();\n finalize();\n } catch (error) {\n finalize(undefined, error);\n throw error;\n }\n return;\n }\n\n const parent = propagation.extract(otelContext.active(), c.req.header());\n return tracer.startActiveSpan(\n spanName(c),\n {\n kind: SpanKind.SERVER,\n startTime: config.getTime?.(),\n attributes: {\n ...stableAttrs,\n [URLAttributes.full]: c.req.url,\n [HTTPAttributes.route]: routePath(c),\n },\n },\n parent,\n async (span) => {\n try {\n for (const [k, v] of Object.entries(deferredRequestHeaderAttributes)) {\n span.setAttribute(k, v);\n }\n await next();\n finalize(span, c.error);\n } catch (error) {\n finalize(span, error);\n throw error;\n } finally {\n span.end(config.getTime?.());\n }\n },\n );\n });\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "autotel-hono",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.30",
|
|
4
4
|
"description": "OpenTelemetry Hono middleware powered by autotel",
|
|
5
|
+
"license": "MIT",
|
|
5
6
|
"type": "module",
|
|
6
7
|
"main": "./dist/index.js",
|
|
7
8
|
"types": "./dist/index.d.ts",
|
|
@@ -20,8 +21,8 @@
|
|
|
20
21
|
"skills"
|
|
21
22
|
],
|
|
22
23
|
"dependencies": {
|
|
23
|
-
"autotel": "3.
|
|
24
|
-
"autotel-adapters": "0.3.
|
|
24
|
+
"autotel": "3.7.0",
|
|
25
|
+
"autotel-adapters": "0.3.9"
|
|
25
26
|
},
|
|
26
27
|
"peerDependencies": {
|
|
27
28
|
"hono": ">=4.12.23"
|
|
@@ -34,7 +35,7 @@
|
|
|
34
35
|
"devDependencies": {
|
|
35
36
|
"@types/node": "^25.9.2",
|
|
36
37
|
"hono": "^4.12.23",
|
|
37
|
-
"
|
|
38
|
+
"tsdown": "^0.22.2",
|
|
38
39
|
"typescript": "^6.0.3",
|
|
39
40
|
"vitest": "^4.1.8"
|
|
40
41
|
},
|
|
@@ -44,8 +45,8 @@
|
|
|
44
45
|
"directory": "packages/autotel-hono"
|
|
45
46
|
},
|
|
46
47
|
"scripts": {
|
|
47
|
-
"build": "
|
|
48
|
-
"dev": "
|
|
48
|
+
"build": "tsdown",
|
|
49
|
+
"dev": "tsdown --watch",
|
|
49
50
|
"type-check": "tsc --noEmit",
|
|
50
51
|
"lint": "eslint src",
|
|
51
52
|
"test": "vitest run",
|