-
Notifications
You must be signed in to change notification settings - Fork 1.2k
/
InstrumentationMiddleware.ts
40 lines (33 loc) · 1.37 KB
/
InstrumentationMiddleware.ts
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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0
import { NextApiHandler } from 'next';
import {context, Exception, Span, SpanStatusCode, trace} from '@opentelemetry/api';
import { SemanticAttributes } from '@opentelemetry/semantic-conventions';
import { metrics } from '@opentelemetry/api';
const meter = metrics.getMeter('frontend');
const requestCounter = meter.createCounter('app.frontend.requests');
const InstrumentationMiddleware = (handler: NextApiHandler): NextApiHandler => {
return async (request, response) => {
const {method, url = ''} = request;
const [target] = url.split('?');
const span = trace.getSpan(context.active()) as Span;
let httpStatus = 200;
try {
await runWithSpan(span, async () => handler(request, response));
httpStatus = response.statusCode;
} catch (error) {
span.recordException(error as Exception);
span.setStatus({ code: SpanStatusCode.ERROR });
httpStatus = 500;
throw error;
} finally {
requestCounter.add(1, { method, target, status: httpStatus });
span.setAttribute(SemanticAttributes.HTTP_STATUS_CODE, httpStatus);
}
};
};
async function runWithSpan(parentSpan: Span, fn: () => Promise<unknown>) {
const ctx = trace.setSpan(context.active(), parentSpan);
return await context.with(ctx, fn);
}
export default InstrumentationMiddleware;