@openapi-typescript-infra/service 4.5.4 → 4.6.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.
- package/CHANGELOG.md +14 -0
- package/build/express-app/app.js +5 -2
- package/build/express-app/app.js.map +1 -1
- package/build/telemetry/index.js +7 -0
- package/build/telemetry/index.js.map +1 -1
- package/build/telemetry/requestLogger.d.ts +3 -2
- package/build/telemetry/requestLogger.js +12 -5
- package/build/telemetry/requestLogger.js.map +1 -1
- package/build/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/express-app/app.ts +6 -2
- package/src/telemetry/index.ts +10 -0
- package/src/telemetry/requestLogger.ts +19 -4
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openapi-typescript-infra/service",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.6.1",
|
|
4
4
|
"description": "An opinionated framework for building configuration driven services - web, api, or ob. Uses OpenAPI, pino logging, express, confit, Typescript and vitest.",
|
|
5
5
|
"main": "build/index.js",
|
|
6
6
|
"scripts": {
|
package/src/express-app/app.ts
CHANGED
|
@@ -118,7 +118,11 @@ export async function startApp<
|
|
|
118
118
|
app.set('trust proxy', config.trustProxy);
|
|
119
119
|
}
|
|
120
120
|
|
|
121
|
-
app.
|
|
121
|
+
const histogram = app.locals.meter.createHistogram('http_request_duration_seconds', {
|
|
122
|
+
description: 'Duration of HTTP requests in seconds',
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
app.use(loggerMiddleware(app, histogram, logging?.logRequestBody, logging?.logResponseBody));
|
|
122
126
|
|
|
123
127
|
// Allow the service to add locals, etc. We put this before the body parsers
|
|
124
128
|
// so that the req can decide whether to save the raw request body or not.
|
|
@@ -236,7 +240,7 @@ export async function startApp<
|
|
|
236
240
|
app.use(notFoundMiddleware());
|
|
237
241
|
}
|
|
238
242
|
if (errors?.enabled) {
|
|
239
|
-
app.use(errorHandlerMiddleware(app, errors?.unnest, errors?.render));
|
|
243
|
+
app.use(errorHandlerMiddleware(app, histogram, errors?.unnest, errors?.render));
|
|
240
244
|
}
|
|
241
245
|
|
|
242
246
|
return app;
|
package/src/telemetry/index.ts
CHANGED
|
@@ -55,6 +55,16 @@ export function startGlobalTelemetry(serviceName: string) {
|
|
|
55
55
|
resourceDetectors: getResourceDetectors(),
|
|
56
56
|
metricReader: prometheusExporter,
|
|
57
57
|
instrumentations: [getAutoInstrumentations()],
|
|
58
|
+
views: [
|
|
59
|
+
new opentelemetry.metrics.View({
|
|
60
|
+
instrumentName: 'http_request_duration_seconds',
|
|
61
|
+
instrumentType: opentelemetry.metrics.InstrumentType.HISTOGRAM,
|
|
62
|
+
aggregation: new opentelemetry.metrics.ExplicitBucketHistogramAggregation(
|
|
63
|
+
[0.003, 0.03, 0.1, 0.3, 1.5, 10],
|
|
64
|
+
true,
|
|
65
|
+
),
|
|
66
|
+
}),
|
|
67
|
+
],
|
|
58
68
|
});
|
|
59
69
|
telemetrySdk.start();
|
|
60
70
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { RequestHandler, Request, Response, ErrorRequestHandler } from 'express';
|
|
2
|
+
import { Histogram } from '@opentelemetry/api';
|
|
2
3
|
|
|
3
4
|
import { ServiceError } from '../error';
|
|
4
5
|
import type { AnyServiceLocals, RequestWithApp, ServiceExpress, ServiceLocals } from '../types';
|
|
@@ -44,6 +45,7 @@ function finishLog<SLocals extends AnyServiceLocals = ServiceLocals<Configuratio
|
|
|
44
45
|
error: Error | undefined,
|
|
45
46
|
req: Request,
|
|
46
47
|
res: Response,
|
|
48
|
+
histogram: Histogram,
|
|
47
49
|
) {
|
|
48
50
|
const prefs = (res.locals as WithLogPrefs)[LOG_PREFS];
|
|
49
51
|
if (prefs.logged) {
|
|
@@ -61,6 +63,14 @@ function finishLog<SLocals extends AnyServiceLocals = ServiceLocals<Configuratio
|
|
|
61
63
|
dur,
|
|
62
64
|
};
|
|
63
65
|
|
|
66
|
+
const path = req.route ? { path: req.route.path } : undefined;
|
|
67
|
+
histogram.record(dur, {
|
|
68
|
+
status_code: endLog.s,
|
|
69
|
+
method: endLog.m,
|
|
70
|
+
...path,
|
|
71
|
+
service: app.locals.name,
|
|
72
|
+
});
|
|
73
|
+
|
|
64
74
|
if (res.locals.user?.id) {
|
|
65
75
|
endLog.u = res.locals.user.id;
|
|
66
76
|
}
|
|
@@ -95,7 +105,12 @@ function finishLog<SLocals extends AnyServiceLocals = ServiceLocals<Configuratio
|
|
|
95
105
|
|
|
96
106
|
export function loggerMiddleware<
|
|
97
107
|
SLocals extends AnyServiceLocals = ServiceLocals<ConfigurationSchema>,
|
|
98
|
-
>(
|
|
108
|
+
>(
|
|
109
|
+
app: ServiceExpress<SLocals>,
|
|
110
|
+
histogram: Histogram,
|
|
111
|
+
logRequests?: boolean,
|
|
112
|
+
logResponses?: boolean,
|
|
113
|
+
): RequestHandler {
|
|
99
114
|
const { logger, service } = app.locals;
|
|
100
115
|
return function gblogger(req, res, next) {
|
|
101
116
|
const prefs: LogPrefs = {
|
|
@@ -135,7 +150,7 @@ export function loggerMiddleware<
|
|
|
135
150
|
service.getLogFields?.(req as RequestWithApp<SLocals>, preLog);
|
|
136
151
|
logger.info(preLog, 'pre');
|
|
137
152
|
|
|
138
|
-
const logWriter = () => finishLog(app, undefined, req, res);
|
|
153
|
+
const logWriter = () => finishLog(app, undefined, req, res, histogram);
|
|
139
154
|
res.on('finish', logWriter);
|
|
140
155
|
next();
|
|
141
156
|
};
|
|
@@ -143,7 +158,7 @@ export function loggerMiddleware<
|
|
|
143
158
|
|
|
144
159
|
export function errorHandlerMiddleware<
|
|
145
160
|
SLocals extends AnyServiceLocals = ServiceLocals<ConfigurationSchema>,
|
|
146
|
-
>(app: ServiceExpress<SLocals>, unnest?: boolean, returnError?: boolean) {
|
|
161
|
+
>(app: ServiceExpress<SLocals>, histogram: Histogram, unnest?: boolean, returnError?: boolean) {
|
|
147
162
|
const gbErrorHandler: ErrorRequestHandler = (error, req, res, next) => {
|
|
148
163
|
let loggable: Partial<ServiceError> = error;
|
|
149
164
|
const body = error.response?.body || error.body;
|
|
@@ -159,7 +174,7 @@ export function errorHandlerMiddleware<
|
|
|
159
174
|
// Set the status to error, even if we aren't going to render the error.
|
|
160
175
|
res.status(loggable.status || 500);
|
|
161
176
|
if (returnError) {
|
|
162
|
-
finishLog(app, error, req, res);
|
|
177
|
+
finishLog(app, error, req, res, histogram);
|
|
163
178
|
const prefs = (res.locals as WithLogPrefs)[LOG_PREFS];
|
|
164
179
|
prefs.logged = true;
|
|
165
180
|
res.json({
|