logixia 1.2.1 → 1.3.0
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-BDRSTjUt.d.ts → index-CHIsdA9n.d.ts} +53 -2
- package/dist/index-CHIsdA9n.d.ts.map +1 -0
- package/dist/{index-Drrzn-Yg.d.mts → index-iDTW2-eY.d.mts} +53 -2
- package/dist/index-iDTW2-eY.d.mts.map +1 -0
- package/dist/index.d.mts +89 -3
- package/dist/index.d.mts.map +1 -1
- package/dist/index.d.ts +89 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -2
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +3 -3
- package/dist/index.mjs.map +1 -1
- package/dist/{logitron-logger.module-iO8DPE7_.mjs → logitron-logger.module-2AzkadqZ.mjs} +226 -8
- package/dist/logitron-logger.module-2AzkadqZ.mjs.map +1 -0
- package/dist/{logitron-logger.module-X6nGDVGC.js → logitron-logger.module-BqNKp0Fs.js} +240 -4
- package/dist/logitron-logger.module-BqNKp0Fs.js.map +1 -0
- package/dist/{logitron-logger.module-CY3t8yK6.d.mts → logitron-logger.module-C0G8JGVf.d.ts} +6 -4
- package/dist/logitron-logger.module-C0G8JGVf.d.ts.map +1 -0
- package/dist/{logitron-logger.module-DgEldK9V.d.ts → logitron-logger.module-DQKaZTJL.d.mts} +6 -4
- package/dist/logitron-logger.module-DQKaZTJL.d.mts.map +1 -0
- package/dist/middleware.d.mts +83 -0
- package/dist/middleware.d.mts.map +1 -0
- package/dist/middleware.d.ts +83 -0
- package/dist/middleware.d.ts.map +1 -0
- package/dist/middleware.js +132 -0
- package/dist/middleware.js.map +1 -0
- package/dist/middleware.mjs +130 -0
- package/dist/middleware.mjs.map +1 -0
- package/dist/nest.d.mts +2 -2
- package/dist/nest.d.ts +2 -2
- package/dist/nest.js +2 -2
- package/dist/nest.mjs +2 -2
- package/dist/testing.d.mts +67 -0
- package/dist/testing.d.mts.map +1 -0
- package/dist/testing.d.ts +67 -0
- package/dist/testing.d.ts.map +1 -0
- package/dist/testing.js +164 -0
- package/dist/testing.js.map +1 -0
- package/dist/testing.mjs +163 -0
- package/dist/testing.mjs.map +1 -0
- package/dist/{transport.manager-Vi__pagn.mjs → transport.manager-5VVdqS3o.mjs} +51 -2
- package/dist/transport.manager-5VVdqS3o.mjs.map +1 -0
- package/dist/{transport.manager-C3Xr7Tvi.js → transport.manager-DCOm4uIQ.js} +51 -2
- package/dist/transport.manager-DCOm4uIQ.js.map +1 -0
- package/dist/transports.d.mts +38 -1
- package/dist/transports.d.mts.map +1 -1
- package/dist/transports.d.ts +38 -1
- package/dist/transports.d.ts.map +1 -1
- package/dist/transports.js +1 -1
- package/dist/transports.mjs +1 -1
- package/package.json +21 -1
- package/dist/index-BDRSTjUt.d.ts.map +0 -1
- package/dist/index-Drrzn-Yg.d.mts.map +0 -1
- package/dist/logitron-logger.module-CY3t8yK6.d.mts.map +0 -1
- package/dist/logitron-logger.module-DgEldK9V.d.ts.map +0 -1
- package/dist/logitron-logger.module-X6nGDVGC.js.map +0 -1
- package/dist/logitron-logger.module-iO8DPE7_.mjs.map +0 -1
- package/dist/transport.manager-C3Xr7Tvi.js.map +0 -1
- package/dist/transport.manager-Vi__pagn.mjs.map +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { _ as LogLevelString, d as ILogger, f as ILoggerDefault, v as LoggerConfig,
|
|
1
|
+
import { T as TraceIdConfig, _ as LogLevelString, d as ILogger, f as ILoggerDefault, v as LoggerConfig, y as LoggerWithLevels } from "./index-CHIsdA9n.js";
|
|
2
2
|
import * as _nestjs_common0 from "@nestjs/common";
|
|
3
3
|
import { CallHandler, ExecutionContext, InjectionToken, LoggerService, MiddlewareConsumer, ModuleMetadata, NestInterceptor, NestModule, OptionalFactoryDependency, Type } from "@nestjs/common";
|
|
4
4
|
import { Observable } from "rxjs";
|
|
@@ -34,6 +34,8 @@ declare class LogixiaLogger<TConfig extends LoggerConfig<Record<string, number>>
|
|
|
34
34
|
private _formattedAppName;
|
|
35
35
|
/** True when a redact config is present — short-circuits applyRedaction when false. */
|
|
36
36
|
private _hasRedact;
|
|
37
|
+
/** Sampling engine — only created when sampling config is present. */
|
|
38
|
+
private _sampler?;
|
|
37
39
|
constructor(config: TConfig, context?: string);
|
|
38
40
|
private setupGracefulShutdown;
|
|
39
41
|
private createCustomLevelMethods;
|
|
@@ -219,7 +221,7 @@ declare class LogixiaLoggerModule implements NestModule {
|
|
|
219
221
|
inject: string[];
|
|
220
222
|
useValue?: never;
|
|
221
223
|
})[];
|
|
222
|
-
exports: (string | typeof
|
|
224
|
+
exports: (string | typeof WebSocketTraceInterceptor | typeof KafkaTraceInterceptor | typeof LogixiaLoggerService)[];
|
|
223
225
|
global: boolean;
|
|
224
226
|
};
|
|
225
227
|
/**
|
|
@@ -256,7 +258,7 @@ declare class LogixiaLoggerModule implements NestModule {
|
|
|
256
258
|
useFactory: (traceConfig: any) => WebSocketTraceInterceptor;
|
|
257
259
|
inject: string[];
|
|
258
260
|
})[];
|
|
259
|
-
exports: (string | typeof
|
|
261
|
+
exports: (string | typeof WebSocketTraceInterceptor | typeof KafkaTraceInterceptor | typeof LogixiaLoggerService)[];
|
|
260
262
|
global: boolean;
|
|
261
263
|
};
|
|
262
264
|
/**
|
|
@@ -276,4 +278,4 @@ declare class LogixiaLoggerModule implements NestModule {
|
|
|
276
278
|
}
|
|
277
279
|
//#endregion
|
|
278
280
|
export { LogixiaOptionsFactory as a, LogixiaLoggerService as c, LogixiaLoggerModule as i, LogixiaLogger as l, LOGIXIA_LOGGER_PREFIX as n, WebSocketTraceInterceptor as o, LogixiaAsyncOptions as r, KafkaTraceInterceptor as s, LOGIXIA_LOGGER_CONFIG as t, createLogger as u };
|
|
279
|
-
//# sourceMappingURL=logitron-logger.module-
|
|
281
|
+
//# sourceMappingURL=logitron-logger.module-C0G8JGVf.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logitron-logger.module-C0G8JGVf.d.ts","names":[],"sources":["../src/core/logitron-logger.ts","../src/core/logitron-nestjs.service.ts","../src/core/kafka-trace.interceptor.ts","../src/core/websocket-trace.interceptor.ts","../src/core/logitron-logger.module.ts"],"sourcesContent":[],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { _ as LogLevelString, d as ILogger, f as ILoggerDefault, v as LoggerConfig,
|
|
1
|
+
import { T as TraceIdConfig, _ as LogLevelString, d as ILogger, f as ILoggerDefault, v as LoggerConfig, y as LoggerWithLevels } from "./index-iDTW2-eY.mjs";
|
|
2
2
|
import * as _nestjs_common0 from "@nestjs/common";
|
|
3
3
|
import { CallHandler, ExecutionContext, InjectionToken, LoggerService, MiddlewareConsumer, ModuleMetadata, NestInterceptor, NestModule, OptionalFactoryDependency, Type } from "@nestjs/common";
|
|
4
4
|
import { Observable } from "rxjs";
|
|
@@ -34,6 +34,8 @@ declare class LogixiaLogger<TConfig extends LoggerConfig<Record<string, number>>
|
|
|
34
34
|
private _formattedAppName;
|
|
35
35
|
/** True when a redact config is present — short-circuits applyRedaction when false. */
|
|
36
36
|
private _hasRedact;
|
|
37
|
+
/** Sampling engine — only created when sampling config is present. */
|
|
38
|
+
private _sampler?;
|
|
37
39
|
constructor(config: TConfig, context?: string);
|
|
38
40
|
private setupGracefulShutdown;
|
|
39
41
|
private createCustomLevelMethods;
|
|
@@ -219,7 +221,7 @@ declare class LogixiaLoggerModule implements NestModule {
|
|
|
219
221
|
inject: string[];
|
|
220
222
|
useValue?: never;
|
|
221
223
|
})[];
|
|
222
|
-
exports: (string | typeof
|
|
224
|
+
exports: (string | typeof WebSocketTraceInterceptor | typeof KafkaTraceInterceptor | typeof LogixiaLoggerService)[];
|
|
223
225
|
global: boolean;
|
|
224
226
|
};
|
|
225
227
|
/**
|
|
@@ -256,7 +258,7 @@ declare class LogixiaLoggerModule implements NestModule {
|
|
|
256
258
|
useFactory: (traceConfig: any) => WebSocketTraceInterceptor;
|
|
257
259
|
inject: string[];
|
|
258
260
|
})[];
|
|
259
|
-
exports: (string | typeof
|
|
261
|
+
exports: (string | typeof WebSocketTraceInterceptor | typeof KafkaTraceInterceptor | typeof LogixiaLoggerService)[];
|
|
260
262
|
global: boolean;
|
|
261
263
|
};
|
|
262
264
|
/**
|
|
@@ -276,4 +278,4 @@ declare class LogixiaLoggerModule implements NestModule {
|
|
|
276
278
|
}
|
|
277
279
|
//#endregion
|
|
278
280
|
export { LogixiaOptionsFactory as a, LogixiaLoggerService as c, LogixiaLoggerModule as i, LogixiaLogger as l, LOGIXIA_LOGGER_PREFIX as n, WebSocketTraceInterceptor as o, LogixiaAsyncOptions as r, KafkaTraceInterceptor as s, LOGIXIA_LOGGER_CONFIG as t, createLogger as u };
|
|
279
|
-
//# sourceMappingURL=logitron-logger.module-
|
|
281
|
+
//# sourceMappingURL=logitron-logger.module-DQKaZTJL.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logitron-logger.module-DQKaZTJL.d.mts","names":[],"sources":["../src/core/logitron-logger.ts","../src/core/logitron-nestjs.service.ts","../src/core/kafka-trace.interceptor.ts","../src/core/websocket-trace.interceptor.ts","../src/core/logitron-logger.module.ts"],"sourcesContent":[],"mappings":"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"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { l as IBaseLogger } from "./index-iDTW2-eY.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/middleware/http-logger.d.ts
|
|
4
|
+
|
|
5
|
+
interface HttpLoggerOptions {
|
|
6
|
+
/**
|
|
7
|
+
* Skip logging for a request. Called before any I/O.
|
|
8
|
+
* @example `skip: (req) => req.url === '/health'`
|
|
9
|
+
*/
|
|
10
|
+
skip?: (req: IncomingRequest) => boolean;
|
|
11
|
+
/**
|
|
12
|
+
* Log request body (POST/PUT/PATCH). Capped at `bodyMaxBytes` (default: 4096).
|
|
13
|
+
* Redaction still applies to the captured body.
|
|
14
|
+
* Default: false.
|
|
15
|
+
*/
|
|
16
|
+
logBody?: boolean;
|
|
17
|
+
/** Max bytes of body to capture. Default: 4096. */
|
|
18
|
+
bodyMaxBytes?: number;
|
|
19
|
+
/**
|
|
20
|
+
* Emit a WARN log when a request duration exceeds this threshold (ms).
|
|
21
|
+
* Default: 1000.
|
|
22
|
+
*/
|
|
23
|
+
slowRequestThresholdMs?: number;
|
|
24
|
+
/**
|
|
25
|
+
* Additional fields to include in every log entry.
|
|
26
|
+
* @example `extraFields: (req) => ({ tenantId: req.headers['x-tenant-id'] })`
|
|
27
|
+
*/
|
|
28
|
+
extraFields?: (req: IncomingRequest) => Record<string, unknown>;
|
|
29
|
+
/**
|
|
30
|
+
* Request ID header. Default: 'x-request-id'.
|
|
31
|
+
* If the header is absent, a short random ID is generated.
|
|
32
|
+
*/
|
|
33
|
+
requestIdHeader?: string;
|
|
34
|
+
/**
|
|
35
|
+
* Headers to redact from logged output.
|
|
36
|
+
* Default: ['authorization', 'cookie', 'set-cookie', 'x-api-key'].
|
|
37
|
+
*/
|
|
38
|
+
redactHeaders?: string[];
|
|
39
|
+
/**
|
|
40
|
+
* Log level for request-start entries. Default: 'debug'.
|
|
41
|
+
* Set to 'silent' to suppress request-start logs entirely.
|
|
42
|
+
*/
|
|
43
|
+
requestLevel?: string;
|
|
44
|
+
/** Log level for successful response entries. Default: 'info'. */
|
|
45
|
+
responseLevel?: string;
|
|
46
|
+
/** Log level for error responses (status ≥ 500). Default: 'error'. */
|
|
47
|
+
errorLevel?: string;
|
|
48
|
+
}
|
|
49
|
+
interface IncomingRequest {
|
|
50
|
+
method?: string;
|
|
51
|
+
url?: string;
|
|
52
|
+
headers?: Record<string, string | string[] | undefined>;
|
|
53
|
+
body?: unknown;
|
|
54
|
+
socket?: {
|
|
55
|
+
remoteAddress?: string;
|
|
56
|
+
};
|
|
57
|
+
ip?: string;
|
|
58
|
+
}
|
|
59
|
+
interface OutgoingResponse {
|
|
60
|
+
statusCode?: number;
|
|
61
|
+
on?: (event: string, cb: () => void) => void;
|
|
62
|
+
once?: (event: string, cb: () => void) => void;
|
|
63
|
+
getHeader?: (name: string) => string | number | string[] | undefined;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Create an Express / Connect compatible middleware that replaces Morgan.
|
|
67
|
+
*/
|
|
68
|
+
declare function createExpressMiddleware(logger: IBaseLogger, options?: HttpLoggerOptions): (req: IncomingRequest, res: OutgoingResponse, next: () => void) => void;
|
|
69
|
+
interface FastifyInstance {
|
|
70
|
+
addHook: (name: string, fn: (req: unknown, reply: unknown, done: () => void) => void) => void;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Create a Fastify plugin (a function you pass to `fastify.register()`).
|
|
74
|
+
*
|
|
75
|
+
* @example
|
|
76
|
+
* ```ts
|
|
77
|
+
* await fastify.register(createFastifyPlugin(logger, { slowRequestThresholdMs: 500 }));
|
|
78
|
+
* ```
|
|
79
|
+
*/
|
|
80
|
+
declare function createFastifyPlugin(logger: IBaseLogger, options?: HttpLoggerOptions): (fastify: FastifyInstance, _opts: unknown, done: () => void) => void;
|
|
81
|
+
//#endregion
|
|
82
|
+
export { type FastifyInstance, type HttpLoggerOptions, type IncomingRequest, type OutgoingResponse, createExpressMiddleware, createFastifyPlugin };
|
|
83
|
+
//# sourceMappingURL=middleware.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"middleware.d.mts","names":[],"sources":["../src/middleware/http-logger.ts"],"sourcesContent":[],"mappings":";;;;UA6BiB,iBAAA;;;;;eAKF;;;;;;;;;;;;;;;;;;sBAkBO,oBAAoB;;;;;;;;;;;;;;;;;;;;;UAuBzB,eAAA;;;YAGL;;;;;;;UAMK,gBAAA;;;;;;;;;iBAyDD,uBAAA,SACN,uBACC,0BACF,sBAAsB;UAsEd,eAAA;;;;;;;;;;;iBAYD,mBAAA,SAA4B,uBAAsB,8BAWrD"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { l as IBaseLogger } from "./index-CHIsdA9n.js";
|
|
2
|
+
|
|
3
|
+
//#region src/middleware/http-logger.d.ts
|
|
4
|
+
|
|
5
|
+
interface HttpLoggerOptions {
|
|
6
|
+
/**
|
|
7
|
+
* Skip logging for a request. Called before any I/O.
|
|
8
|
+
* @example `skip: (req) => req.url === '/health'`
|
|
9
|
+
*/
|
|
10
|
+
skip?: (req: IncomingRequest) => boolean;
|
|
11
|
+
/**
|
|
12
|
+
* Log request body (POST/PUT/PATCH). Capped at `bodyMaxBytes` (default: 4096).
|
|
13
|
+
* Redaction still applies to the captured body.
|
|
14
|
+
* Default: false.
|
|
15
|
+
*/
|
|
16
|
+
logBody?: boolean;
|
|
17
|
+
/** Max bytes of body to capture. Default: 4096. */
|
|
18
|
+
bodyMaxBytes?: number;
|
|
19
|
+
/**
|
|
20
|
+
* Emit a WARN log when a request duration exceeds this threshold (ms).
|
|
21
|
+
* Default: 1000.
|
|
22
|
+
*/
|
|
23
|
+
slowRequestThresholdMs?: number;
|
|
24
|
+
/**
|
|
25
|
+
* Additional fields to include in every log entry.
|
|
26
|
+
* @example `extraFields: (req) => ({ tenantId: req.headers['x-tenant-id'] })`
|
|
27
|
+
*/
|
|
28
|
+
extraFields?: (req: IncomingRequest) => Record<string, unknown>;
|
|
29
|
+
/**
|
|
30
|
+
* Request ID header. Default: 'x-request-id'.
|
|
31
|
+
* If the header is absent, a short random ID is generated.
|
|
32
|
+
*/
|
|
33
|
+
requestIdHeader?: string;
|
|
34
|
+
/**
|
|
35
|
+
* Headers to redact from logged output.
|
|
36
|
+
* Default: ['authorization', 'cookie', 'set-cookie', 'x-api-key'].
|
|
37
|
+
*/
|
|
38
|
+
redactHeaders?: string[];
|
|
39
|
+
/**
|
|
40
|
+
* Log level for request-start entries. Default: 'debug'.
|
|
41
|
+
* Set to 'silent' to suppress request-start logs entirely.
|
|
42
|
+
*/
|
|
43
|
+
requestLevel?: string;
|
|
44
|
+
/** Log level for successful response entries. Default: 'info'. */
|
|
45
|
+
responseLevel?: string;
|
|
46
|
+
/** Log level for error responses (status ≥ 500). Default: 'error'. */
|
|
47
|
+
errorLevel?: string;
|
|
48
|
+
}
|
|
49
|
+
interface IncomingRequest {
|
|
50
|
+
method?: string;
|
|
51
|
+
url?: string;
|
|
52
|
+
headers?: Record<string, string | string[] | undefined>;
|
|
53
|
+
body?: unknown;
|
|
54
|
+
socket?: {
|
|
55
|
+
remoteAddress?: string;
|
|
56
|
+
};
|
|
57
|
+
ip?: string;
|
|
58
|
+
}
|
|
59
|
+
interface OutgoingResponse {
|
|
60
|
+
statusCode?: number;
|
|
61
|
+
on?: (event: string, cb: () => void) => void;
|
|
62
|
+
once?: (event: string, cb: () => void) => void;
|
|
63
|
+
getHeader?: (name: string) => string | number | string[] | undefined;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Create an Express / Connect compatible middleware that replaces Morgan.
|
|
67
|
+
*/
|
|
68
|
+
declare function createExpressMiddleware(logger: IBaseLogger, options?: HttpLoggerOptions): (req: IncomingRequest, res: OutgoingResponse, next: () => void) => void;
|
|
69
|
+
interface FastifyInstance {
|
|
70
|
+
addHook: (name: string, fn: (req: unknown, reply: unknown, done: () => void) => void) => void;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Create a Fastify plugin (a function you pass to `fastify.register()`).
|
|
74
|
+
*
|
|
75
|
+
* @example
|
|
76
|
+
* ```ts
|
|
77
|
+
* await fastify.register(createFastifyPlugin(logger, { slowRequestThresholdMs: 500 }));
|
|
78
|
+
* ```
|
|
79
|
+
*/
|
|
80
|
+
declare function createFastifyPlugin(logger: IBaseLogger, options?: HttpLoggerOptions): (fastify: FastifyInstance, _opts: unknown, done: () => void) => void;
|
|
81
|
+
//#endregion
|
|
82
|
+
export { type FastifyInstance, type HttpLoggerOptions, type IncomingRequest, type OutgoingResponse, createExpressMiddleware, createFastifyPlugin };
|
|
83
|
+
//# sourceMappingURL=middleware.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"middleware.d.ts","names":[],"sources":["../src/middleware/http-logger.ts"],"sourcesContent":[],"mappings":";;;;UA6BiB,iBAAA;;;;;eAKF;;;;;;;;;;;;;;;;;;sBAkBO,oBAAoB;;;;;;;;;;;;;;;;;;;;;UAuBzB,eAAA;;;YAGL;;;;;;;UAMK,gBAAA;;;;;;;;;iBAyDD,uBAAA,SACN,uBACC,0BACF,sBAAsB;UAsEd,eAAA;;;;;;;;;;;iBAYD,mBAAA,SAA4B,uBAAsB,8BAWrD"}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
|
|
2
|
+
//#region src/middleware/http-logger.ts
|
|
3
|
+
const DEFAULT_REDACT_HEADERS = new Set([
|
|
4
|
+
"authorization",
|
|
5
|
+
"cookie",
|
|
6
|
+
"set-cookie",
|
|
7
|
+
"x-api-key"
|
|
8
|
+
]);
|
|
9
|
+
function sanitizeHeaders(headers, redactSet) {
|
|
10
|
+
if (!headers) return {};
|
|
11
|
+
const out = {};
|
|
12
|
+
for (const [k, v] of Object.entries(headers)) out[k] = redactSet.has(k.toLowerCase()) ? "[REDACTED]" : v;
|
|
13
|
+
return out;
|
|
14
|
+
}
|
|
15
|
+
function shortId() {
|
|
16
|
+
return Math.random().toString(36).slice(2, 10);
|
|
17
|
+
}
|
|
18
|
+
function buildBaseFields(req, requestId, options) {
|
|
19
|
+
var _req$method, _req$socket;
|
|
20
|
+
const redactSet = options.redactHeaders ? new Set(options.redactHeaders.map((h) => h.toLowerCase())) : DEFAULT_REDACT_HEADERS;
|
|
21
|
+
const fields = {
|
|
22
|
+
requestId,
|
|
23
|
+
method: ((_req$method = req.method) === null || _req$method === void 0 ? void 0 : _req$method.toUpperCase()) ?? "UNKNOWN",
|
|
24
|
+
url: req.url ?? "/",
|
|
25
|
+
ip: req.ip ?? ((_req$socket = req.socket) === null || _req$socket === void 0 ? void 0 : _req$socket.remoteAddress) ?? "unknown",
|
|
26
|
+
headers: sanitizeHeaders(req.headers, redactSet)
|
|
27
|
+
};
|
|
28
|
+
if (options.extraFields) Object.assign(fields, options.extraFields(req));
|
|
29
|
+
return fields;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Create an Express / Connect compatible middleware that replaces Morgan.
|
|
33
|
+
*/
|
|
34
|
+
function createExpressMiddleware(logger, options = {}) {
|
|
35
|
+
const { skip, logBody, bodyMaxBytes, requestIdHeader = "x-request-id", requestLevel = "debug", responseLevel = "info", errorLevel = "error", slowRequestThresholdMs = 1e3 } = options;
|
|
36
|
+
return function logixiaHttpMiddleware(req, res, next) {
|
|
37
|
+
var _req$headers, _res$once, _res$once2;
|
|
38
|
+
if (skip === null || skip === void 0 ? void 0 : skip(req)) {
|
|
39
|
+
next();
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
const requestId = ((_req$headers = req.headers) === null || _req$headers === void 0 ? void 0 : _req$headers[requestIdHeader]) ?? shortId();
|
|
43
|
+
const startMs = Date.now();
|
|
44
|
+
const baseFields = buildBaseFields(req, requestId, options);
|
|
45
|
+
if (requestLevel !== "silent") logger.logLevel(requestLevel, "request started", {
|
|
46
|
+
...baseFields,
|
|
47
|
+
...logBody && req.body ? { body: truncateBody(req.body, bodyMaxBytes) } : {}
|
|
48
|
+
});
|
|
49
|
+
const onFinish = () => {
|
|
50
|
+
const duration = Date.now() - startMs;
|
|
51
|
+
const status = res.statusCode ?? 0;
|
|
52
|
+
const level = status >= 500 ? errorLevel : responseLevel;
|
|
53
|
+
logger.logLevel(level, "request completed", {
|
|
54
|
+
...baseFields,
|
|
55
|
+
statusCode: status,
|
|
56
|
+
duration
|
|
57
|
+
});
|
|
58
|
+
if (duration > slowRequestThresholdMs) logger.warn("slow request detected", {
|
|
59
|
+
...baseFields,
|
|
60
|
+
statusCode: status,
|
|
61
|
+
duration,
|
|
62
|
+
threshold: slowRequestThresholdMs
|
|
63
|
+
});
|
|
64
|
+
};
|
|
65
|
+
(_res$once = res.once) === null || _res$once === void 0 || _res$once.call(res, "finish", onFinish);
|
|
66
|
+
(_res$once2 = res.once) === null || _res$once2 === void 0 || _res$once2.call(res, "close", () => {
|
|
67
|
+
if ((res.statusCode ?? 0) === 0) onFinish();
|
|
68
|
+
});
|
|
69
|
+
next();
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Create a Fastify plugin (a function you pass to `fastify.register()`).
|
|
74
|
+
*
|
|
75
|
+
* @example
|
|
76
|
+
* ```ts
|
|
77
|
+
* await fastify.register(createFastifyPlugin(logger, { slowRequestThresholdMs: 500 }));
|
|
78
|
+
* ```
|
|
79
|
+
*/
|
|
80
|
+
function createFastifyPlugin(logger, options = {}) {
|
|
81
|
+
const { skip, requestIdHeader = "x-request-id", requestLevel = "debug", responseLevel = "info", errorLevel = "error", slowRequestThresholdMs = 1e3 } = options;
|
|
82
|
+
return function logixiaFastifyPlugin(fastify, _opts, done) {
|
|
83
|
+
fastify.addHook("onRequest", (request, _reply, hookDone) => {
|
|
84
|
+
var _req$headers2;
|
|
85
|
+
const req = request;
|
|
86
|
+
if (skip === null || skip === void 0 ? void 0 : skip(req)) {
|
|
87
|
+
hookDone();
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
const requestId = ((_req$headers2 = req.headers) === null || _req$headers2 === void 0 ? void 0 : _req$headers2[requestIdHeader]) ?? shortId();
|
|
91
|
+
req._logixiaStart = Date.now();
|
|
92
|
+
req._logixiaId = requestId;
|
|
93
|
+
if (requestLevel !== "silent") logger.logLevel(requestLevel, "request started", buildBaseFields(req, requestId, options));
|
|
94
|
+
hookDone();
|
|
95
|
+
});
|
|
96
|
+
fastify.addHook("onResponse", (request, reply, hookDone) => {
|
|
97
|
+
const req = request;
|
|
98
|
+
const rep = reply;
|
|
99
|
+
const duration = Date.now() - (req._logixiaStart ?? Date.now());
|
|
100
|
+
const status = rep.statusCode ?? 0;
|
|
101
|
+
const requestId = req._logixiaId ?? shortId();
|
|
102
|
+
const level = status >= 500 ? errorLevel : responseLevel;
|
|
103
|
+
logger.logLevel(level, "request completed", {
|
|
104
|
+
...buildBaseFields(req, requestId, options),
|
|
105
|
+
statusCode: status,
|
|
106
|
+
duration
|
|
107
|
+
});
|
|
108
|
+
if (duration > slowRequestThresholdMs) logger.warn("slow request detected", {
|
|
109
|
+
requestId,
|
|
110
|
+
url: req.url,
|
|
111
|
+
method: req.method,
|
|
112
|
+
duration,
|
|
113
|
+
threshold: slowRequestThresholdMs
|
|
114
|
+
});
|
|
115
|
+
hookDone();
|
|
116
|
+
});
|
|
117
|
+
done();
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
function truncateBody(body, maxBytes = 4096) {
|
|
121
|
+
if (typeof body === "string") return body.length > maxBytes ? body.slice(0, maxBytes) + "…[truncated]" : body;
|
|
122
|
+
if (body && typeof body === "object") {
|
|
123
|
+
const str = JSON.stringify(body);
|
|
124
|
+
if (str.length > maxBytes) return str.slice(0, maxBytes) + "…[truncated]";
|
|
125
|
+
}
|
|
126
|
+
return body;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
//#endregion
|
|
130
|
+
exports.createExpressMiddleware = createExpressMiddleware;
|
|
131
|
+
exports.createFastifyPlugin = createFastifyPlugin;
|
|
132
|
+
//# sourceMappingURL=middleware.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"middleware.js","names":["out: Record<string, unknown>","fields: Record<string, unknown>"],"sources":["../src/middleware/http-logger.ts"],"sourcesContent":["/**\n * HTTP request/response logging middleware — Morgan replacement.\n *\n * Fixes every documented Morgan bug:\n * - statusCode always captured correctly, even for requests > 20 s\n * - Logs request START (with requestId) and response FINISH (with duration)\n * - Captures errors before and after response\n * - Auto-redacts Authorization / Cookie / Set-Cookie headers\n * - Slow-request warnings\n * - Skip predicates for health-check routes / static assets\n *\n * @example Express\n * ```ts\n * import { createExpressMiddleware } from 'logixia/middleware';\n * app.use(createExpressMiddleware(logger));\n * ```\n *\n * @example Fastify\n * ```ts\n * import { createFastifyPlugin } from 'logixia/middleware';\n * await fastify.register(createFastifyPlugin(logger));\n * ```\n */\n\n/* eslint-disable sonarjs/void-use -- intentional fire-and-forget in sync middleware callbacks */\nimport type { IBaseLogger } from '../types';\n\n// ── Shared types ─────────────────────────────────────────────────────────────\n\nexport interface HttpLoggerOptions {\n /**\n * Skip logging for a request. Called before any I/O.\n * @example `skip: (req) => req.url === '/health'`\n */\n skip?: (req: IncomingRequest) => boolean;\n /**\n * Log request body (POST/PUT/PATCH). Capped at `bodyMaxBytes` (default: 4096).\n * Redaction still applies to the captured body.\n * Default: false.\n */\n logBody?: boolean;\n /** Max bytes of body to capture. Default: 4096. */\n bodyMaxBytes?: number;\n /**\n * Emit a WARN log when a request duration exceeds this threshold (ms).\n * Default: 1000.\n */\n slowRequestThresholdMs?: number;\n /**\n * Additional fields to include in every log entry.\n * @example `extraFields: (req) => ({ tenantId: req.headers['x-tenant-id'] })`\n */\n extraFields?: (req: IncomingRequest) => Record<string, unknown>;\n /**\n * Request ID header. Default: 'x-request-id'.\n * If the header is absent, a short random ID is generated.\n */\n requestIdHeader?: string;\n /**\n * Headers to redact from logged output.\n * Default: ['authorization', 'cookie', 'set-cookie', 'x-api-key'].\n */\n redactHeaders?: string[];\n /**\n * Log level for request-start entries. Default: 'debug'.\n * Set to 'silent' to suppress request-start logs entirely.\n */\n requestLevel?: string;\n /** Log level for successful response entries. Default: 'info'. */\n responseLevel?: string;\n /** Log level for error responses (status ≥ 500). Default: 'error'. */\n errorLevel?: string;\n}\n\n// Minimal structural types so we don't need @types/express / fastify in core\nexport interface IncomingRequest {\n method?: string;\n url?: string;\n headers?: Record<string, string | string[] | undefined>;\n body?: unknown;\n socket?: { remoteAddress?: string };\n ip?: string;\n}\n\nexport interface OutgoingResponse {\n statusCode?: number;\n on?: (event: string, cb: () => void) => void;\n once?: (event: string, cb: () => void) => void;\n getHeader?: (name: string) => string | number | string[] | undefined;\n}\n\n// ── Helpers ───────────────────────────────────────────────────────────────────\n\nconst DEFAULT_REDACT_HEADERS = new Set(['authorization', 'cookie', 'set-cookie', 'x-api-key']);\n\nfunction sanitizeHeaders(\n headers: Record<string, string | string[] | undefined> | undefined,\n redactSet: Set<string>\n): Record<string, unknown> {\n if (!headers) return {};\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(headers)) {\n out[k] = redactSet.has(k.toLowerCase()) ? '[REDACTED]' : v;\n }\n return out;\n}\n\nfunction shortId(): string {\n // eslint-disable-next-line sonarjs/pseudo-random -- non-security request ID\n return Math.random().toString(36).slice(2, 10);\n}\n\nfunction buildBaseFields(\n req: IncomingRequest,\n requestId: string,\n options: HttpLoggerOptions\n): Record<string, unknown> {\n const redactSet = options.redactHeaders\n ? new Set(options.redactHeaders.map((h) => h.toLowerCase()))\n : DEFAULT_REDACT_HEADERS;\n\n const fields: Record<string, unknown> = {\n requestId,\n method: req.method?.toUpperCase() ?? 'UNKNOWN',\n url: req.url ?? '/',\n ip: req.ip ?? req.socket?.remoteAddress ?? 'unknown',\n headers: sanitizeHeaders(req.headers, redactSet),\n };\n\n if (options.extraFields) {\n Object.assign(fields, options.extraFields(req));\n }\n\n return fields;\n}\n\n// ── Express middleware ────────────────────────────────────────────────────────\n\n/**\n * Create an Express / Connect compatible middleware that replaces Morgan.\n */\nexport function createExpressMiddleware(\n logger: IBaseLogger,\n options: HttpLoggerOptions = {}\n): (req: IncomingRequest, res: OutgoingResponse, next: () => void) => void {\n const {\n skip,\n logBody,\n bodyMaxBytes,\n requestIdHeader = 'x-request-id',\n requestLevel = 'debug',\n responseLevel = 'info',\n errorLevel = 'error',\n slowRequestThresholdMs = 1000,\n } = options;\n\n return function logixiaHttpMiddleware(\n req: IncomingRequest,\n res: OutgoingResponse,\n next: () => void\n ): void {\n if (skip?.(req)) {\n next();\n return;\n }\n\n const requestId = (req.headers?.[requestIdHeader] as string | undefined) ?? shortId();\n const startMs = Date.now();\n const baseFields = buildBaseFields(req, requestId, options);\n\n // Log request start\n if (requestLevel !== 'silent') {\n void logger.logLevel(requestLevel, 'request started', {\n ...baseFields,\n ...(logBody && req.body ? { body: truncateBody(req.body, bodyMaxBytes) } : {}),\n });\n }\n\n // Hook into the response 'finish' event — fires after headers + body are sent.\n // This is what Morgan gets wrong for slow requests (it uses 'close' which may\n // fire before the status code is set on some Node versions).\n const onFinish = (): void => {\n const duration = Date.now() - startMs;\n const status = res.statusCode ?? 0;\n const level = status >= 500 ? errorLevel : responseLevel;\n\n void logger.logLevel(level, 'request completed', {\n ...baseFields,\n statusCode: status,\n duration,\n });\n\n if (duration > slowRequestThresholdMs) {\n void logger.warn('slow request detected', {\n ...baseFields,\n statusCode: status,\n duration,\n threshold: slowRequestThresholdMs,\n });\n }\n };\n\n res.once?.('finish', onFinish);\n // Fallback: also listen to 'close' (client disconnected before response finished)\n res.once?.('close', () => {\n if ((res.statusCode ?? 0) === 0) onFinish();\n });\n\n next();\n };\n}\n\n// ── Fastify plugin ─────────────────────────────────────────────────────────────\n\nexport interface FastifyInstance {\n addHook: (name: string, fn: (req: unknown, reply: unknown, done: () => void) => void) => void;\n}\n\n/**\n * Create a Fastify plugin (a function you pass to `fastify.register()`).\n *\n * @example\n * ```ts\n * await fastify.register(createFastifyPlugin(logger, { slowRequestThresholdMs: 500 }));\n * ```\n */\nexport function createFastifyPlugin(logger: IBaseLogger, options: HttpLoggerOptions = {}) {\n const {\n skip,\n requestIdHeader = 'x-request-id',\n requestLevel = 'debug',\n responseLevel = 'info',\n errorLevel = 'error',\n slowRequestThresholdMs = 1000,\n } = options;\n\n return function logixiaFastifyPlugin(\n fastify: FastifyInstance,\n _opts: unknown,\n done: () => void\n ): void {\n fastify.addHook('onRequest', (request: unknown, _reply: unknown, hookDone: () => void) => {\n const req = request as IncomingRequest & { _logixiaStart?: number; _logixiaId?: string };\n if (skip?.(req)) {\n hookDone();\n return;\n }\n\n const requestId = (req.headers?.[requestIdHeader] as string | undefined) ?? shortId();\n req._logixiaStart = Date.now();\n req._logixiaId = requestId;\n\n if (requestLevel !== 'silent') {\n void logger.logLevel(\n requestLevel,\n 'request started',\n buildBaseFields(req, requestId, options)\n );\n }\n hookDone();\n });\n\n fastify.addHook('onResponse', (request: unknown, reply: unknown, hookDone: () => void) => {\n const req = request as IncomingRequest & { _logixiaStart?: number; _logixiaId?: string };\n const rep = reply as { statusCode?: number };\n const duration = Date.now() - (req._logixiaStart ?? Date.now());\n const status = rep.statusCode ?? 0;\n const requestId = req._logixiaId ?? shortId();\n const level = status >= 500 ? errorLevel : responseLevel;\n\n void logger.logLevel(level, 'request completed', {\n ...buildBaseFields(req, requestId, options),\n statusCode: status,\n duration,\n });\n\n if (duration > slowRequestThresholdMs) {\n void logger.warn('slow request detected', {\n requestId,\n url: req.url,\n method: req.method,\n duration,\n threshold: slowRequestThresholdMs,\n });\n }\n\n hookDone();\n });\n\n done();\n };\n}\n\n// ── Internal helpers ──────────────────────────────────────────────────────────\n\nfunction truncateBody(body: unknown, maxBytes = 4096): unknown {\n if (typeof body === 'string') {\n return body.length > maxBytes ? body.slice(0, maxBytes) + '…[truncated]' : body;\n }\n if (body && typeof body === 'object') {\n const str = JSON.stringify(body);\n if (str.length > maxBytes) {\n return str.slice(0, maxBytes) + '…[truncated]';\n }\n }\n return body;\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
//#region src/middleware/http-logger.ts
|
|
2
|
+
const DEFAULT_REDACT_HEADERS = new Set([
|
|
3
|
+
"authorization",
|
|
4
|
+
"cookie",
|
|
5
|
+
"set-cookie",
|
|
6
|
+
"x-api-key"
|
|
7
|
+
]);
|
|
8
|
+
function sanitizeHeaders(headers, redactSet) {
|
|
9
|
+
if (!headers) return {};
|
|
10
|
+
const out = {};
|
|
11
|
+
for (const [k, v] of Object.entries(headers)) out[k] = redactSet.has(k.toLowerCase()) ? "[REDACTED]" : v;
|
|
12
|
+
return out;
|
|
13
|
+
}
|
|
14
|
+
function shortId() {
|
|
15
|
+
return Math.random().toString(36).slice(2, 10);
|
|
16
|
+
}
|
|
17
|
+
function buildBaseFields(req, requestId, options) {
|
|
18
|
+
var _req$method, _req$socket;
|
|
19
|
+
const redactSet = options.redactHeaders ? new Set(options.redactHeaders.map((h) => h.toLowerCase())) : DEFAULT_REDACT_HEADERS;
|
|
20
|
+
const fields = {
|
|
21
|
+
requestId,
|
|
22
|
+
method: ((_req$method = req.method) === null || _req$method === void 0 ? void 0 : _req$method.toUpperCase()) ?? "UNKNOWN",
|
|
23
|
+
url: req.url ?? "/",
|
|
24
|
+
ip: req.ip ?? ((_req$socket = req.socket) === null || _req$socket === void 0 ? void 0 : _req$socket.remoteAddress) ?? "unknown",
|
|
25
|
+
headers: sanitizeHeaders(req.headers, redactSet)
|
|
26
|
+
};
|
|
27
|
+
if (options.extraFields) Object.assign(fields, options.extraFields(req));
|
|
28
|
+
return fields;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Create an Express / Connect compatible middleware that replaces Morgan.
|
|
32
|
+
*/
|
|
33
|
+
function createExpressMiddleware(logger, options = {}) {
|
|
34
|
+
const { skip, logBody, bodyMaxBytes, requestIdHeader = "x-request-id", requestLevel = "debug", responseLevel = "info", errorLevel = "error", slowRequestThresholdMs = 1e3 } = options;
|
|
35
|
+
return function logixiaHttpMiddleware(req, res, next) {
|
|
36
|
+
var _req$headers, _res$once, _res$once2;
|
|
37
|
+
if (skip === null || skip === void 0 ? void 0 : skip(req)) {
|
|
38
|
+
next();
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
const requestId = ((_req$headers = req.headers) === null || _req$headers === void 0 ? void 0 : _req$headers[requestIdHeader]) ?? shortId();
|
|
42
|
+
const startMs = Date.now();
|
|
43
|
+
const baseFields = buildBaseFields(req, requestId, options);
|
|
44
|
+
if (requestLevel !== "silent") logger.logLevel(requestLevel, "request started", {
|
|
45
|
+
...baseFields,
|
|
46
|
+
...logBody && req.body ? { body: truncateBody(req.body, bodyMaxBytes) } : {}
|
|
47
|
+
});
|
|
48
|
+
const onFinish = () => {
|
|
49
|
+
const duration = Date.now() - startMs;
|
|
50
|
+
const status = res.statusCode ?? 0;
|
|
51
|
+
const level = status >= 500 ? errorLevel : responseLevel;
|
|
52
|
+
logger.logLevel(level, "request completed", {
|
|
53
|
+
...baseFields,
|
|
54
|
+
statusCode: status,
|
|
55
|
+
duration
|
|
56
|
+
});
|
|
57
|
+
if (duration > slowRequestThresholdMs) logger.warn("slow request detected", {
|
|
58
|
+
...baseFields,
|
|
59
|
+
statusCode: status,
|
|
60
|
+
duration,
|
|
61
|
+
threshold: slowRequestThresholdMs
|
|
62
|
+
});
|
|
63
|
+
};
|
|
64
|
+
(_res$once = res.once) === null || _res$once === void 0 || _res$once.call(res, "finish", onFinish);
|
|
65
|
+
(_res$once2 = res.once) === null || _res$once2 === void 0 || _res$once2.call(res, "close", () => {
|
|
66
|
+
if ((res.statusCode ?? 0) === 0) onFinish();
|
|
67
|
+
});
|
|
68
|
+
next();
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Create a Fastify plugin (a function you pass to `fastify.register()`).
|
|
73
|
+
*
|
|
74
|
+
* @example
|
|
75
|
+
* ```ts
|
|
76
|
+
* await fastify.register(createFastifyPlugin(logger, { slowRequestThresholdMs: 500 }));
|
|
77
|
+
* ```
|
|
78
|
+
*/
|
|
79
|
+
function createFastifyPlugin(logger, options = {}) {
|
|
80
|
+
const { skip, requestIdHeader = "x-request-id", requestLevel = "debug", responseLevel = "info", errorLevel = "error", slowRequestThresholdMs = 1e3 } = options;
|
|
81
|
+
return function logixiaFastifyPlugin(fastify, _opts, done) {
|
|
82
|
+
fastify.addHook("onRequest", (request, _reply, hookDone) => {
|
|
83
|
+
var _req$headers2;
|
|
84
|
+
const req = request;
|
|
85
|
+
if (skip === null || skip === void 0 ? void 0 : skip(req)) {
|
|
86
|
+
hookDone();
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
const requestId = ((_req$headers2 = req.headers) === null || _req$headers2 === void 0 ? void 0 : _req$headers2[requestIdHeader]) ?? shortId();
|
|
90
|
+
req._logixiaStart = Date.now();
|
|
91
|
+
req._logixiaId = requestId;
|
|
92
|
+
if (requestLevel !== "silent") logger.logLevel(requestLevel, "request started", buildBaseFields(req, requestId, options));
|
|
93
|
+
hookDone();
|
|
94
|
+
});
|
|
95
|
+
fastify.addHook("onResponse", (request, reply, hookDone) => {
|
|
96
|
+
const req = request;
|
|
97
|
+
const rep = reply;
|
|
98
|
+
const duration = Date.now() - (req._logixiaStart ?? Date.now());
|
|
99
|
+
const status = rep.statusCode ?? 0;
|
|
100
|
+
const requestId = req._logixiaId ?? shortId();
|
|
101
|
+
const level = status >= 500 ? errorLevel : responseLevel;
|
|
102
|
+
logger.logLevel(level, "request completed", {
|
|
103
|
+
...buildBaseFields(req, requestId, options),
|
|
104
|
+
statusCode: status,
|
|
105
|
+
duration
|
|
106
|
+
});
|
|
107
|
+
if (duration > slowRequestThresholdMs) logger.warn("slow request detected", {
|
|
108
|
+
requestId,
|
|
109
|
+
url: req.url,
|
|
110
|
+
method: req.method,
|
|
111
|
+
duration,
|
|
112
|
+
threshold: slowRequestThresholdMs
|
|
113
|
+
});
|
|
114
|
+
hookDone();
|
|
115
|
+
});
|
|
116
|
+
done();
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
function truncateBody(body, maxBytes = 4096) {
|
|
120
|
+
if (typeof body === "string") return body.length > maxBytes ? body.slice(0, maxBytes) + "…[truncated]" : body;
|
|
121
|
+
if (body && typeof body === "object") {
|
|
122
|
+
const str = JSON.stringify(body);
|
|
123
|
+
if (str.length > maxBytes) return str.slice(0, maxBytes) + "…[truncated]";
|
|
124
|
+
}
|
|
125
|
+
return body;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
//#endregion
|
|
129
|
+
export { createExpressMiddleware, createFastifyPlugin };
|
|
130
|
+
//# sourceMappingURL=middleware.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"middleware.mjs","names":["out: Record<string, unknown>","fields: Record<string, unknown>"],"sources":["../src/middleware/http-logger.ts"],"sourcesContent":["/**\n * HTTP request/response logging middleware — Morgan replacement.\n *\n * Fixes every documented Morgan bug:\n * - statusCode always captured correctly, even for requests > 20 s\n * - Logs request START (with requestId) and response FINISH (with duration)\n * - Captures errors before and after response\n * - Auto-redacts Authorization / Cookie / Set-Cookie headers\n * - Slow-request warnings\n * - Skip predicates for health-check routes / static assets\n *\n * @example Express\n * ```ts\n * import { createExpressMiddleware } from 'logixia/middleware';\n * app.use(createExpressMiddleware(logger));\n * ```\n *\n * @example Fastify\n * ```ts\n * import { createFastifyPlugin } from 'logixia/middleware';\n * await fastify.register(createFastifyPlugin(logger));\n * ```\n */\n\n/* eslint-disable sonarjs/void-use -- intentional fire-and-forget in sync middleware callbacks */\nimport type { IBaseLogger } from '../types';\n\n// ── Shared types ─────────────────────────────────────────────────────────────\n\nexport interface HttpLoggerOptions {\n /**\n * Skip logging for a request. Called before any I/O.\n * @example `skip: (req) => req.url === '/health'`\n */\n skip?: (req: IncomingRequest) => boolean;\n /**\n * Log request body (POST/PUT/PATCH). Capped at `bodyMaxBytes` (default: 4096).\n * Redaction still applies to the captured body.\n * Default: false.\n */\n logBody?: boolean;\n /** Max bytes of body to capture. Default: 4096. */\n bodyMaxBytes?: number;\n /**\n * Emit a WARN log when a request duration exceeds this threshold (ms).\n * Default: 1000.\n */\n slowRequestThresholdMs?: number;\n /**\n * Additional fields to include in every log entry.\n * @example `extraFields: (req) => ({ tenantId: req.headers['x-tenant-id'] })`\n */\n extraFields?: (req: IncomingRequest) => Record<string, unknown>;\n /**\n * Request ID header. Default: 'x-request-id'.\n * If the header is absent, a short random ID is generated.\n */\n requestIdHeader?: string;\n /**\n * Headers to redact from logged output.\n * Default: ['authorization', 'cookie', 'set-cookie', 'x-api-key'].\n */\n redactHeaders?: string[];\n /**\n * Log level for request-start entries. Default: 'debug'.\n * Set to 'silent' to suppress request-start logs entirely.\n */\n requestLevel?: string;\n /** Log level for successful response entries. Default: 'info'. */\n responseLevel?: string;\n /** Log level for error responses (status ≥ 500). Default: 'error'. */\n errorLevel?: string;\n}\n\n// Minimal structural types so we don't need @types/express / fastify in core\nexport interface IncomingRequest {\n method?: string;\n url?: string;\n headers?: Record<string, string | string[] | undefined>;\n body?: unknown;\n socket?: { remoteAddress?: string };\n ip?: string;\n}\n\nexport interface OutgoingResponse {\n statusCode?: number;\n on?: (event: string, cb: () => void) => void;\n once?: (event: string, cb: () => void) => void;\n getHeader?: (name: string) => string | number | string[] | undefined;\n}\n\n// ── Helpers ───────────────────────────────────────────────────────────────────\n\nconst DEFAULT_REDACT_HEADERS = new Set(['authorization', 'cookie', 'set-cookie', 'x-api-key']);\n\nfunction sanitizeHeaders(\n headers: Record<string, string | string[] | undefined> | undefined,\n redactSet: Set<string>\n): Record<string, unknown> {\n if (!headers) return {};\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(headers)) {\n out[k] = redactSet.has(k.toLowerCase()) ? '[REDACTED]' : v;\n }\n return out;\n}\n\nfunction shortId(): string {\n // eslint-disable-next-line sonarjs/pseudo-random -- non-security request ID\n return Math.random().toString(36).slice(2, 10);\n}\n\nfunction buildBaseFields(\n req: IncomingRequest,\n requestId: string,\n options: HttpLoggerOptions\n): Record<string, unknown> {\n const redactSet = options.redactHeaders\n ? new Set(options.redactHeaders.map((h) => h.toLowerCase()))\n : DEFAULT_REDACT_HEADERS;\n\n const fields: Record<string, unknown> = {\n requestId,\n method: req.method?.toUpperCase() ?? 'UNKNOWN',\n url: req.url ?? '/',\n ip: req.ip ?? req.socket?.remoteAddress ?? 'unknown',\n headers: sanitizeHeaders(req.headers, redactSet),\n };\n\n if (options.extraFields) {\n Object.assign(fields, options.extraFields(req));\n }\n\n return fields;\n}\n\n// ── Express middleware ────────────────────────────────────────────────────────\n\n/**\n * Create an Express / Connect compatible middleware that replaces Morgan.\n */\nexport function createExpressMiddleware(\n logger: IBaseLogger,\n options: HttpLoggerOptions = {}\n): (req: IncomingRequest, res: OutgoingResponse, next: () => void) => void {\n const {\n skip,\n logBody,\n bodyMaxBytes,\n requestIdHeader = 'x-request-id',\n requestLevel = 'debug',\n responseLevel = 'info',\n errorLevel = 'error',\n slowRequestThresholdMs = 1000,\n } = options;\n\n return function logixiaHttpMiddleware(\n req: IncomingRequest,\n res: OutgoingResponse,\n next: () => void\n ): void {\n if (skip?.(req)) {\n next();\n return;\n }\n\n const requestId = (req.headers?.[requestIdHeader] as string | undefined) ?? shortId();\n const startMs = Date.now();\n const baseFields = buildBaseFields(req, requestId, options);\n\n // Log request start\n if (requestLevel !== 'silent') {\n void logger.logLevel(requestLevel, 'request started', {\n ...baseFields,\n ...(logBody && req.body ? { body: truncateBody(req.body, bodyMaxBytes) } : {}),\n });\n }\n\n // Hook into the response 'finish' event — fires after headers + body are sent.\n // This is what Morgan gets wrong for slow requests (it uses 'close' which may\n // fire before the status code is set on some Node versions).\n const onFinish = (): void => {\n const duration = Date.now() - startMs;\n const status = res.statusCode ?? 0;\n const level = status >= 500 ? errorLevel : responseLevel;\n\n void logger.logLevel(level, 'request completed', {\n ...baseFields,\n statusCode: status,\n duration,\n });\n\n if (duration > slowRequestThresholdMs) {\n void logger.warn('slow request detected', {\n ...baseFields,\n statusCode: status,\n duration,\n threshold: slowRequestThresholdMs,\n });\n }\n };\n\n res.once?.('finish', onFinish);\n // Fallback: also listen to 'close' (client disconnected before response finished)\n res.once?.('close', () => {\n if ((res.statusCode ?? 0) === 0) onFinish();\n });\n\n next();\n };\n}\n\n// ── Fastify plugin ─────────────────────────────────────────────────────────────\n\nexport interface FastifyInstance {\n addHook: (name: string, fn: (req: unknown, reply: unknown, done: () => void) => void) => void;\n}\n\n/**\n * Create a Fastify plugin (a function you pass to `fastify.register()`).\n *\n * @example\n * ```ts\n * await fastify.register(createFastifyPlugin(logger, { slowRequestThresholdMs: 500 }));\n * ```\n */\nexport function createFastifyPlugin(logger: IBaseLogger, options: HttpLoggerOptions = {}) {\n const {\n skip,\n requestIdHeader = 'x-request-id',\n requestLevel = 'debug',\n responseLevel = 'info',\n errorLevel = 'error',\n slowRequestThresholdMs = 1000,\n } = options;\n\n return function logixiaFastifyPlugin(\n fastify: FastifyInstance,\n _opts: unknown,\n done: () => void\n ): void {\n fastify.addHook('onRequest', (request: unknown, _reply: unknown, hookDone: () => void) => {\n const req = request as IncomingRequest & { _logixiaStart?: number; _logixiaId?: string };\n if (skip?.(req)) {\n hookDone();\n return;\n }\n\n const requestId = (req.headers?.[requestIdHeader] as string | undefined) ?? shortId();\n req._logixiaStart = Date.now();\n req._logixiaId = requestId;\n\n if (requestLevel !== 'silent') {\n void logger.logLevel(\n requestLevel,\n 'request started',\n buildBaseFields(req, requestId, options)\n );\n }\n hookDone();\n });\n\n fastify.addHook('onResponse', (request: unknown, reply: unknown, hookDone: () => void) => {\n const req = request as IncomingRequest & { _logixiaStart?: number; _logixiaId?: string };\n const rep = reply as { statusCode?: number };\n const duration = Date.now() - (req._logixiaStart ?? Date.now());\n const status = rep.statusCode ?? 0;\n const requestId = req._logixiaId ?? shortId();\n const level = status >= 500 ? errorLevel : responseLevel;\n\n void logger.logLevel(level, 'request completed', {\n ...buildBaseFields(req, requestId, options),\n statusCode: status,\n duration,\n });\n\n if (duration > slowRequestThresholdMs) {\n void logger.warn('slow request detected', {\n requestId,\n url: req.url,\n method: req.method,\n duration,\n threshold: slowRequestThresholdMs,\n });\n }\n\n hookDone();\n });\n\n done();\n };\n}\n\n// ── Internal helpers ──────────────────────────────────────────────────────────\n\nfunction truncateBody(body: unknown, maxBytes = 4096): unknown {\n if (typeof body === 'string') {\n return body.length > maxBytes ? body.slice(0, maxBytes) + '…[truncated]' : body;\n }\n if (body && typeof body === 'object') {\n const str = JSON.stringify(body);\n if (str.length > maxBytes) {\n return str.slice(0, maxBytes) + '…[truncated]';\n }\n }\n return body;\n}\n"],"mappings":"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"}
|
package/dist/nest.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { a as LogixiaOptionsFactory, c as LogixiaLoggerService, i as LogixiaLoggerModule, n as LOGIXIA_LOGGER_PREFIX, o as WebSocketTraceInterceptor, r as LogixiaAsyncOptions, s as KafkaTraceInterceptor, t as LOGIXIA_LOGGER_CONFIG } from "./logitron-logger.module-
|
|
1
|
+
import { O as HttpRequest, S as RequestContext, T as TraceIdConfig, k as HttpResponse } from "./index-iDTW2-eY.mjs";
|
|
2
|
+
import { a as LogixiaOptionsFactory, c as LogixiaLoggerService, i as LogixiaLoggerModule, n as LOGIXIA_LOGGER_PREFIX, o as WebSocketTraceInterceptor, r as LogixiaAsyncOptions, s as KafkaTraceInterceptor, t as LOGIXIA_LOGGER_CONFIG } from "./logitron-logger.module-DQKaZTJL.mjs";
|
|
3
3
|
import { NestMiddleware } from "@nestjs/common";
|
|
4
4
|
import { NextFunction, Request, Response } from "express";
|
|
5
5
|
|
package/dist/nest.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { a as LogixiaOptionsFactory, c as LogixiaLoggerService, i as LogixiaLoggerModule, n as LOGIXIA_LOGGER_PREFIX, o as WebSocketTraceInterceptor, r as LogixiaAsyncOptions, s as KafkaTraceInterceptor, t as LOGIXIA_LOGGER_CONFIG } from "./logitron-logger.module-
|
|
1
|
+
import { O as HttpRequest, S as RequestContext, T as TraceIdConfig, k as HttpResponse } from "./index-CHIsdA9n.js";
|
|
2
|
+
import { a as LogixiaOptionsFactory, c as LogixiaLoggerService, i as LogixiaLoggerModule, n as LOGIXIA_LOGGER_PREFIX, o as WebSocketTraceInterceptor, r as LogixiaAsyncOptions, s as KafkaTraceInterceptor, t as LOGIXIA_LOGGER_CONFIG } from "./logitron-logger.module-C0G8JGVf.js";
|
|
3
3
|
import { NestMiddleware } from "@nestjs/common";
|
|
4
4
|
import { NextFunction, Request, Response } from "express";
|
|
5
5
|
|
package/dist/nest.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
require('./
|
|
2
|
-
|
|
1
|
+
const require_logitron_logger_module = require('./logitron-logger.module-BqNKp0Fs.js');
|
|
2
|
+
require('./transport.manager-DCOm4uIQ.js');
|
|
3
3
|
|
|
4
4
|
//#region src/core/request-context.ts
|
|
5
5
|
var RequestContextManager = class {
|