@onivoro/server-pino 22.0.12 → 24.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,518 @@
1
+ # @onivoro/server-pino
2
+
3
+ A comprehensive Pino logging integration library for NestJS applications, providing structured logging, console patching, and enterprise-grade logging configuration with built-in performance optimizations.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @onivoro/server-pino
9
+ ```
10
+
11
+ ## Features
12
+
13
+ - **Pino Integration**: High-performance structured logging with Pino
14
+ - **NestJS Module**: Ready-to-use module with dependency injection
15
+ - **Console Patching**: Automatic console method replacement with structured logging
16
+ - **Configuration Management**: Strongly-typed configuration with environment variables
17
+ - **Performance Optimized**: Asynchronous logging for minimal performance impact
18
+ - **Structured Logging**: JSON-formatted logs with consistent structure
19
+ - **Log Levels**: Configurable log levels (trace, debug, info, warn, error, fatal)
20
+ - **Request Correlation**: Built-in request ID tracking for distributed systems
21
+
22
+ ## Quick Start
23
+
24
+ ### Import the Module
25
+
26
+ ```typescript
27
+ import { ServerPinoModule } from '@onivoro/server-pino';
28
+
29
+ @Module({
30
+ imports: [ServerPinoModule],
31
+ })
32
+ export class AppModule {}
33
+ ```
34
+
35
+ ### Basic Configuration
36
+
37
+ ```typescript
38
+ import { ServerPinoConfig } from '@onivoro/server-pino';
39
+
40
+ // Environment variables
41
+ // LOG_LEVEL=info
42
+ // LOG_PRETTY=false
43
+ // LOG_DESTINATION=stdout
44
+ ```
45
+
46
+ ### Enable Console Patching
47
+
48
+ ```typescript
49
+ import { patchConsole } from '@onivoro/server-pino';
50
+
51
+ // Patch console methods to use Pino
52
+ patchConsole();
53
+
54
+ // Now console.log, console.error, etc. will use structured logging
55
+ console.log('Hello world'); // Outputs structured JSON log
56
+ console.error('Error occurred', { error: 'details' });
57
+ ```
58
+
59
+ ## Configuration
60
+
61
+ ### Environment Variables
62
+
63
+ ```bash
64
+ # Log level (trace, debug, info, warn, error, fatal)
65
+ LOG_LEVEL=info
66
+
67
+ # Pretty print logs (useful for development)
68
+ LOG_PRETTY=true
69
+
70
+ # Log destination (stdout, stderr, or file path)
71
+ LOG_DESTINATION=stdout
72
+
73
+ # Enable/disable request logging
74
+ LOG_REQUESTS=true
75
+
76
+ # Log file rotation (if using file destination)
77
+ LOG_MAX_FILES=10
78
+ LOG_MAX_SIZE=10m
79
+ ```
80
+
81
+ ### Configuration Class
82
+
83
+ ```typescript
84
+ import { ServerPinoConfig, EnvironmentClass } from '@onivoro/server-pino';
85
+
86
+ @EnvironmentClass()
87
+ export class CustomPinoConfig extends ServerPinoConfig {
88
+ @EnvironmentVariable('LOG_LEVEL', 'info')
89
+ logLevel: string;
90
+
91
+ @EnvironmentVariable('LOG_PRETTY', 'false')
92
+ prettyPrint: boolean;
93
+
94
+ @EnvironmentVariable('LOG_DESTINATION', 'stdout')
95
+ destination: string;
96
+ }
97
+ ```
98
+
99
+ ## Usage Examples
100
+
101
+ ### Basic Logging
102
+
103
+ ```typescript
104
+ import { Injectable, Logger } from '@nestjs/common';
105
+
106
+ @Injectable()
107
+ export class MyService {
108
+ private readonly logger = new Logger(MyService.name);
109
+
110
+ async performOperation(data: any): Promise<void> {
111
+ this.logger.log('Starting operation', { data });
112
+
113
+ try {
114
+ // Perform operation
115
+ this.logger.debug('Operation step completed', { step: 1 });
116
+
117
+ this.logger.log('Operation completed successfully');
118
+ } catch (error) {
119
+ this.logger.error('Operation failed', error.stack, {
120
+ error: error.message,
121
+ data
122
+ });
123
+ throw error;
124
+ }
125
+ }
126
+ }
127
+ ```
128
+
129
+ ### Console Patching
130
+
131
+ ```typescript
132
+ import { patchConsole } from '@onivoro/server-pino';
133
+
134
+ // Apply console patching early in your application
135
+ patchConsole();
136
+
137
+ // Now all console methods produce structured logs
138
+ console.log('User logged in', { userId: '123', timestamp: new Date() });
139
+ console.error('Database connection failed', {
140
+ host: 'localhost',
141
+ port: 5432,
142
+ error: 'Connection timeout'
143
+ });
144
+ console.warn('Deprecated API usage', {
145
+ endpoint: '/api/v1/users',
146
+ suggestion: 'Use /api/v2/users instead'
147
+ });
148
+ ```
149
+
150
+ ### Advanced Configuration
151
+
152
+ ```typescript
153
+ import { Module } from '@nestjs/common';
154
+ import { ServerPinoModule } from '@onivoro/server-pino';
155
+
156
+ @Module({
157
+ imports: [
158
+ ServerPinoModule.forRoot({
159
+ level: 'info',
160
+ prettyPrint: process.env.NODE_ENV === 'development',
161
+ transport: {
162
+ target: 'pino-pretty',
163
+ options: {
164
+ colorize: true,
165
+ translateTime: 'SYS:standard',
166
+ ignore: 'pid,hostname'
167
+ }
168
+ },
169
+ serializers: {
170
+ req: (req) => ({
171
+ method: req.method,
172
+ url: req.url,
173
+ headers: req.headers,
174
+ remoteAddress: req.remoteAddress,
175
+ remotePort: req.remotePort
176
+ }),
177
+ res: (res) => ({
178
+ statusCode: res.statusCode,
179
+ headers: res.headers
180
+ })
181
+ }
182
+ })
183
+ ],
184
+ })
185
+ export class AppModule {}
186
+ ```
187
+
188
+ ### Request Logging
189
+
190
+ ```typescript
191
+ import { Injectable, NestMiddleware, Logger } from '@nestjs/common';
192
+ import { Request, Response, NextFunction } from 'express';
193
+
194
+ @Injectable()
195
+ export class LoggingMiddleware implements NestMiddleware {
196
+ private readonly logger = new Logger(LoggingMiddleware.name);
197
+
198
+ use(req: Request, res: Response, next: NextFunction): void {
199
+ const startTime = Date.now();
200
+ const { method, originalUrl, headers, body } = req;
201
+
202
+ // Log incoming request
203
+ this.logger.log('Incoming request', {
204
+ method,
205
+ url: originalUrl,
206
+ userAgent: headers['user-agent'],
207
+ contentLength: headers['content-length'],
208
+ requestId: req.headers['x-request-id']
209
+ });
210
+
211
+ // Log response when finished
212
+ res.on('finish', () => {
213
+ const duration = Date.now() - startTime;
214
+ this.logger.log('Request completed', {
215
+ method,
216
+ url: originalUrl,
217
+ statusCode: res.statusCode,
218
+ duration,
219
+ requestId: req.headers['x-request-id']
220
+ });
221
+ });
222
+
223
+ next();
224
+ }
225
+ }
226
+ ```
227
+
228
+ ### Error Logging
229
+
230
+ ```typescript
231
+ import { Injectable, Logger } from '@nestjs/common';
232
+ import { ExceptionFilter, Catch, ArgumentsHost, HttpException } from '@nestjs/common';
233
+
234
+ @Injectable()
235
+ @Catch()
236
+ export class GlobalExceptionFilter implements ExceptionFilter {
237
+ private readonly logger = new Logger(GlobalExceptionFilter.name);
238
+
239
+ catch(exception: unknown, host: ArgumentsHost): void {
240
+ const ctx = host.switchToHttp();
241
+ const response = ctx.getResponse();
242
+ const request = ctx.getRequest();
243
+
244
+ const status = exception instanceof HttpException
245
+ ? exception.getStatus()
246
+ : 500;
247
+
248
+ const message = exception instanceof HttpException
249
+ ? exception.message
250
+ : 'Internal server error';
251
+
252
+ // Structured error logging
253
+ this.logger.error('Exception caught', {
254
+ error: {
255
+ message,
256
+ stack: exception instanceof Error ? exception.stack : undefined,
257
+ status
258
+ },
259
+ request: {
260
+ method: request.method,
261
+ url: request.url,
262
+ headers: request.headers,
263
+ body: request.body,
264
+ requestId: request.headers['x-request-id']
265
+ },
266
+ timestamp: new Date().toISOString()
267
+ });
268
+
269
+ response.status(status).json({
270
+ statusCode: status,
271
+ message,
272
+ timestamp: new Date().toISOString(),
273
+ path: request.url
274
+ });
275
+ }
276
+ }
277
+ ```
278
+
279
+ ### Performance Logging
280
+
281
+ ```typescript
282
+ import { Injectable, Logger } from '@nestjs/common';
283
+
284
+ @Injectable()
285
+ export class PerformanceService {
286
+ private readonly logger = new Logger(PerformanceService.name);
287
+
288
+ async measurePerformance<T>(
289
+ operation: () => Promise<T>,
290
+ operationName: string,
291
+ metadata?: Record<string, any>
292
+ ): Promise<T> {
293
+ const startTime = process.hrtime.bigint();
294
+ const startMemory = process.memoryUsage();
295
+
296
+ try {
297
+ const result = await operation();
298
+ const endTime = process.hrtime.bigint();
299
+ const endMemory = process.memoryUsage();
300
+
301
+ const duration = Number(endTime - startTime) / 1000000; // Convert to milliseconds
302
+ const memoryDelta = {
303
+ rss: endMemory.rss - startMemory.rss,
304
+ heapUsed: endMemory.heapUsed - startMemory.heapUsed,
305
+ heapTotal: endMemory.heapTotal - startMemory.heapTotal
306
+ };
307
+
308
+ this.logger.log('Performance measurement', {
309
+ operation: operationName,
310
+ duration,
311
+ memory: {
312
+ before: startMemory,
313
+ after: endMemory,
314
+ delta: memoryDelta
315
+ },
316
+ metadata
317
+ });
318
+
319
+ return result;
320
+ } catch (error) {
321
+ const endTime = process.hrtime.bigint();
322
+ const duration = Number(endTime - startTime) / 1000000;
323
+
324
+ this.logger.error('Performance measurement failed', {
325
+ operation: operationName,
326
+ duration,
327
+ error: error.message,
328
+ metadata
329
+ });
330
+
331
+ throw error;
332
+ }
333
+ }
334
+ }
335
+ ```
336
+
337
+ ### Contextual Logging
338
+
339
+ ```typescript
340
+ import { Injectable, Logger } from '@nestjs/common';
341
+ import { AsyncLocalStorage } from 'async_hooks';
342
+
343
+ interface LogContext {
344
+ requestId?: string;
345
+ userId?: string;
346
+ operationId?: string;
347
+ correlationId?: string;
348
+ }
349
+
350
+ @Injectable()
351
+ export class ContextualLogger {
352
+ private readonly logger = new Logger(ContextualLogger.name);
353
+ private readonly context = new AsyncLocalStorage<LogContext>();
354
+
355
+ setContext(context: LogContext): void {
356
+ this.context.enterWith(context);
357
+ }
358
+
359
+ log(message: string, data?: any): void {
360
+ const context = this.context.getStore();
361
+ this.logger.log(message, { ...data, context });
362
+ }
363
+
364
+ error(message: string, trace?: string, data?: any): void {
365
+ const context = this.context.getStore();
366
+ this.logger.error(message, trace, { ...data, context });
367
+ }
368
+
369
+ warn(message: string, data?: any): void {
370
+ const context = this.context.getStore();
371
+ this.logger.warn(message, { ...data, context });
372
+ }
373
+
374
+ debug(message: string, data?: any): void {
375
+ const context = this.context.getStore();
376
+ this.logger.debug(message, { ...data, context });
377
+ }
378
+ }
379
+ ```
380
+
381
+ ## API Reference
382
+
383
+ ### ServerPinoConfig
384
+
385
+ Configuration class for Pino logging:
386
+
387
+ ```typescript
388
+ @EnvironmentClass()
389
+ export class ServerPinoConfig {
390
+ @EnvironmentVariable('LOG_LEVEL', 'info')
391
+ logLevel: string;
392
+
393
+ @EnvironmentVariable('LOG_PRETTY', 'false')
394
+ prettyPrint: boolean;
395
+
396
+ @EnvironmentVariable('LOG_DESTINATION', 'stdout')
397
+ destination: string;
398
+
399
+ @EnvironmentVariable('LOG_REQUESTS', 'true')
400
+ logRequests: boolean;
401
+ }
402
+ ```
403
+
404
+ ### Functions
405
+
406
+ #### patchConsole
407
+
408
+ Patch console methods to use structured logging:
409
+
410
+ ```typescript
411
+ function patchConsole(options?: {
412
+ logLevel?: string;
413
+ includeStack?: boolean;
414
+ formatters?: Record<string, (args: any[]) => any>;
415
+ }): void
416
+ ```
417
+
418
+ ### Log Levels
419
+
420
+ Available log levels in order of severity:
421
+
422
+ 1. **trace** - Most detailed information
423
+ 2. **debug** - Detailed information for debugging
424
+ 3. **info** - General information about application flow
425
+ 4. **warn** - Warning messages for potentially harmful situations
426
+ 5. **error** - Error events that allow the application to continue
427
+ 6. **fatal** - Critical errors that might cause the application to abort
428
+
429
+ ### Structured Log Format
430
+
431
+ All logs follow this structure:
432
+
433
+ ```json
434
+ {
435
+ "level": 30,
436
+ "time": 1640995200000,
437
+ "pid": 12345,
438
+ "hostname": "server-01",
439
+ "msg": "User logged in",
440
+ "userId": "123",
441
+ "requestId": "req-456",
442
+ "v": 1
443
+ }
444
+ ```
445
+
446
+ ## Best Practices
447
+
448
+ 1. **Use Structured Data**: Always include relevant context in log messages
449
+ 2. **Consistent Log Levels**: Use appropriate log levels for different types of messages
450
+ 3. **Request Correlation**: Include request IDs for tracing requests across services
451
+ 4. **Avoid Sensitive Data**: Never log passwords, tokens, or other sensitive information
452
+ 5. **Performance Monitoring**: Use performance logging for critical operations
453
+ 6. **Error Context**: Include full error context when logging exceptions
454
+ 7. **Log Rotation**: Configure log rotation for production environments
455
+ 8. **Centralized Logging**: Use centralized logging systems in production
456
+
457
+ ## Integration with Monitoring Systems
458
+
459
+ ### ELK Stack
460
+
461
+ ```typescript
462
+ // Configure for Elasticsearch ingestion
463
+ const pinoConfig = {
464
+ level: 'info',
465
+ formatters: {
466
+ timestamp: () => ({ '@timestamp': new Date().toISOString() }),
467
+ level: (level) => ({ level: level })
468
+ }
469
+ };
470
+ ```
471
+
472
+ ### AWS CloudWatch
473
+
474
+ ```typescript
475
+ // Use AWS CloudWatch transport
476
+ const pinoConfig = {
477
+ transport: {
478
+ target: 'pino-cloudwatch',
479
+ options: {
480
+ logGroup: '/aws/lambda/my-function',
481
+ logStream: 'my-stream',
482
+ region: 'us-east-1'
483
+ }
484
+ }
485
+ };
486
+ ```
487
+
488
+ ## Testing
489
+
490
+ ```typescript
491
+ import { Test } from '@nestjs/testing';
492
+ import { ServerPinoModule } from '@onivoro/server-pino';
493
+ import { Logger } from '@nestjs/common';
494
+
495
+ describe('Pino Logging', () => {
496
+ let logger: Logger;
497
+
498
+ beforeEach(async () => {
499
+ const module = await Test.createTestingModule({
500
+ imports: [ServerPinoModule],
501
+ }).compile();
502
+
503
+ logger = module.get<Logger>(Logger);
504
+ });
505
+
506
+ it('should log messages', () => {
507
+ const logSpy = jest.spyOn(logger, 'log');
508
+
509
+ logger.log('Test message', { data: 'test' });
510
+
511
+ expect(logSpy).toHaveBeenCalledWith('Test message', { data: 'test' });
512
+ });
513
+ });
514
+ ```
515
+
516
+ ## License
517
+
518
+ This library is part of the Onivoro monorepo ecosystem.
package/jest.config.ts ADDED
@@ -0,0 +1,11 @@
1
+ /* eslint-disable */
2
+ export default {
3
+ displayName: 'lib-server-pino',
4
+ preset: '../../../jest.preset.js',
5
+ testEnvironment: 'node',
6
+ transform: {
7
+ '^.+\\.[tj]s$': ['ts-jest', { tsconfig: '<rootDir>/tsconfig.spec.json' }],
8
+ },
9
+ moduleFileExtensions: ['ts', 'js', 'html'],
10
+ coverageDirectory: '../../../coverage/libs/server/pino',
11
+ };
package/package.json CHANGED
@@ -1,47 +1,11 @@
1
1
  {
2
- "name": "@onivoro/server-pino",
3
- "version": "22.0.12",
4
- "repository": {
5
- "url": "git+https://github.com/onivoro/server-pino.git"
6
- },
7
- "main": "dist/cjs/index.js",
8
- "module": "dist/esm/index.js",
9
- "types": "dist/types/index.d.ts",
10
- "files": [
11
- "dist/*"
12
- ],
13
- "scripts": {
14
- "onx": "onx",
15
- "build": "onx Build",
16
- "deploy": "onx Publish",
17
- "test": "onx Test",
18
- "update": "onx Update"
19
- },
20
- "exports": {
21
- ".": {
22
- "types": "./dist/types/index.d.ts",
23
- "require": "./dist/cjs/index.js",
24
- "import": "./dist/esm/index.js",
25
- "default": "./dist/esm/lib.js"
26
- }
27
- },
28
- "onx": {
29
- "platform": "server",
30
- "module": "commonjs"
31
- },
32
- "devDependencies": {
33
- "@onivoro/cli": "*",
34
- "@types/jest": "*",
35
- "@types/node": "22.9.0",
36
- "typescript": "*"
37
- },
38
- "engines": {
39
- "node": "22.10.0",
40
- "npm": "10.9.0"
41
- },
42
- "dependencies": {
43
- "@nestjs/common": "^10.4.8",
44
- "@onivoro/server-common": "^22.0.3",
45
- "nestjs-pino": "^4.1.0"
46
- }
2
+ "name": "@onivoro/server-pino",
3
+ "version": "24.0.1",
4
+ "type": "commonjs",
5
+ "main": "./src/index.js",
6
+ "types": "./src/index.d.ts",
7
+ "dependencies": {
8
+ "@onivoro/server-common": "24.0.1",
9
+ "tslib": "^2.3.0"
10
+ }
47
11
  }
package/project.json ADDED
@@ -0,0 +1,23 @@
1
+ {
2
+ "name": "lib-server-pino",
3
+ "$schema": "../../../node_modules/nx/schemas/project-schema.json",
4
+ "sourceRoot": "libs/server/pino/src",
5
+ "projectType": "library",
6
+ "targets": {
7
+ "build": {
8
+ "executor": "@nx/js:tsc",
9
+ "outputs": ["{options.outputPath}"],
10
+ "options": {
11
+ "outputPath": "dist/libs/server/pino",
12
+ "main": "libs/server/pino/src/index.ts",
13
+ "tsConfig": "libs/server/pino/tsconfig.lib.json",
14
+ "assets": [
15
+ "libs/server/pino/README.md",
16
+ "libs/server/pino/package.json"
17
+ ],
18
+ "declaration": true
19
+ }
20
+ }
21
+ },
22
+ "tags": []
23
+ }
@@ -1,3 +1,5 @@
1
1
  export * from './lib/classes/server-pino-config.class';
2
+
2
3
  export * from './lib/functions/patch-console.function';
3
- export * from './lib/server-pino.module';
4
+
5
+ export * from './lib/server-pino.module';
@@ -0,0 +1,68 @@
1
+ import { RouteInfo, Type } from "@nestjs/common/interfaces";
2
+ import { randomUUID } from "crypto";
3
+ import { Params } from "nestjs-pino";
4
+ import { IncomingMessage, ServerResponse } from "node:http";
5
+ import { DestinationStream } from "pino";
6
+ import { Options } from "pino-http";
7
+
8
+ export const apiIdHeader = 'x-api-id';
9
+ export const apiKeyHeader = 'x-api-key';
10
+
11
+ export class ServerPinoConfig implements Params {
12
+ exclude?: (string | RouteInfo)[] | undefined;
13
+ pinoHttp?: Options<IncomingMessage, ServerResponse<IncomingMessage>, never> | DestinationStream | [Options<IncomingMessage, ServerResponse<IncomingMessage>, never>, DestinationStream] | undefined;
14
+ forRoutes?: (string | RouteInfo | Type<any>)[] | undefined;
15
+ renameContext?: string | undefined;
16
+ useExisting?: true | undefined;
17
+
18
+ constructor(overrides?: Partial<Params> & { excludeUrls?: (string | RegExp)[] }) {
19
+ const defaultValues = ServerPinoConfig.getDefaultParams(overrides?.excludeUrls);
20
+
21
+ Object.entries({ ...defaultValues, ...(overrides || {}) }).forEach(([key, value]) => {
22
+ (this as any)[key] = value;
23
+ });
24
+ }
25
+
26
+ static getDefaultParams(excludeUrls: (string | RegExp)[] = ['/api/health']): Params {
27
+ return {
28
+ pinoHttp: {
29
+ autoLogging: {
30
+ ignore: !!excludeUrls.length
31
+ ? (req) => excludeUrls.some(pattern =>
32
+ typeof pattern === 'string'
33
+ ? req.url === pattern
34
+ : pattern instanceof RegExp
35
+ ? pattern.test((req as any).url)
36
+ : false
37
+ )
38
+ : (req) => false,
39
+ },
40
+ genReqId: () => randomUUID(),
41
+ redact: [
42
+ 'req.headers["accept"]',
43
+ 'req.headers["accept-encoding"]',
44
+ 'req.headers["accept-language"]',
45
+ 'req.headers["authorization"]',
46
+ `req.headers["${apiIdHeader}"]`,
47
+ `req.headers["${apiKeyHeader}"]`,
48
+ 'req.headers["cache-control"]',
49
+ 'req.headers["connection"]',
50
+ 'req.headers["cookie"]',
51
+ 'req.headers["sec-ch-ua"]',
52
+ 'req.headers["sec-ch-ua-mobile"]',
53
+ 'req.headers["sec-ch-ua-platform"]',
54
+ 'req.headers["sec-fetch-dest"]',
55
+ 'req.headers["sec-fetch-mode"]',
56
+ 'req.headers["sec-fetch-site"]',
57
+ 'req.headers["sec-fetch-user"]',
58
+ 'req.headers["cookie"]',
59
+ 'res.headers["set-cookie"]',
60
+ 'req.headers["upgrade-insecure-requests"]',
61
+ 'req.headers["user-agent"]',
62
+ ],
63
+ useLevel: 'info',
64
+ transport: undefined,
65
+ }
66
+ };
67
+ }
68
+ }
@@ -1,8 +1,8 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.patchConsole = patchConsole;
4
- function patchConsole(logger) {
1
+ import { PinoLogger } from 'nestjs-pino';
2
+
3
+ export function patchConsole(logger: PinoLogger) {
5
4
  const _console = logger;
5
+
6
6
  const original = {
7
7
  debug: console.debug,
8
8
  error: console.error,
@@ -11,29 +11,36 @@ function patchConsole(logger) {
11
11
  trace: console.trace,
12
12
  warn: console.warn,
13
13
  };
14
+
14
15
  console.debug = (...args) => {
15
- _console.debug({ msg: args });
16
+ _console.debug({msg: args});
16
17
  };
18
+
17
19
  console.error = (...args) => {
18
- _console.error({ msg: args });
20
+ _console.error({msg: args});
19
21
  };
22
+
20
23
  console.info = (...args) => {
21
- _console.info({ msg: args });
24
+ _console.info({msg: args});
22
25
  };
26
+
23
27
  console.log = (...args) => {
24
- _console.info({ msg: args });
28
+ _console.info({msg: args});
25
29
  };
30
+
26
31
  console.trace = (...args) => {
27
- _console.trace({ msg: args });
32
+ _console.trace({msg: args});
28
33
  };
34
+
29
35
  console.warn = (...args) => {
30
- _console.warn({ msg: args });
36
+ _console.warn({msg: args});
31
37
  };
38
+
32
39
  return {
33
40
  _console,
34
41
  restore: () => {
35
42
  Object.entries(original).forEach(([method, implementation]) => {
36
- console[method] = implementation;
43
+ (console as any)[method] = implementation;
37
44
  });
38
45
  }
39
46
  };
@@ -0,0 +1,34 @@
1
+ import { Module } from '@nestjs/common';
2
+ import { LoggerModule, PinoLogger } from 'nestjs-pino';
3
+ import { ServerPinoConfig } from './classes/server-pino-config.class';
4
+ import { moduleFactory } from '@onivoro/server-common';
5
+ import { patchConsole } from './functions/patch-console.function';
6
+
7
+ @Module({})
8
+ export class ServerPinoModule {
9
+ static configure(config: ServerPinoConfig, patchConsoleInstance = false) {
10
+
11
+ if (patchConsoleInstance) {
12
+ patchConsole(new PinoLogger(config));
13
+ }
14
+
15
+ if (process.env.NODE_ENV === 'production') {
16
+ console.log('prod')
17
+ return moduleFactory({
18
+ module: ServerPinoModule,
19
+ imports: [LoggerModule.forRoot(config)],
20
+ providers: [
21
+ { provide: ServerPinoConfig, useValue: config },
22
+ ]
23
+ });
24
+ }
25
+
26
+ return moduleFactory({
27
+ module: ServerPinoModule,
28
+ providers: [
29
+ { provide: ServerPinoConfig, useValue: config },
30
+ ]
31
+ });
32
+ }
33
+ }
34
+
package/tsconfig.json ADDED
@@ -0,0 +1,16 @@
1
+ {
2
+ "extends": "../../../tsconfig.server.json",
3
+ "compilerOptions": {
4
+ "outDir": "../../../dist/out-tsc"
5
+ },
6
+ "files": [],
7
+ "include": [],
8
+ "references": [
9
+ {
10
+ "path": "./tsconfig.lib.json"
11
+ },
12
+ {
13
+ "path": "./tsconfig.spec.json"
14
+ }
15
+ ]
16
+ }
@@ -0,0 +1,8 @@
1
+ {
2
+ "extends": "./tsconfig.json",
3
+ "compilerOptions": {
4
+ "declaration": true
5
+ },
6
+ "exclude": ["jest.config.ts", "**/*.spec.ts", "**/*.test.ts"],
7
+ "include": ["**/*.ts"]
8
+ }
@@ -0,0 +1,21 @@
1
+ {
2
+ "extends": "./tsconfig.json",
3
+ "compilerOptions": {
4
+ "types": [
5
+ "jest",
6
+ "node"
7
+ ]
8
+ },
9
+ "include": [
10
+ "jest.config.ts",
11
+ "**/*.test.ts",
12
+ "**/*.spec.ts",
13
+ "**/*.test.tsx",
14
+ "**/*.spec.tsx",
15
+ "**/*.test.js",
16
+ "**/*.spec.js",
17
+ "**/*.test.jsx",
18
+ "**/*.spec.jsx",
19
+ "**/*.d.ts"
20
+ ]
21
+ }
package/dist/cjs/index.js DELETED
@@ -1,19 +0,0 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
- for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
- };
16
- Object.defineProperty(exports, "__esModule", { value: true });
17
- __exportStar(require("./lib/classes/server-pino-config.class"), exports);
18
- __exportStar(require("./lib/functions/patch-console.function"), exports);
19
- __exportStar(require("./lib/server-pino.module"), exports);
@@ -1,16 +0,0 @@
1
- import { RouteInfo, Type } from "@nestjs/common/interfaces";
2
- import { Params } from "nestjs-pino";
3
- import { IncomingMessage, ServerResponse } from "node:http";
4
- import { DestinationStream } from "pino";
5
- import { Options } from "pino-http";
6
- export declare const apiIdHeader = "x-api-id";
7
- export declare const apiKeyHeader = "x-api-key";
8
- export declare class ServerPinoConfig implements Params {
9
- exclude?: (string | RouteInfo)[] | undefined;
10
- pinoHttp?: Options<IncomingMessage, ServerResponse<IncomingMessage>, never> | DestinationStream | [Options<IncomingMessage, ServerResponse<IncomingMessage>, never>, DestinationStream] | undefined;
11
- forRoutes?: (string | RouteInfo | Type<any>)[] | undefined;
12
- renameContext?: string | undefined;
13
- useExisting?: true | undefined;
14
- constructor(overrides?: Partial<Params>);
15
- static getDefaultParams(): Params;
16
- }
@@ -1,50 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ServerPinoConfig = exports.apiKeyHeader = exports.apiIdHeader = void 0;
4
- const crypto_1 = require("crypto");
5
- exports.apiIdHeader = 'x-api-id';
6
- exports.apiKeyHeader = 'x-api-key';
7
- class ServerPinoConfig {
8
- exclude;
9
- pinoHttp;
10
- forRoutes;
11
- renameContext;
12
- useExisting;
13
- constructor(overrides) {
14
- const defaultValues = ServerPinoConfig.getDefaultParams();
15
- Object.entries({ ...defaultValues, ...(overrides || {}) }).forEach(([key, value]) => {
16
- this[key] = value;
17
- });
18
- }
19
- static getDefaultParams() {
20
- return {
21
- pinoHttp: {
22
- autoLogging: true,
23
- genReqId: () => (0, crypto_1.randomUUID)(),
24
- redact: [
25
- 'req.headers["accept"]',
26
- 'req.headers["accept-encoding"]',
27
- 'req.headers["accept-language"]',
28
- 'req.headers["authorization"]',
29
- `req.headers["${exports.apiIdHeader}"]`,
30
- `req.headers["${exports.apiKeyHeader}"]`,
31
- 'req.headers["cache-control"]',
32
- 'req.headers["connection"]',
33
- 'req.headers["cookie"]',
34
- 'req.headers["sec-ch-ua"]',
35
- 'req.headers["sec-ch-ua-mobile"]',
36
- 'req.headers["sec-ch-ua-platform"]',
37
- 'req.headers["sec-fetch-dest"]',
38
- 'req.headers["sec-fetch-mode"]',
39
- 'req.headers["sec-fetch-site"]',
40
- 'req.headers["sec-fetch-user"]',
41
- 'req.headers["upgrade-insecure-requests"]',
42
- 'req.headers["user-agent"]',
43
- ],
44
- useLevel: 'info',
45
- transport: undefined,
46
- }
47
- };
48
- }
49
- }
50
- exports.ServerPinoConfig = ServerPinoConfig;
@@ -1,5 +0,0 @@
1
- import { PinoLogger } from 'nestjs-pino';
2
- export declare function patchConsole(logger: PinoLogger): {
3
- _console: PinoLogger;
4
- restore: () => void;
5
- };
@@ -1,4 +0,0 @@
1
- import { ServerPinoConfig } from './classes/server-pino-config.class';
2
- export declare class ServerPinoModule {
3
- static configure(config: ServerPinoConfig, patchConsoleInstance?: boolean): any;
4
- }
@@ -1,33 +0,0 @@
1
- "use strict";
2
- var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
- return c > 3 && r && Object.defineProperty(target, key, r), r;
7
- };
8
- var ServerPinoModule_1;
9
- Object.defineProperty(exports, "__esModule", { value: true });
10
- exports.ServerPinoModule = void 0;
11
- const common_1 = require("@nestjs/common");
12
- const nestjs_pino_1 = require("nestjs-pino");
13
- const server_pino_config_class_1 = require("./classes/server-pino-config.class");
14
- const server_common_1 = require("@onivoro/server-common");
15
- const patch_console_function_1 = require("./functions/patch-console.function");
16
- let ServerPinoModule = ServerPinoModule_1 = class ServerPinoModule {
17
- static configure(config, patchConsoleInstance = false) {
18
- if (patchConsoleInstance) {
19
- (0, patch_console_function_1.patchConsole)(new nestjs_pino_1.PinoLogger(config));
20
- }
21
- return (0, server_common_1.moduleFactory)({
22
- module: ServerPinoModule_1,
23
- imports: [nestjs_pino_1.LoggerModule.forRoot(config)],
24
- providers: [
25
- { provide: server_pino_config_class_1.ServerPinoConfig, useValue: config },
26
- ]
27
- });
28
- }
29
- };
30
- exports.ServerPinoModule = ServerPinoModule;
31
- exports.ServerPinoModule = ServerPinoModule = ServerPinoModule_1 = __decorate([
32
- (0, common_1.Module)({})
33
- ], ServerPinoModule);
@@ -1,3 +0,0 @@
1
- export * from './lib/classes/server-pino-config.class';
2
- export * from './lib/functions/patch-console.function';
3
- export * from './lib/server-pino.module';
package/dist/esm/index.js DELETED
@@ -1,19 +0,0 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
- for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
- };
16
- Object.defineProperty(exports, "__esModule", { value: true });
17
- __exportStar(require("./lib/classes/server-pino-config.class"), exports);
18
- __exportStar(require("./lib/functions/patch-console.function"), exports);
19
- __exportStar(require("./lib/server-pino.module"), exports);
@@ -1,16 +0,0 @@
1
- import { RouteInfo, Type } from "@nestjs/common/interfaces";
2
- import { Params } from "nestjs-pino";
3
- import { IncomingMessage, ServerResponse } from "node:http";
4
- import { DestinationStream } from "pino";
5
- import { Options } from "pino-http";
6
- export declare const apiIdHeader = "x-api-id";
7
- export declare const apiKeyHeader = "x-api-key";
8
- export declare class ServerPinoConfig implements Params {
9
- exclude?: (string | RouteInfo)[] | undefined;
10
- pinoHttp?: Options<IncomingMessage, ServerResponse<IncomingMessage>, never> | DestinationStream | [Options<IncomingMessage, ServerResponse<IncomingMessage>, never>, DestinationStream] | undefined;
11
- forRoutes?: (string | RouteInfo | Type<any>)[] | undefined;
12
- renameContext?: string | undefined;
13
- useExisting?: true | undefined;
14
- constructor(overrides?: Partial<Params>);
15
- static getDefaultParams(): Params;
16
- }
@@ -1,50 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ServerPinoConfig = exports.apiKeyHeader = exports.apiIdHeader = void 0;
4
- const crypto_1 = require("crypto");
5
- exports.apiIdHeader = 'x-api-id';
6
- exports.apiKeyHeader = 'x-api-key';
7
- class ServerPinoConfig {
8
- exclude;
9
- pinoHttp;
10
- forRoutes;
11
- renameContext;
12
- useExisting;
13
- constructor(overrides) {
14
- const defaultValues = ServerPinoConfig.getDefaultParams();
15
- Object.entries({ ...defaultValues, ...(overrides || {}) }).forEach(([key, value]) => {
16
- this[key] = value;
17
- });
18
- }
19
- static getDefaultParams() {
20
- return {
21
- pinoHttp: {
22
- autoLogging: true,
23
- genReqId: () => (0, crypto_1.randomUUID)(),
24
- redact: [
25
- 'req.headers["accept"]',
26
- 'req.headers["accept-encoding"]',
27
- 'req.headers["accept-language"]',
28
- 'req.headers["authorization"]',
29
- `req.headers["${exports.apiIdHeader}"]`,
30
- `req.headers["${exports.apiKeyHeader}"]`,
31
- 'req.headers["cache-control"]',
32
- 'req.headers["connection"]',
33
- 'req.headers["cookie"]',
34
- 'req.headers["sec-ch-ua"]',
35
- 'req.headers["sec-ch-ua-mobile"]',
36
- 'req.headers["sec-ch-ua-platform"]',
37
- 'req.headers["sec-fetch-dest"]',
38
- 'req.headers["sec-fetch-mode"]',
39
- 'req.headers["sec-fetch-site"]',
40
- 'req.headers["sec-fetch-user"]',
41
- 'req.headers["upgrade-insecure-requests"]',
42
- 'req.headers["user-agent"]',
43
- ],
44
- useLevel: 'info',
45
- transport: undefined,
46
- }
47
- };
48
- }
49
- }
50
- exports.ServerPinoConfig = ServerPinoConfig;
@@ -1,5 +0,0 @@
1
- import { PinoLogger } from 'nestjs-pino';
2
- export declare function patchConsole(logger: PinoLogger): {
3
- _console: PinoLogger;
4
- restore: () => void;
5
- };
@@ -1,40 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.patchConsole = patchConsole;
4
- function patchConsole(logger) {
5
- const _console = logger;
6
- const original = {
7
- debug: console.debug,
8
- error: console.error,
9
- info: console.info,
10
- log: console.log,
11
- trace: console.trace,
12
- warn: console.warn,
13
- };
14
- console.debug = (...args) => {
15
- _console.debug({ msg: args });
16
- };
17
- console.error = (...args) => {
18
- _console.error({ msg: args });
19
- };
20
- console.info = (...args) => {
21
- _console.info({ msg: args });
22
- };
23
- console.log = (...args) => {
24
- _console.info({ msg: args });
25
- };
26
- console.trace = (...args) => {
27
- _console.trace({ msg: args });
28
- };
29
- console.warn = (...args) => {
30
- _console.warn({ msg: args });
31
- };
32
- return {
33
- _console,
34
- restore: () => {
35
- Object.entries(original).forEach(([method, implementation]) => {
36
- console[method] = implementation;
37
- });
38
- }
39
- };
40
- }
@@ -1,4 +0,0 @@
1
- import { ServerPinoConfig } from './classes/server-pino-config.class';
2
- export declare class ServerPinoModule {
3
- static configure(config: ServerPinoConfig, patchConsoleInstance?: boolean): any;
4
- }
@@ -1,33 +0,0 @@
1
- "use strict";
2
- var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
- return c > 3 && r && Object.defineProperty(target, key, r), r;
7
- };
8
- var ServerPinoModule_1;
9
- Object.defineProperty(exports, "__esModule", { value: true });
10
- exports.ServerPinoModule = void 0;
11
- const common_1 = require("@nestjs/common");
12
- const nestjs_pino_1 = require("nestjs-pino");
13
- const server_pino_config_class_1 = require("./classes/server-pino-config.class");
14
- const server_common_1 = require("@onivoro/server-common");
15
- const patch_console_function_1 = require("./functions/patch-console.function");
16
- let ServerPinoModule = ServerPinoModule_1 = class ServerPinoModule {
17
- static configure(config, patchConsoleInstance = false) {
18
- if (patchConsoleInstance) {
19
- (0, patch_console_function_1.patchConsole)(new nestjs_pino_1.PinoLogger(config));
20
- }
21
- return (0, server_common_1.moduleFactory)({
22
- module: ServerPinoModule_1,
23
- imports: [nestjs_pino_1.LoggerModule.forRoot(config)],
24
- providers: [
25
- { provide: server_pino_config_class_1.ServerPinoConfig, useValue: config },
26
- ]
27
- });
28
- }
29
- };
30
- exports.ServerPinoModule = ServerPinoModule;
31
- exports.ServerPinoModule = ServerPinoModule = ServerPinoModule_1 = __decorate([
32
- (0, common_1.Module)({})
33
- ], ServerPinoModule);
@@ -1,3 +0,0 @@
1
- export * from './lib/classes/server-pino-config.class';
2
- export * from './lib/functions/patch-console.function';
3
- export * from './lib/server-pino.module';
@@ -1,16 +0,0 @@
1
- import { RouteInfo, Type } from "@nestjs/common/interfaces";
2
- import { Params } from "nestjs-pino";
3
- import { IncomingMessage, ServerResponse } from "node:http";
4
- import { DestinationStream } from "pino";
5
- import { Options } from "pino-http";
6
- export declare const apiIdHeader = "x-api-id";
7
- export declare const apiKeyHeader = "x-api-key";
8
- export declare class ServerPinoConfig implements Params {
9
- exclude?: (string | RouteInfo)[] | undefined;
10
- pinoHttp?: Options<IncomingMessage, ServerResponse<IncomingMessage>, never> | DestinationStream | [Options<IncomingMessage, ServerResponse<IncomingMessage>, never>, DestinationStream] | undefined;
11
- forRoutes?: (string | RouteInfo | Type<any>)[] | undefined;
12
- renameContext?: string | undefined;
13
- useExisting?: true | undefined;
14
- constructor(overrides?: Partial<Params>);
15
- static getDefaultParams(): Params;
16
- }
@@ -1,5 +0,0 @@
1
- import { PinoLogger } from 'nestjs-pino';
2
- export declare function patchConsole(logger: PinoLogger): {
3
- _console: PinoLogger;
4
- restore: () => void;
5
- };
@@ -1,4 +0,0 @@
1
- import { ServerPinoConfig } from './classes/server-pino-config.class';
2
- export declare class ServerPinoModule {
3
- static configure(config: ServerPinoConfig, patchConsoleInstance?: boolean): any;
4
- }