@nestjs-labs/pino-http-extra 0.0.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/README.md ADDED
@@ -0,0 +1,148 @@
1
+ # @nestjs-labs/pino-http-extra
2
+
3
+ Enhanced pino-http with OpenTelemetry, Loki, file rotation and enterprise features.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @nestjs-labs/pino-http-extra
9
+ ```
10
+
11
+ ## Features
12
+
13
+ - 🔍 **OpenTelemetry Integration**: Automatic span and trace ID injection
14
+ - 📊 **Loki Transport**: Send logs to Grafana Loki
15
+ - 📁 **File Rotation**: Automatic log file rotation with compression
16
+ - 🎨 **Pretty Logging**: Colored and formatted console output
17
+ - 🔒 **Security**: Automatic redaction of sensitive fields
18
+ - ⚡ **Performance**: High-performance logging with Pino
19
+
20
+ ## Quick Start
21
+
22
+ ### Basic Usage
23
+
24
+ ```typescript
25
+ import { Module } from '@nestjs/common';
26
+ import { ConfigModule, ConfigService } from '@nestjs/config';
27
+ import { LoggerModule } from '@nestjs-labs/nest-pino-extra';
28
+
29
+ @Module({
30
+ imports: [
31
+ ConfigModule.forRoot(),
32
+ LoggerModule.forRootAsync({
33
+ imports: [ConfigModule],
34
+ useFactory: (configService: ConfigService) =>
35
+ getNestjsPinoModuleOptions(configService),
36
+ inject: [ConfigService],
37
+ }),
38
+ ],
39
+ })
40
+ export class AppModule {}
41
+ ```
42
+
43
+ ### Environment Variables
44
+
45
+ ```bash
46
+ # Required
47
+ OTLP_SERVICE_NAME=my-app
48
+
49
+ # Optional
50
+ LOG_LEVEL=info
51
+ LOG_FILE=/var/log/app.log
52
+ LOG_LOKI=http://loki:3100
53
+ OTEL_SPAN_ID_KEY=spanId
54
+ OTEL_TRACE_ID_KEY=traceId
55
+ ```
56
+
57
+ ### Advanced Configuration
58
+
59
+ ```typescript
60
+ import { Module } from '@nestjs/common';
61
+ import { ConfigModule, ConfigService } from '@nestjs/config';
62
+ import { LoggerModule } from '@nestjs-labs/nest-pino-extra';
63
+
64
+ @Module({
65
+ imports: [
66
+ ConfigModule.forRoot(),
67
+ LoggerModule.forRootAsync({
68
+ imports: [ConfigModule],
69
+ useFactory: (configService: ConfigService) =>
70
+ getNestjsPinoModuleOptions(configService, {
71
+ exclude: [
72
+ { method: 0, path: '/health' },
73
+ { method: 0, path: '/metrics' },
74
+ ],
75
+ }),
76
+ inject: [ConfigService],
77
+ }),
78
+ ],
79
+ })
80
+ export class AppModule {}
81
+ ```
82
+
83
+ ## API Reference
84
+
85
+ ### Functions
86
+
87
+ #### `getNestjsPinoModuleOptions(configService, overrides?)`
88
+
89
+ Get nestjs-pino module options with improved type safety and validation.
90
+
91
+ **Parameters:**
92
+ - `configService`: ConfigService - NestJS configuration service
93
+ - `overrides`: Params (optional) - Overrides for the module options
94
+
95
+ **Returns:** Params - Configured nestjs-pino module options
96
+
97
+ #### `getPinoHttpOption(level?, spanIdKey?, traceIdKey?)`
98
+
99
+ Get pino-http options with OpenTelemetry integration.
100
+
101
+ **Parameters:**
102
+ - `level`: string (default: 'info') - Log level
103
+ - `spanIdKey`: string (default: 'spanId') - OpenTelemetry span ID key
104
+ - `traceIdKey`: string (default: 'traceId') - OpenTelemetry trace ID key
105
+
106
+ **Returns:** Options - Configured pino-http options
107
+
108
+ #### `getMultiDestinationStream(app, level?, filepath?, loki?)`
109
+
110
+ Create multi-destination stream supporting pretty, file, and Loki outputs.
111
+
112
+ **Parameters:**
113
+ - `app`: string - Application name
114
+ - `level`: pino.Level (default: 'info') - Log level
115
+ - `filepath`: string (optional) - Log file path for rotation
116
+ - `loki`: string (optional) - Loki host URL
117
+
118
+ **Returns:** MultiStreamRes - Configured multi-stream
119
+
120
+ ## Examples
121
+
122
+ ### Custom Logging
123
+
124
+ ```typescript
125
+ import { Injectable, Logger } from '@nestjs/common';
126
+
127
+ @Injectable()
128
+ export class AppService {
129
+ private readonly logger = new Logger(AppService.name);
130
+
131
+ getHello(): string {
132
+ this.logger.log('Hello World!');
133
+ return 'Hello World!';
134
+ }
135
+ }
136
+ ```
137
+
138
+ ### HTTP Request Logging
139
+
140
+ The middleware automatically logs HTTP requests with:
141
+ - Request ID generation
142
+ - Response time tracking
143
+ - Status code-based log levels
144
+ - Sensitive data redaction
145
+
146
+ ## License
147
+
148
+ MIT
@@ -0,0 +1,7 @@
1
+ export declare function getOtelFormatters(spanIdKey?: string, traceIdKey?: string): {
2
+ level: (label: string) => {
3
+ level: string;
4
+ };
5
+ log(object: Record<string, unknown>): Record<string, unknown>;
6
+ };
7
+ //# sourceMappingURL=formatters.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formatters.d.ts","sourceRoot":"","sources":["../src/formatters.ts"],"names":[],"mappings":"AAMA,wBAAgB,iBAAiB,CAChC,SAAS,SAAW,EACpB,UAAU,SAAY;mBAGN,MAAM;;;gBAIT,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;EAapC"}
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getOtelFormatters = getOtelFormatters;
4
+ const api_1 = require("@opentelemetry/api");
5
+ function getOtelFormatters(spanIdKey = 'spanId', traceIdKey = 'traceId') {
6
+ return {
7
+ level: (label) => {
8
+ return { level: label };
9
+ },
10
+ log(object) {
11
+ const span = api_1.trace.getSpan(api_1.context.active());
12
+ if (!span)
13
+ return object;
14
+ const spanContext = api_1.trace.getSpan(api_1.context.active())?.spanContext();
15
+ if (!spanContext)
16
+ return object;
17
+ const { spanId, traceId } = spanContext;
18
+ return { ...object, [spanIdKey]: spanId, [traceIdKey]: traceId };
19
+ },
20
+ };
21
+ }
22
+ //# sourceMappingURL=formatters.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formatters.js","sourceRoot":"","sources":["../src/formatters.ts"],"names":[],"mappings":";;AAMA,8CAsBC;AA5BD,4CAAoD;AAMpD,SAAgB,iBAAiB,CAChC,SAAS,GAAG,QAAQ,EACpB,UAAU,GAAG,SAAS;IAEtB,OAAO;QACN,KAAK,EAAE,CAAC,KAAa,EAAE,EAAE;YACxB,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;QACzB,CAAC;QAED,GAAG,CAAC,MAA+B;YAClC,MAAM,IAAI,GAAG,WAAK,CAAC,OAAO,CAAC,aAAO,CAAC,MAAM,EAAE,CAAC,CAAC;YAE7C,IAAI,CAAC,IAAI;gBAAE,OAAO,MAAM,CAAC;YACzB,MAAM,WAAW,GAAG,WAAK,CAAC,OAAO,CAAC,aAAO,CAAC,MAAM,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC;YAEnE,IAAI,CAAC,WAAW;gBAAE,OAAO,MAAM,CAAC;YAEhC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,WAAW,CAAC;YAExC,OAAO,EAAE,GAAG,MAAM,EAAE,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC,UAAU,CAAC,EAAE,OAAO,EAAE,CAAC;QAClE,CAAC;KACD,CAAC;AACH,CAAC"}
@@ -0,0 +1,5 @@
1
+ export { getOtelFormatters } from './formatters.js';
2
+ export { getPinoHttpOption } from './options.js';
3
+ export { getSerializers } from './serializers.js';
4
+ export { createFileStreamEntry, createLokiStreamEntry, createPrettyStreamEntry, getMultiDestinationStream, } from './streams.js';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EACL,qBAAqB,EACrB,qBAAqB,EACrB,uBAAuB,EACvB,yBAAyB,GAC1B,MAAM,cAAc,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getMultiDestinationStream = exports.createPrettyStreamEntry = exports.createLokiStreamEntry = exports.createFileStreamEntry = exports.getSerializers = exports.getPinoHttpOption = exports.getOtelFormatters = void 0;
4
+ var formatters_js_1 = require("./formatters.js");
5
+ Object.defineProperty(exports, "getOtelFormatters", { enumerable: true, get: function () { return formatters_js_1.getOtelFormatters; } });
6
+ var options_js_1 = require("./options.js");
7
+ Object.defineProperty(exports, "getPinoHttpOption", { enumerable: true, get: function () { return options_js_1.getPinoHttpOption; } });
8
+ var serializers_js_1 = require("./serializers.js");
9
+ Object.defineProperty(exports, "getSerializers", { enumerable: true, get: function () { return serializers_js_1.getSerializers; } });
10
+ var streams_js_1 = require("./streams.js");
11
+ Object.defineProperty(exports, "createFileStreamEntry", { enumerable: true, get: function () { return streams_js_1.createFileStreamEntry; } });
12
+ Object.defineProperty(exports, "createLokiStreamEntry", { enumerable: true, get: function () { return streams_js_1.createLokiStreamEntry; } });
13
+ Object.defineProperty(exports, "createPrettyStreamEntry", { enumerable: true, get: function () { return streams_js_1.createPrettyStreamEntry; } });
14
+ Object.defineProperty(exports, "getMultiDestinationStream", { enumerable: true, get: function () { return streams_js_1.getMultiDestinationStream; } });
15
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAOA,iDAAoD;AAA3C,kHAAA,iBAAiB,OAAA;AAC1B,2CAAiD;AAAxC,+GAAA,iBAAiB,OAAA;AAC1B,mDAAkD;AAAzC,gHAAA,cAAc,OAAA;AACvB,2CAKsB;AAJpB,mHAAA,qBAAqB,OAAA;AACrB,mHAAA,qBAAqB,OAAA;AACrB,qHAAA,uBAAuB,OAAA;AACvB,uHAAA,yBAAyB,OAAA"}
@@ -0,0 +1,3 @@
1
+ import type { Options } from 'pino-http';
2
+ export declare function getPinoHttpOption(level?: string, spanIdKey?: string, traceIdKey?: string): Options;
3
+ //# sourceMappingURL=options.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"options.d.ts","sourceRoot":"","sources":["../src/options.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAUzC,wBAAgB,iBAAiB,CAChC,KAAK,SAAS,EACd,SAAS,SAAW,EACpB,UAAU,SAAY,GACpB,OAAO,CAmDT"}
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.getPinoHttpOption = getPinoHttpOption;
7
+ const node_crypto_1 = require("node:crypto");
8
+ const pino_1 = __importDefault(require("pino"));
9
+ const formatters_js_1 = require("./formatters.js");
10
+ const serializers_js_1 = require("./serializers.js");
11
+ function getPinoHttpOption(level = 'info', spanIdKey = 'spanId', traceIdKey = 'traceId') {
12
+ return {
13
+ level,
14
+ quietReqLogger: false,
15
+ timestamp: pino_1.default.stdTimeFunctions.isoTime,
16
+ customAttributeKeys: {
17
+ req: 'req',
18
+ res: 'res',
19
+ err: 'err',
20
+ responseTime: 'taken(ms)',
21
+ },
22
+ formatters: (0, formatters_js_1.getOtelFormatters)(spanIdKey, traceIdKey),
23
+ serializers: (0, serializers_js_1.getSerializers)(),
24
+ redact: {
25
+ paths: [
26
+ 'password',
27
+ 'reqBody.password',
28
+ 'user.password',
29
+ 'reqBody.user.password',
30
+ ],
31
+ },
32
+ genReqId: function (req, res) {
33
+ const reqId = req.id ?? req.headers['x-request-id'];
34
+ if (reqId)
35
+ return reqId;
36
+ const id = (0, node_crypto_1.randomUUID)();
37
+ res.setHeader('X-Request-Id', id);
38
+ return id;
39
+ },
40
+ customLogLevel(_, res, err) {
41
+ if (res.statusCode >= 400 && res.statusCode < 500) {
42
+ return 'warn';
43
+ }
44
+ else if (res.statusCode >= 500 || err) {
45
+ return 'error';
46
+ }
47
+ else if (res.statusCode >= 300 && res.statusCode < 400) {
48
+ return 'silent';
49
+ }
50
+ return 'info';
51
+ },
52
+ };
53
+ }
54
+ //# sourceMappingURL=options.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"options.js","sourceRoot":"","sources":["../src/options.ts"],"names":[],"mappings":";;;;;AAcA,8CAuDC;AApED,6CAAyC;AAKzC,gDAAwB;AAExB,mDAAoD;AACpD,qDAAkD;AAKlD,SAAgB,iBAAiB,CAChC,KAAK,GAAG,MAAM,EACd,SAAS,GAAG,QAAQ,EACpB,UAAU,GAAG,SAAS;IAEtB,OAAO;QAIN,KAAK;QACL,cAAc,EAAE,KAAK;QACrB,SAAS,EAAE,cAAI,CAAC,gBAAgB,CAAC,OAAO;QACxC,mBAAmB,EAAE;YACpB,GAAG,EAAE,KAAK;YACV,GAAG,EAAE,KAAK;YACV,GAAG,EAAE,KAAK;YACV,YAAY,EAAE,WAAW;SACzB;QACD,UAAU,EAAE,IAAA,iCAAiB,EAAC,SAAS,EAAE,UAAU,CAAC;QACpD,WAAW,EAAE,IAAA,+BAAc,GAAE;QAC7B,MAAM,EAAE;YACP,KAAK,EAAE;gBACN,UAAU;gBACV,kBAAkB;gBAClB,eAAe;gBACf,uBAAuB;aACvB;SACD;QACD,QAAQ,EAAE,UAAU,GAAG,EAAE,GAAG;YAC3B,MAAM,KAAK,GAAG,GAAG,CAAC,EAAE,IAAI,GAAG,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;YAEpD,IAAI,KAAK;gBAAE,OAAO,KAAK,CAAC;YACxB,MAAM,EAAE,GAAG,IAAA,wBAAU,GAAE,CAAC;YAExB,GAAG,CAAC,SAAS,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC;YAElC,OAAO,EAAE,CAAC;QACX,CAAC;QAED,cAAc,CACb,CAAkB,EAClB,GAAoC,EACpC,GAAW;YAEX,IAAI,GAAG,CAAC,UAAU,IAAI,GAAG,IAAI,GAAG,CAAC,UAAU,GAAG,GAAG,EAAE,CAAC;gBACnD,OAAO,MAAM,CAAC;YACf,CAAC;iBAAM,IAAI,GAAG,CAAC,UAAU,IAAI,GAAG,IAAI,GAAG,EAAE,CAAC;gBACzC,OAAO,OAAO,CAAC;YAChB,CAAC;iBAAM,IAAI,GAAG,CAAC,UAAU,IAAI,GAAG,IAAI,GAAG,CAAC,UAAU,GAAG,GAAG,EAAE,CAAC;gBAC1D,OAAO,QAAQ,CAAC;YACjB,CAAC;YAED,OAAO,MAAM,CAAC;QACf,CAAC;KACD,CAAC;AACH,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { SerializerFn } from 'pino';
2
+ export declare function getSerializers(): Record<string, SerializerFn>;
3
+ //# sourceMappingURL=serializers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"serializers.d.ts","sourceRoot":"","sources":["../src/serializers.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,MAAM,CAAC;AAWzC,wBAAgB,cAAc,IAAI,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAyB7D"}
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getSerializers = getSerializers;
4
+ function getSerializers() {
5
+ return {
6
+ req(req) {
7
+ const request = req.raw;
8
+ return {
9
+ id: req.id,
10
+ method: req.method,
11
+ url: req.url,
12
+ headers: request.headers,
13
+ query: request.query,
14
+ body: request.body,
15
+ };
16
+ },
17
+ res(response) {
18
+ const { statusCode: status, ...serialized } = response;
19
+ return Object.assign({ status }, serialized);
20
+ },
21
+ err(err) {
22
+ return err;
23
+ },
24
+ };
25
+ }
26
+ //# sourceMappingURL=serializers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"serializers.js","sourceRoot":"","sources":["../src/serializers.ts"],"names":[],"mappings":";;AAYA,wCAyBC;AAzBD,SAAgB,cAAc;IAC7B,OAAO;QACN,GAAG,CAAC,GAAsB;YACzB,MAAM,OAAO,GAAG,GAAG,CAAC,GAEnB,CAAC;YAEF,OAAO;gBACN,EAAE,EAAE,GAAG,CAAC,EAAE;gBACV,MAAM,EAAE,GAAG,CAAC,MAAM;gBAClB,GAAG,EAAE,GAAG,CAAC,GAAG;gBACZ,OAAO,EAAE,OAAO,CAAC,OAAO;gBACxB,KAAK,EAAE,OAAO,CAAC,KAAK;gBACpB,IAAI,EAAE,OAAO,CAAC,IAAI;aAClB,CAAC;QACH,CAAC;QACD,GAAG,CAAC,QAA4B;YAC/B,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,UAAU,EAAE,GAAG,QAAQ,CAAC;YAEvD,OAAO,MAAM,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,EAAE,UAAU,CAAC,CAAC;QAC9C,CAAC;QACD,GAAG,CAAC,GAAoB;YACvB,OAAO,GAAG,CAAC;QACZ,CAAC;KACD,CAAC;AACH,CAAC"}
@@ -0,0 +1,6 @@
1
+ import pino from 'pino';
2
+ export declare function createPrettyStreamEntry(_app: string, level: pino.Level): pino.StreamEntry;
3
+ export declare function createLokiStreamEntry(app: string, level: pino.Level, host: string): pino.StreamEntry;
4
+ export declare function createFileStreamEntry(_app: string, level: pino.Level, filepath: string): pino.StreamEntry;
5
+ export declare function getMultiDestinationStream(app: string, level?: pino.Level, filepath?: string, loki?: string): pino.MultiStreamRes;
6
+ //# sourceMappingURL=streams.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"streams.d.ts","sourceRoot":"","sources":["../src/streams.ts"],"names":[],"mappings":"AAGA,OAAO,IAAI,MAAM,MAAM,CAAC;AAQxB,wBAAgB,uBAAuB,CACtC,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,IAAI,CAAC,KAAK,GACf,IAAI,CAAC,WAAW,CAQlB;AAMD,wBAAgB,qBAAqB,CACpC,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,IAAI,CAAC,KAAK,EACjB,IAAI,EAAE,MAAM,GACV,IAAI,CAAC,WAAW,CAWlB;AAMD,wBAAgB,qBAAqB,CACpC,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,IAAI,CAAC,KAAK,EACjB,QAAQ,EAAE,MAAM,GACd,IAAI,CAAC,WAAW,CAWlB;AAMD,wBAAgB,yBAAyB,CACxC,GAAG,EAAE,MAAM,EACX,KAAK,GAAE,IAAI,CAAC,KAAc,EAC1B,QAAQ,CAAC,EAAE,MAAM,EACjB,IAAI,CAAC,EAAE,MAAM,GACX,IAAI,CAAC,cAAc,CAOrB"}
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.createPrettyStreamEntry = createPrettyStreamEntry;
7
+ exports.createLokiStreamEntry = createLokiStreamEntry;
8
+ exports.createFileStreamEntry = createFileStreamEntry;
9
+ exports.getMultiDestinationStream = getMultiDestinationStream;
10
+ const node_path_1 = __importDefault(require("node:path"));
11
+ const pino_1 = __importDefault(require("pino"));
12
+ const pino_loki_1 = require("pino-loki");
13
+ const pino_pretty_1 = __importDefault(require("pino-pretty"));
14
+ const rotating_file_stream_1 = require("rotating-file-stream");
15
+ function createPrettyStreamEntry(_app, level) {
16
+ const stream = (0, pino_pretty_1.default)({
17
+ translateTime: false,
18
+ hideObject: false,
19
+ colorize: true,
20
+ });
21
+ return { level, stream };
22
+ }
23
+ function createLokiStreamEntry(app, level, host) {
24
+ console.log('createLokiStreamEntry', app, level, host);
25
+ const stream = (0, pino_loki_1.pinoLoki)({
26
+ replaceTimestamp: true,
27
+ batching: true,
28
+ interval: 5,
29
+ host,
30
+ labels: { app, service: app },
31
+ });
32
+ return { level, stream };
33
+ }
34
+ function createFileStreamEntry(_app, level, filepath) {
35
+ const { base, dir } = node_path_1.default.parse(filepath);
36
+ const stream = (0, rotating_file_stream_1.createStream)(base, {
37
+ size: '1G',
38
+ interval: '1d',
39
+ compress: 'gzip',
40
+ path: dir,
41
+ });
42
+ return { level, stream };
43
+ }
44
+ function getMultiDestinationStream(app, level = 'info', filepath, loki) {
45
+ const entries = [createPrettyStreamEntry(app, level)];
46
+ if (filepath)
47
+ entries.push(createFileStreamEntry(app, level, filepath));
48
+ if (loki)
49
+ entries.push(createLokiStreamEntry(app, level, loki));
50
+ return pino_1.default.multistream(entries);
51
+ }
52
+ //# sourceMappingURL=streams.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"streams.js","sourceRoot":"","sources":["../src/streams.ts"],"names":[],"mappings":";;;;;AAWA,0DAWC;AAMD,sDAeC;AAMD,sDAeC;AAMD,8DAYC;AAjFD,0DAA6B;AAE7B,gDAAwB;AACxB,yCAAqC;AACrC,8DAAqC;AACrC,+DAAoD;AAKpD,SAAgB,uBAAuB,CACtC,IAAY,EACZ,KAAiB;IAEjB,MAAM,MAAM,GAAG,IAAA,qBAAU,EAAC;QACzB,aAAa,EAAE,KAAK;QACpB,UAAU,EAAE,KAAK;QACjB,QAAQ,EAAE,IAAI;KACd,CAAC,CAAC;IAEH,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;AAC1B,CAAC;AAMD,SAAgB,qBAAqB,CACpC,GAAW,EACX,KAAiB,EACjB,IAAY;IAEZ,OAAO,CAAC,GAAG,CAAC,uBAAuB,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;IACvD,MAAM,MAAM,GAAG,IAAA,oBAAQ,EAAC;QACvB,gBAAgB,EAAE,IAAI;QACtB,QAAQ,EAAE,IAAI;QACd,QAAQ,EAAE,CAAC;QACX,IAAI;QACJ,MAAM,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE;KAC7B,CAAC,CAAC;IAEH,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;AAC1B,CAAC;AAMD,SAAgB,qBAAqB,CACpC,IAAY,EACZ,KAAiB,EACjB,QAAgB;IAEhB,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,mBAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IAE3C,MAAM,MAAM,GAAG,IAAA,mCAAY,EAAC,IAAI,EAAE;QACjC,IAAI,EAAE,IAAI;QACV,QAAQ,EAAE,IAAI;QACd,QAAQ,EAAE,MAAM;QAChB,IAAI,EAAE,GAAG;KACT,CAAC,CAAC;IAEH,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;AAC1B,CAAC;AAMD,SAAgB,yBAAyB,CACxC,GAAW,EACX,QAAoB,MAAM,EAC1B,QAAiB,EACjB,IAAa;IAEb,MAAM,OAAO,GAAuB,CAAC,uBAAuB,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC;IAE1E,IAAI,QAAQ;QAAE,OAAO,CAAC,IAAI,CAAC,qBAAqB,CAAC,GAAG,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC;IACxE,IAAI,IAAI;QAAE,OAAO,CAAC,IAAI,CAAC,qBAAqB,CAAC,GAAG,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC;IAEhE,OAAO,cAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;AAClC,CAAC"}
package/package.json ADDED
@@ -0,0 +1,95 @@
1
+ {
2
+ "name": "@nestjs-labs/pino-http-extra",
3
+ "version": "0.0.1",
4
+ "description": "Enhanced pino-http with OpenTelemetry, Loki, file rotation and enterprise features",
5
+ "main": "./dist/index.js",
6
+ "module": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "import": "./dist/index.js",
11
+ "require": "./dist/index.js"
12
+ },
13
+ "./options": {
14
+ "import": "./dist/options.js",
15
+ "require": "./dist/options.js"
16
+ },
17
+ "./streams": {
18
+ "import": "./dist/streams.js",
19
+ "require": "./dist/streams.js"
20
+ },
21
+ "./serializers": {
22
+ "import": "./dist/serializers.js",
23
+ "require": "./dist/serializers.js"
24
+ }
25
+ },
26
+ "scripts": {
27
+ "build": "tsc",
28
+ "lint": "eslint .",
29
+ "lint:fix": "eslint . --fix && prettier --write .",
30
+ "format": "prettier --write .",
31
+ "dry-run": "npm publish --dry-run",
32
+ "prepublishOnly": "npm run build",
33
+ "semantic-release": "semantic-release"
34
+ },
35
+ "repository": {
36
+ "type": "git",
37
+ "url": "git+https://github.com/nestjs-labs/nestjs-pino-extra.git",
38
+ "directory": "packages/pino-http-extra"
39
+ },
40
+ "keywords": [
41
+ "pino",
42
+ "http",
43
+ "logging",
44
+ "opentelemetry",
45
+ "loki",
46
+ "file-rotation",
47
+ "middleware"
48
+ ],
49
+ "author": "NestJS Labs AB",
50
+ "license": "MIT",
51
+ "bugs": {
52
+ "url": "https://github.com/nestjs-labs/nestjs-pino-extra/issues"
53
+ },
54
+ "homepage": "https://nestjs-labs.github.io/nestjs-pino-extra",
55
+ "docs": "https://nestjs-labs.github.io/nestjs-pino-extra",
56
+ "files": [
57
+ "dist"
58
+ ],
59
+ "dependencies": {
60
+ "@opentelemetry/api": "^1.9.0",
61
+ "pino": "^9.7.0",
62
+ "pino-http": "^10.5.0",
63
+ "pino-loki": "^2.6.0",
64
+ "pino-pretty": "^13.0.0",
65
+ "pino-std-serializers": "^7.0.0",
66
+ "rotating-file-stream": "^3.2.6"
67
+ },
68
+ "devDependencies": {
69
+ "@commitlint/cli": "^19.4.1",
70
+ "@commitlint/config-conventional": "^19.4.1",
71
+ "@nestjs-labs/eslint-config": "^1.0.1",
72
+ "@semantic-release/changelog": "^6.0.3",
73
+ "@semantic-release/commit-analyzer": "^13.0.1",
74
+ "@semantic-release/git": "^10.0.1",
75
+ "@semantic-release/github": "^11.0.3",
76
+ "@semantic-release/npm": "^12.0.2",
77
+ "@semantic-release/release-notes-generator": "^14.0.3",
78
+ "eslint": "^9.31.0",
79
+ "prettier": "^3.6.2",
80
+ "semantic-release": "^24.2.7",
81
+ "tslib": "^2.8.0",
82
+ "typedoc": "^0.28.7",
83
+ "typescript": "^5.5.4"
84
+ },
85
+ "config": {
86
+ "commitizen": {
87
+ "path": "node_modules/cz-conventional-changelog"
88
+ }
89
+ },
90
+ "commitlint": {
91
+ "extends": [
92
+ "@commitlint/config-conventional"
93
+ ]
94
+ }
95
+ }