Code Monkey home page Code Monkey logo

nestjs-pino's Introduction

Here is a list of my own open source projects:

NestJS

nestjs-pino

GitHub stars npm

Platform agnostic logger for NestJS based on pino with request context in every log.


nestjs-session

GitHub stars npm

Idiomatic session module for NestJS. Built on top of express-session.


nestjs-cookie-session

GitHub stars npm

Idiomatic cookie session module for NestJS. Built on top of cookie-session.


nestjs-roles

GitHub stars npm

Type safe roles guard and decorator made easy.


nestjs-injectable

GitHub stars npm

@Injectable() on steroids that simplifies work with inversion of control in your hexagonal architecture.


nest-ratelimiter

GitHub stars npm

Distributed consistent flexible NestJS rate limiter based on Redis.


create-nestjs-middleware-module

GitHub stars npm

Create a simple idiomatic NestJS module based on Express/Fastify middleware in just a few lines of code with routing out of the box.


nestjs-configure-after

GitHub stars npm

Declarative configuration of NestJS middleware order.


nestjs-saga

GitHub stars npm

Basic implementation of saga pattern for NestJS (do not confuse it with the built-in sagas).


nestjs-gcp-pubsub

GitHub stars npm

The most basic and unopinionated implementation of GCP PubSub transport for NestJS microservices.


nest-nsq-transport

GitHub stars npm

The most basic and unopinionated implementation of NSQ transport for NestJS microservices.

React Native

react-native-launch-arguments

GitHub stars npm

Get launch arguments for testing with Detox and Appium.

Go

enviper

GitHub stars

Consider environment variables while unmarshaling viper's config.


rebus

GitHub stars

Type-safe bus generator for go.


ratelimiter

GitHub stars

Rate limiter with sliding window algorithm implementation.

nestjs-pino's People

Contributors

0xslipk avatar actions-user avatar antspk avatar bmeverett avatar dependabot-preview[bot] avatar dependabot[bot] avatar dougludlow avatar exsesx avatar github-actions[bot] avatar gyanendrokh avatar hotsezus avatar iamolegga avatar katafractari avatar mentos1386 avatar mergify[bot] avatar mksmtn avatar rstreefland avatar songkeys avatar tomups avatar trymoto avatar ttoomm318 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

nestjs-pino's Issues

[FEATURE REQUEST] Customize requests messages

Hello,

Is your feature request related to a problem? Please describe.
I would like the ability to customize the messages automatically logged by pino-http (request completed and request errored).

Describe the solution you'd like
Since version 5.0.0 of pino-http, two new options were added: customSuccessMessage and customErrorMessage to do this. So in the end my feature request is only updating the dependencies and publishing a new version. However, the types package is not up to date, so it might not be possible right now.

Describe alternatives you've considered
I haven't considered any alternative yet.

Additional context
Nothing to add.

Thank you!

[FEATURE REQUEST] Support autoLogging ignorePaths feature of pino-http

Is your feature request related to a problem? Please describe.
The latest version of pino-http (4.4.0) includes a new param for autoLogging called ignorePaths which allows you to specify an array of paths to ignore. We need this to prevent logging for our health-check endpoints.

There are two issues I discovered when trying to see if I could get this working with nestjs-pino.

  1. The typescript definitions for pino-http haven't been updated to include this new option. I have created a pull request to add it here (DefinitelyTyped/DefinitelyTyped#43137)

  2. The underlying pino-http feature uses the req.url property to compare against the configured ignore paths. This is a problem because req.url in nest class middlewares gets rewritten with the route mount point stripped. So it is always / regardless of which route is hit. I believe this is a byproduct of how app.use() works in express

Describe the solution you'd like
Somehow figure out how this feature could be implemented.

Describe alternatives you've considered
As a more proactive measure I've put up a PR against pino-http that if accepted would make this feature request irrelevant. It would allow for us to specify the current path through a function passed as an autoLogging option. This would allow us to use req.originalUrl instead of req.url. pinojs/pino-http#80

[QUESTION] Usage with pino-caller

I would like to use pino-caller to log the line number where the log method was invoked. Is it currently possible to use the returned pino-caller logger instance when configuring this module?

[QUESTION] How can I retrieve the 'req.id' from each request?

I have a microservice architecture, where all external requests are http, while internal ones are gRPC.
Now for logging, I want to have a unique id for each http request, so that I can have a correlation between my logs in different microservices.

Is there a way to retrieve the 'req.id', so that I can provide it as metadata in my clientGrpc call?

[BUG] Path exclusion doesn't work as expected with predefined paths

What is the current behavior?

Implementation of route exclusion (see #122 ) does not allow conditional exclusion of predefined paths without explicitly specyfing all of the applications controllers in forRoutes attribute. This issue is caused by a known limitation of Nest interoperability with functional middlewares (please see nestjs #853 for more details).

Please provide the steps to reproduce.

Nestjs-pino module configuration like the one specified below doesn't work as expected, that is GET requests to /live and /ready paths still leave log traces in applications stdout.

{
    forRoutes: [{ path: '*', method: RequestMethod.ALL }],
    exclude: [
        { path: 'live', method: RequestMethod.GET },
        { path: 'ready', method: RequestMethod.GET },
    ],
}

What is the expected behavior?

This is not explicitly stated anywhere, but a good implementation would allow conditional exclusion of predefined routes from request logging without explicitly passing all of the apps controllers, as this approach is cumbersome and error prone. Wrapping logger middleware with path exclusion logic as suggested in #853 might be a good solution.

Please mention other relevant information such as Node.js version and Operating System.

package version
node v12
nest v6+
nestjs-pino v1.1.3

[BUG] When context is supplied to Logger, message gets stringified

What is the current behavior?

Recommended way to use nestjs logger is to instantiate the singleton class Logger from @nestjs/common and supply context to it (https://stackoverflow.com/a/52907695/4601673), like so:

import { Logger } from '@nestjs/common';

class MyService implements OnModuleInit {
  logger = new Logger(MyService.name);
  onModuleInit() {
    this.logger.log({ msg: 'test' });
  }
}

Using this pattern with nestjs-pino works quite well, but there is a catch.
When context is supplied, message is sent as a second argument to pino here: https://github.com/iamolegga/nestjs-pino/blob/master/src/Logger.ts#L35.
This results in message being treated as the format string here: https://github.com/pinojs/pino/blob/master/lib/tools.js#L52.
So if message is an object, it gets stringified into the "msg" field of the logged json object, like so:

{"level":30,"time":1598681218911,"pid":92,"hostname":"sse-sandbox-hxfsk","context":"AppService","msg":"{\"msg\":\"test\"} "}

If context is not supplied, the message is supplied as the first argument and pino correctly logs the message as an object.

Please provide the steps to reproduce.

Here is the minimal codesandbox based on nestjs-typescript-starter with pino-logger applied and used from AppService.
https://codesandbox.io/s/nestjs-pino-logger-context-forked-hxfsk?file=/src/app.service.ts

There are some issues with displaying logging output though :(

What is the expected behavior?

I expect message to be logged the same way it is logged when context is not supplied (i.e. merged into root object), like so:

{"level":30,"time":1598681218911,"pid":92,"hostname":"sse-sandbox-hxfsk","context":"AppService","msg":"test"}

Please mention other relevant information such as Node.js version and Operating System.

I do not think this is relevant, but I am using node v12.18.2 and OS Windows 10 Pro 2004.

P.S.

If this is not an intended behavior, I can make a PR to fix it by merging message into context object in all of the methods of Logger class. I would also like to add this usage example to the documentation.

[QUESTION] Why `PinoLogger` instance don't show the error object

When I use a PinoLogger instance to display some error object like this.logger.error(Error('foo')) I get this:

{
  "level": 50,
  "time": 1590422389076,
  "pid": 27787,
  "hostname": "--",
  "name": "app",
  "req": {
    "id": 1,
    "method": "GET",
    "url": "--",
    "headers": {
      "host": "localhost:3000",
      "user-agent": "insomnia/7.1.1",
      "accept": "*/*"
    },
    "remoteAddress": "127.0.0.1",
    "remotePort": 52126
  },
  "context": "ExceptionsHandler"
}

seems like the arg isn't serialized by pino.stdSerializers.err because

this.logger.error( pino.stdSerializers.err(Error('foo')) )

works as expected (with { type, message, stack }). This happen even when I explicity define the serializers. Is it the right behavior?

Great lib btw!

[FEATURE REQUEST]

Is your feature request related to a problem? Please describe.
I'm looking for a way to add the Application name into each log.

Describe the solution you'd like
I would like a new parameter in forRoot module method in order to give an App name.

Describe alternatives you've considered
I would like to get access to Pino instance logger used in the module in order to create a child logger with this property. This option is maybe more powerful.

Additional context
This kind of information is especially useful when a save all the logs of all micro-services in the same space.

[FEATURE REQUEST] Support GCP logging

Is your feature request related to a problem? Please describe.

A clear and concise description of what you want to happen.
Is it possible to support GCP logging like they have integration with Bunyan and Winston?

When using pino on GCP I see that it's formating logs well to make them supported in Stackdriver and Logging but it's not setting Trace field:( Also there is option to support logs related to request with section "Formatting Request Logs"

Describe the solution you'd like
Describe alternatives you've considered
A clear and concise description of any alternative solutions or features you've considered.

Additional context
Add any other context or screenshots about the feature request here.

[BUG] System logs skipped on startup

Hi,

I am using pino with configuration as illustrated below:

// app.module.ts
import { Module } from '@nestjs/common';
import { LoggerModule } from 'nestjs-pino';
import { AppController } from './app.controller';
import { AppService } from './app.service';

import * as pino from 'pino';

const logger = pino({
  level: process.env.NODE_ENV !== 'prod' ? 'debug' : 'info',
},pino.destination({
  minLength: 4096,
  sync: false,
}));

setInterval(function() {
  logger.flush();
}, 5000).unref();

@Module({
  imports: [
    LoggerModule.forRoot({
      pinoHttp: {
        logger,
        autoLogging: true,
        serializers: {
          err: pino.stdSerializers.err,
          req: r => {
            return {
              id: r.id,
              method: r.method,
              url: r.url,
            };
          },
          res: pino.stdSerializers.res,
        }
      },
    }),
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

and

// main.ts
import { NestFactory } from '@nestjs/core';
import { Logger } from 'nestjs-pino';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule, { logger: false });
  app.useLogger(app.get(Logger));
  await app.listen(3000);
}
bootstrap();

But the logging output missed the system logging part.

> nest start --watch
[10:11:49 PM] Starting compilation in watch mode...

[10:11:53 PM] Found 0 errors. Watching for file changes.

{"level":30,"time":1604671913986,"pid":28435,"hostname":"2070iMac","context":"RoutesResolver","msg":"AppController {}:"}
{"level":30,"time":1604671913987,"pid":28435,"hostname":"2070iMac","context":"RouterExplorer","msg":"Mapped {, GET} route"}
{"level":30,"time":1604671913989,"pid":28435,"hostname":"2070iMac","context":"NestApplication","msg":"Nest application successfully started"}

It is expected to output as many as system logging output, which has logging form modules like NestFactory and InstanceLoader. Below is the output from the default logger.

[10:33:59 PM] Starting compilation in watch mode...

[10:34:00 PM] Found 0 errors. Watching for file changes.

[Nest] 30928   - 11/06/2020, 10:34:01 PM   [NestFactory] Starting Nest application...
[Nest] 30928   - 11/06/2020, 10:34:01 PM   [InstanceLoader] LoggerModule dependencies initialized +15ms
[Nest] 30928   - 11/06/2020, 10:34:01 PM   [InstanceLoader] LoggerCoreModule dependencies initialized +1ms
[Nest] 30928   - 11/06/2020, 10:34:01 PM   [InstanceLoader] AppModule dependencies initialized +0ms
[Nest] 30928   - 11/06/2020, 10:34:01 PM   [RoutesResolver] AppController {}: +6ms
[Nest] 30928   - 11/06/2020, 10:34:01 PM   [RouterExplorer] Mapped {, GET} route +1ms
[Nest] 30928   - 11/06/2020, 10:34:01 PM   [NestApplication] Nest application successfully started +4ms

Here are some sample code to reproduce this issue: https://github.com/wuminqi/example-pino-nestjs

Can you kindly offer a help on this?

Thanks.

[BUG]

What is the current behavior?

TS2322: Type '(configService: ConfigurationService) => Promise<{ useExisting: false; }>' is not assignable to type '(...args: any[]) => Params | Promise<Params>'.
  Type 'Promise<{ useExisting: false; }>' is not assignable to type 'Params | Promise<Params>'.
    Type 'Promise<{ useExisting: false; }>' is not assignable to type 'Promise<Params>'.
      Type '{ useExisting: false; }' is not assignable to type 'Params'.
        Types of property 'useExisting' are incompatible.
          Type 'false' is not assignable to type 'true'.

14       useFactory: async (configService: ConfigurationService) => ({

Please provide the steps to reproduce.

LoggerModule.forRootAsync({
      useFactory: async (configService: ConfigurationService) => ({
        useExisting: false,
      }),
      inject: [ConfigurationService],
    }),

What is the expected behavior?
Should be able to set to false

Please mention other relevant information such as Node.js version and Operating System.
in params.ts

export interface Params {
    pinoHttp?: pinoHttp.Options | DestinationStream | [pinoHttp.Options, DestinationStream];
    exclude?: Parameters<MiddlewareConfigProxy["exclude"]>;
    forRoutes?: Parameters<MiddlewareConfigProxy["forRoutes"]>;
    useExisting?: true; 
    renameContext?: string;
}

should be?

export interface Params {
    pinoHttp?: pinoHttp.Options | DestinationStream | [pinoHttp.Options, DestinationStream];
    exclude?: Parameters<MiddlewareConfigProxy["exclude"]>;
    forRoutes?: Parameters<MiddlewareConfigProxy["forRoutes"]>;
    useExisting?: boolean;
    renameContext?: string;
}

[QUESTION] Use a custom wrapper class to log requests to files

Hi guys,

I want the following setup for my NestJS application:

  1. HTTP requests are logged to a dedicated file, using nestjs-pino. They'll be sent to the ELK logging facilities by Filebeat or whatever.
  2. Additionally, Logger Pino object is available for manual invocation across the project (this.logger.log("...")).
  3. Default NestJS stdout logger is enabled.

How do I achieve that?

Say, I let the "middleware" thing initialize like this:

@Module({
  imports: [ LoggerModule.forRoot({ autologging: false, pinoHttp: { ... } }) ],
  ...
})
export class AppModule {}

Is there a way I can re-create the middleware manually, where I can use my custom class (as per NestJS documentation) which in turn uses Pino logger configured by the LoggerModule, but directs its output to a file?

Thank you very much.

Thanks you for this!

I had a hard time finding a clean and easy way to log HTTP requests with Nest. Thank you โค๏ธ

[BUG] Having installed nestjs-pino, app fails

What is the current behavior?

Running my nest app fails

Output from the console

ts-node -r tsconfig-paths/register src/main.ts | pino-pretty -t

1: 0x8dc510 node::Abort() [node]
2: 0x96f439 [node]
3: 0xb62a3f [node]
4: 0xb635a9 v8::internal::Builtin_HandleApiCall(int, v8::internal::Object**, v8::internal::Isolate*) [node]
5: 0x1db7cbadbe1d
Aborted (core dumped)

Please provide the steps to reproduce.

run the above command

What is the expected behavior?

Application starts and logs correctly

Please mention other relevant information such as Node.js version and Operating System.

Behaviour only happens on ubuntu
Node v12

Core dump

  • thread #1, name = 'node', stop reason = signal SIGABRT
    • frame #0: 0x00007ff48c0f7e97
      frame #1: 0x000000000096f439 nodenode::i18n::Initialize(v8::Local<v8::Object>, v8::Local<v8::Value>, v8::Local<v8::Context>, void*) + 1401 frame #2: 0x0000000000b62a3f nodev8::internal::CompilationCacheRegExp::Lookup(v8::internal::Handlev8::internal::String, v8::base::Flags<v8::internal::JSRegExp::Flag, int>) + 335
      frame #3: 0x0000000000b635a9 nodev8::internal::CompilationCache::PutEval(v8::internal::Handle<v8::internal::String>, v8::internal::Handle<v8::internal::SharedFunctionInfo>, v8::internal::Handle<v8::internal::Context>, v8::internal::Handle<v8::internal::SharedFunctionInfo>, v8::internal::Handle<v8::internal::FeedbackCell>, int) + 89 frame #4: 0x00003b61a755be1d frame #5: 0x00003b61a75118d5 frame #6: 0x00003b61a7e7e798 frame #7: 0x00003b61a7541811 frame #8: 0x00003b61a751f83a frame #9: 0x00003b61a7504ba1 frame #10: 0x0000000000e73f0e nodev8::internal::ParserBasev8::internal::Parser::ParseForAwaitStatement(v8::internal::ZoneList<v8::internal::AstRawString const*>, v8::internal::ZoneList<v8::internal::AstRawString const>) + 94
      frame #11: 0x0000000000f8705b nodev8::internal::Runtime_StringCharCodeAt(int, unsigned long*, v8::internal::Isolate*) + 1115 frame #12: 0x0000000000b62a3f nodev8::internal::CompilationCacheRegExp::Lookup(v8::internal::Handlev8::internal::String, v8::base::Flags<v8::internal::JSRegExp::Flag, int>) + 335
      frame #13: 0x0000000000b635a9 nodev8::internal::CompilationCache::PutEval(v8::internal::Handle<v8::internal::String>, v8::internal::Handle<v8::internal::SharedFunctionInfo>, v8::internal::Handle<v8::internal::Context>, v8::internal::Handle<v8::internal::SharedFunctionInfo>, v8::internal::Handle<v8::internal::FeedbackCell>, int) + 89 frame #14: 0x00003b61a755be1d frame #15: 0x00003b61a75118d5 frame #16: 0x00003b61a750ee75 frame #17: 0x00003b61a75092c1 frame #18: 0x0000000000e725d3 nodev8::internal::Parser::CloseTemplateLiteral(v8::internal::Parser::TemplateLiteral**, int, v8::internal::Expression
      ) + 307
      frame #19: 0x0000000000aff8e9 nodev8::internal::Builtin_Impl_ArrayPrototypeFill(v8::internal::BuiltinArguments, v8::internal::Isolate*) + 1705 frame #20: 0x0000000000affaa1 nodev8::internal::Builtin_Impl_Stats_ArrayPrototypeFill(int, unsigned long*, v8::internal::Isolate*) + 97
      frame #21: 0x00000000008abf39 nodenode::AsyncWrap::GetConstructorTemplate(node::Environment*) + 297 frame #22: 0x00000000008ddbd7 nodenode::AsyncHooks::AsyncHooks() + 1911
      frame #23: 0x00000000008a6569 nodenode::AsyncWrap::DestroyAsyncIdsCallback(node::Environment*) + 361 frame #24: 0x00000000008b8a7c nodenode::cares_wrap::(anonymous namespace)::ChannelWrap::New(v8::FunctionCallbackInfov8::Value const&) + 156
      frame #25: 0x0000000000a54e0e nodereport::PrintVersionInformation(report::JSONWriter*) + 11438 frame #26: 0x0000000000a5a5c8 nodevoid report::JSONWriter::json_keyvalue<char [5], char [10]>(char const (&) [5], char const (&) [10]) + 376
      frame #27: 0x0000000000a4a21b nodenode::crypto::ClientHelloParser::ParseHeader(unsigned char const*, unsigned long) + 219 frame #28: 0x00000000008e6f45 nodenapi_get_array_length + 357
      frame #29: 0x00000000008e5239 node`napi_get_property + 537
      frame #30: 0x00007ff48c0dab97

[QUESTION] How to log the res.body

By default, only responseTime, statusCode and headers are logged.

"res":{"statusCode":304,"headers":{...}},"responseTime":15

Is there a configuration to enable logging res.body?

[QUESTION] customize pino parameters

In some cases, we need to customized pino/pino-http default params. How to configure default options globally like this?

`
{
genReqId: generateLogId, //pino-http ID generation

prettyPrint: isDevMode ? { colorize: true } : undefined // dev env pino-pretty
}
`

[BUG] Doesn't work on Nest 6.7

What is the current behavior?
Nest framework logs are not in JSON format:
image

However, injecting PinoLogger into services and using that, those logs are in JSON just fine.

Please provide the steps to reproduce.
Simply install following readme instructions into the root module:

@Module({
  imports: [
    LoggerModule.forRoot(),
    UsersModule,
  ],
  controllers: [AppController],
})
export class AppModule {}

What is the expected behavior?
Nest framework logs should be in JSON.

Please mention other relevant information such as Node.js version and Operating System.
Node version v12.13.0, OS is Ubuntu latest LTR.

According to the Nest docs:
https://docs.nestjs.com/techniques/logger#logger

You can only replace the logger in NestFactory.create(...);, which happens in src/main.ts in my application.

[FEATURE REQUEST] Log function start and end automatically

Is your feature request related to a problem? Please describe.
Avoid writing logs on each function. Lets say I want to write function entry and exit log in 'INFO' level, so I can have a option like a decorator which I can mention on top of function something like @loggable, then the logs with function argument will be printed on function start and function end.

Describe the solution you'd like
It would avoid writing tedious log line on each function.

Describe alternatives you've considered
NA

Additional context
Might be there are packages existing for Java on the same lines.

[FEATURE REQUEST] allow string to be passed to `pinoHttp.stream` option

Is your feature request related to a problem? Please describe.
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

Allow user to pass only a string to pinoHttp options, instead of a DestinationString. Forcing them to import pino to do a (recommended) pino.destination(string)

Describe the solution you'd like
A clear and concise description of what you want to happen.
Allow to pass a string as destination to pinoHttp option stream and do in nestjs-pino the pino.destination(string) transformation.

Describe alternatives you've considered
A clear and concise description of any alternative solutions or features you've considered.
Did not see any other way to do so

Additional context
Add any other context or screenshots about the feature request here.
I didn't want to import pino as a main dependency since i'll be using nestjs-pino, this way we can used the pino dependency contained in nestjs-pino instead.

What are your thought about this ?

I can try to make a PR for this if needed :)

[BUG] Basic configuration with Usage as NestJS app logger doesn't work

What is the current behavior?

Basic configuration as described by Usage as NestJS app logger doesn't work.

Please provide the steps to reproduce.

On a NestJS 6.10.10 project, just :

import { Logger } from "nestjs-pino";

const app = await NestFactory.create(MyModule, { logger: false });
app.useLogger(app.get(Logger));

gives:

Error: Nest could not find Logger element (this provider does not exist in the current context)
    at ContainerScanner.getWrapperCollectionPairByHost (/myproject/node_modules/@nestjs/core/injector/container-scanner.js:34:19)
    at ContainerScanner.findInstanceByToken (/myproject/node_modules/@nestjs/core/injector/container-scanner.js:20:40)
    at ContainerScanner.find (/myproject/node_modules/@nestjs/core/injector/container-scanner.js:13:21)
    at NestApplication.find (/myproject/node_modules/@nestjs/core/nest-application-context.js:184:38)
    at NestApplication.get (/myproject/node_modules/@nestjs/core/nest-application-context.js:43:25)
    at /myproject/node_modules/@nestjs/core/nest-factory.js:112:40
    at Function.run (/myproject/node_modules/@nestjs/core/errors/exceptions-zone.js:8:13)
    at Proxy.<anonymous> (/myproject/node_modules/@nestjs/core/nest-factory.js:111:46)
    at bootstrap (/myproject/dist/src/main.js:9:23)
    at processTicksAndRejections (internal/process/task_queues.js:85:5)

What is the expected behavior?

Please mention other relevant information such as Node.js version and Operating System.

NodeJS: 12.9.1
NestJS: 6.10.10

Logo is missing

Okay, so i think this project can better communicate its value through some visuals.

[QUESTION] Does the configuration of pino-http also configure pino?

Hello,

I'm using the syntax shown in https://github.com/iamolegga/nestjs-pino#asynchronous-configuration

@Module({
  imports: [
    LoggerModule.forRootAsync({
      imports: [ConfigModule],
      inject: [ConfigService],
      useFactory: async (config: ConfigService) => {
        return {
          pinoHttp: {
            level: config.level,
            prettyPrint: true
          },
        };
      }
    })
  ],
  ...
})
class TestModule {}

I get this kind of logs:

{"level":40,"time":1612819694266,"pid":37211,"hostname":"...","context":"..Service","msg":"a message"}
[1612819713135] INFO  (my-app/37211 on truc): request completed
    res: {
      "statusCode": 201,
      "headers": {
        "x-powered-by": "Express",
        "access-control-allow-origin": "*",
        "content-type": "application/vnd.api+json; charset=utf-8",
        "content-length": "91",
        "etag": "W/\"5b-otKW0l0jfPtZ563iVaysTjm6m5s\""
      }
    }
    responseTime: 12
  ...

Some of them are pretty-printed, some others aren't.

I also tried to force pino configuration:

...
      useFactory: async (config: ConfigService) => {
        return {
          pinoHttp: {
            logger: pino({
              level: config.level,
              prettyPrint: true
            },
            level: config.level,
            prettyPrint: true
          },
      }
    })
  ],
  ...
})
class TestModule {}

But no change.

How to get the same configuration for all logs?

Thank you

[QUESTION] Extend PinoLogger class

Hi guys! I would like to extend the Pino logger to be able to inject my own business logic in some cases (for example logger.error).

So decided to build a logger module on top of nestjs-pino.

Here are my two files

logger.service.ts

import { Injectable } from '@nestjs/common';
import { PinoLogger } from 'nestjs-pino';

@Injectable()
export class LoggerService extends PinoLogger {
  error(message: any, trace?: string, context?: string, ...args: any[]) {
    // My business logic here
    super.error(message, trace);
  }
}

logger.module.ts

import { Global, Module } from '@nestjs/common';
import { LoggerService } from './logger.service';
import { LoggerModule as PinoModule } from 'nestjs-pino';

@Global()
@Module({
  imports: [PinoModule.forRoot()],
  providers: [LoggerService],
  exports: [LoggerService],
})
export class LoggerModule {}

I am importing the module in app.module.ts.
My issue is when I start the application, I got this error at module initialization.

Error: Nest can't resolve dependencies of the LoggerService (?). Please make sure that the argument pino-params at index [0] is available in the LoggerModule context.

Potential solutions:
- If pino-params is a provider, is it part of the current LoggerModule?
- If pino-params is exported from a separate @Module, is that module imported within LoggerModule?
  @Module({
    imports: [ /* the Module containing pino-params */ ]
  })

I cannot figured out why I have this message, I am well imported the PinoModule in the loggerModule.

Thanks for any help ๐Ÿ˜ธ

[FEATURE REQUEST] Provide context per class

Is your feature request related to a problem? Please describe.

I'm using globally imported pino logger module. Every time when I make a log line I would like to know from which class the log was created. Right now, I have to include the context manually. Like the following lines in the README.md:
https://github.com/iamolegga/nestjs-pino/blob/master/README.md#L56
https://github.com/iamolegga/nestjs-pino/blob/master/README.md#L72

Currently, we can set base context per configuration of logger module. That's too broad for my use case. Even if I migrate my logger module import from global to per module import, I'd prefer finer level of granularity in defining base context. (But not as fine as log line :) )

Describe the solution you'd like

I would like to write log lines using injected logger without manually providing class context on each log line. I'd like the context to be either set up once per class (injection) or somehow dynamically configured to use class name (or whatever else) per module configuration.

I'm probably off on these, but my superficial suggestions would be:

  • configure the module with an option to always fork a child logger for each class it's injected into OR
  • expose child functionality so we can fork (child) a logger manually. Then we could set it up with context in each class constructor (or wherever we deem useful)

[FEATURE REQUEST] use "name" instead of "context" for the context

Is your feature request related to a problem? Please describe.
I just migrated from another library I used to use name: {ModuleName} for the context.
The main reason I did choose this, is that the default key used by pino-pretty

I would like to change the context key to use name instead.

Describe the solution you'd like
I think it would be a good idea to have an extra option at the initialization to define the key used for the context.

Describe alternatives you've considered
I tried to implement it, but I didn't weel understood the typing of the options. So I don't know how to add the option.
My code is here : https://github.com/Nhacsam/nestjs-pino/tree/add-param-to-context-key

[QUESTION] How to use Pino for entire application with configuration options?

Hi!

First of all, thanks for this module, it is really appreciated.

I am trying to use Pino Logger throughout the application; perhaps I am wrong about it, but what I am doing is to add the following code to app.module.ts:

@Module({
    imports: [
        ConfigModule.forRoot(),
        LoggerModule.forRoot({
            pinoHttp: { prettyPrint: true, useLevelLabels: true }, // <--
        }),
        // ...
    ],
    // ...
})
export class AppModule {}

And, in main.ts:

import { NestFactory } from '@nestjs/core';
import { Logger } from 'nestjs-pino';

async function bootstrap() {
  // Create the application.
  const app = await NestFactory.create(AppModule, { logger: false });

  // Get Pino Logger instance.
  const logger = app.get(Logger);

  // Use Pino as the main logger!
  app.useLogger(logger);

  // Start the server!
  await app.listen(3030);
}

// Initialize application!
bootstrap();

The issue is that, if I import LoggerModule and call forRoot (or forRootAsync by injecting ConfigService etc), without any Pino options (prettyPrint or useLevelLabels) it works perfectly, however when adding even one option, it hangs the entire application without even booting!

  1. Is this the way to use the Logger throughout the Application?
  2. If it is, am I providing configuration options in a wrong format?

I would like to use Pino as the main logging system for the entire application, no exclusions.

I am using NestJS v7.

Again, thanks for this library! And thanks in advance for any commentary this might receive :)

[QUESTION] How to inject nestjs-pino logger into Module configuration?

I am new to NestJS and NodeJS. I am using nestjs-pino in my application.

In my AppModule class I am importing the LoggerModule. Then when I configure TypeOrmModule I want to log something with nestjs-pino. How can I inject the nestjs-pino logger into my module configuration?

@Module({
  imports: [
    LoggerModule.forRoot({
      pinoHttp: {
        autoLogging: false
      }
    }),
    TypeOrmModule.forRootAsync({
      useFactory: async () => {
        const host = process.env.DATABASE_HOST || "localhost";
        const port = Number(process.env.DATABASE_PORT) || 5432;
        const username = process.env.DATABASE_USER || "postgres";
        const password = process.env.DATABASE_PASSWORD || "mysecretpassword";
        const database = process.env.DATABASE_DATABASE || "postgres";
        // TODO use nestjs-pino here
        console.log(`Connecting to database ${database} on ${host}:${port} with user ${username}`);
        return {
          type: "postgres", host: host, port: port, username: username, password: password, database: database, synchronize: true
        };
      }
    })
  ],
  controllers: [AppController, HealthController],
  providers: [AppService]
})
export class AppModule {
}

[QUESTION] Performance and async_hooks

Thank you guys for your good job with this library.
Pino is a great logger, and nestjs-pino provides a very nice integration for NestJS.

However, I'm interested to know your point of view about performance question we can read about async_hooks which is still in experimental status, and with the main reason of performance impact.
In addition to this (or linked with this), async_hooks is not recommended for production deployment.

As you mentioned in nestjs-pino docs, REQUEST scope can have performance issues. It's true and I fully agree.
But async_hooks have also some performance impact too.

It will be very friendly if you could share your opinion on this topic.
Thank you very much.

[QUESTION] How to add userId for each authenticated request

Hello,

I am using your library in my project. Thanks for your work, it is really helpful!

We are using a Passport local strategy for authentication (https://docs.nestjs.com/security/authentication#implementing-passport-local). If the authentication is performed correctly, the user object will be added on the request object that it will be later passed to the controllers.

What I would like to do is to add the userId value to each request information that is bundled together with each log. It seems that the serializer methods are called before this auth layer is called and I did not find a way to do this in the documentation.

Do you have any advice on how to implement this?

Thank you!

[QUESTION] Is it possible to set a request Id manually?

In my case, we receive a specific Id per request, it goes through several systems and we use it to log and track the request cycle.

Is it possible to manually change the request Id? If so, what would be the best way to do this?

[QUESTION] "failed with status code 500" output instead of detailed error message

When I'm throwing an error from Nest application nestjs-pino always prints in the error message "failed with status code 500" even though I'm throwing an error with a detailed message any idea how to solve this?

this is how I setup nestjs-pino

    LoggerModule.forRoot({
      pinoHttp: {
        prettyPrint: { colorize: true, translateTime: true },
        serializers: {
          req: (req) => ({
            ...req,
            headers: undefined,
          }),
          res: (res) => ({
            ...res,
            headers: undefined,
          }),
        },
      },
    }),

and this is how I throw the error

import {InternalServerErrorException} from '@nestjs/common';
throw new InternalServerErrorException("This is my detailed error");

And nestjs-pino output

   res: {
      "statusCode": 500
    }
    err: {
      "type": "Error",
      "message": "failed with status code 500",
      "stack":
          Error: failed with status code 500
              at ServerResponse.onResFinished (/Users/shahaf/Source/muil/muil/node_modules/pino-http/logger.js:73:38)
              at ServerResponse.clsBind (/Users/shahaf/Source/muil/muil/node_modules/cls-hooked/context.js:172:17)
              at ServerResponse.emit (node:events:388:22)
              at ServerResponse.EventEmitter.emit (node:domain:532:15)
              at ServerResponse.emitted (/Users/shahaf/Source/muil/muil/node_modules/emitter-listener/listener.js:134:21)
              at onFinish (node:_http_outgoing:800:10)
              at callback (node:internal/streams/writable:557:21)
              at afterWrite (node:internal/streams/writable:503:5)
              at afterWriteTick (node:internal/streams/writable:490:10)
              at processTicksAndRejections (node:internal/process/task_queues:79:21)
    }
    responseTime: 94
    req: {
      "id": 1,
      "method": "POST",
      "url": "/api/test/test",
      "remoteAddress": "::1",
      "remotePort": 61221
    }

Log to FILE or DB

Hello!

How can I implement log to file or database?

I use global log as bellow:

async function bootstrap() {
const app = await NestFactory.create(AppModule, {
logger: false,
});
app.useLogger(app.get(Logger));
await app.listenAsync(process.env.PORT || 3000);
}

bootstrap().then();

[QUESTION] Fetch request ID

Im using below code to generate request ID:-

shared.module.ts

import {
  Module,
  HttpModule
} from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';
import { APP_FILTER } from '@nestjs/core';
import { LoggerModule } from 'nestjs-pino';
import * as config from 'config';

import { CorrelationIdGeneratorService } from './services/helpers/generators/correlation-id-generator.service';


@Module({
  imports: [
    MongooseModule.forFeature([{ name: 'Device', schema: DeviceSchema }]),
    MongooseModule.forFeature([{ name: 'File', schema: FileSchema }]),
    HttpModule,
    LoggerModule.forRootAsync({
      providers: [
        CorrelationIdGeneratorService,
      ],
      inject: [CorrelationIdGeneratorService],
      useFactory: (correlationIdGeneratorService: CorrelationIdGeneratorService) => {
        return {
          pinoHttp: {
            genReqId: (request) => {
              correlationIdGeneratorService.generateCorrelationId(request);
              console.log('Im here 1',correlationIdGeneratorService.getCorrelationId());
              return correlationIdGeneratorService.getCorrelationId();
            },
            level: config.get('log.LEVEL'),
            useLevelLabels: true,
            base: null,
            timestamp: () => {
              return `, "time":"${new Date().toISOString()}"`;
            },
          },
        };
      }
    })
  ],
  providers: [
    CorrelationIdGeneratorService,
  ],
  exports: [
    CorrelationIdGeneratorService,
  ]
})
export class SharedModule { }

Now the issue is, i need to fetch the correlationId in another module for which i have exported the CorrelationIdGeneratorService from shared.module.ts and imported in my consuming modules.

Now in the consuming module im getting correlationId as undefined.

It seems that the object of CorrelationIdGeneratorService passed in loggermodule is different from the object passed in my consuming module. Please help, how can i share the singleton instance of correlation id throughout my code.

Below is the code for CorrelationIdGeneratorService
correlation-id-generator.service.ts

import { Injectable } from '@nestjs/common';
import * as config from 'config';

import { UniqueIdGeneratorService } from './unique-id-generator.service';

@Injectable()
export class CorrelationIdGeneratorService {
    private correlationId: string;
    constructor(private readonly uniqueIdGeneratorService: UniqueIdGeneratorService) {}

    public generateCorrelationId(request: any) {
        this.correlationId = request?.headers?.[config.get('httpHeaders.CORRELATION_ID')] ||
        this.uniqueIdGeneratorService.generate(
            config.get('correlationId.VALID_CHARS'),
            config.get('correlationId.LENGTH')
        );
        console.log('Ammy 2', this.correlationId)
    }

    public getCorrelationId(): string {
        return this.correlationId;
    }
}

[QUESTION] How to change context of "automatic logs of every request/response"?

As discussed in the docs:

// Logs by app itself
{"level":30,"time":1570470154387,"pid":17383,"hostname":"my-host","context":"RoutesResolver","msg":"AppController {/}: true","v":1}
{"level":30,"time":1570470154391,"pid":17383,"hostname":"my-host","context":"RouterExplorer","msg":"Mapped {/, GET} route true","v":1}
{"level":30,"time":1570470154405,"pid":17383,"hostname":"my-host","context":"NestApplication","msg":"Nest application successfully started true","v":1}

// Logs by injected Logger and PinoLogger in Services/Controllers
// Every log has it's request data and unique `req.id` (per process)
{"level":30,"time":1570470161805,"pid":17383,"hostname":"my-host","req":{"id":1,"method":"GET","url":"/","headers":{...},"remoteAddress":"::1","remotePort":53957},"context":"AppController","msg":"getHello()","v":1}
{"level":30,"time":1570470161805,"pid":17383,"hostname":"my-host","req":{"id":1,"method":"GET","url":"/","headers":{...},"remoteAddress":"::1","remotePort":53957},"context":"MyService","msg":"getWorld([])","v":1}

// Automatic logs of every request/response
{"level":30,"time":1570470161819,"pid":17383,"hostname":"my-host","req":{"id":1,"method":"GET","url":"/","headers":{...},"remoteAddress":"::1","remotePort":53957},"res":{"statusCode":304,"headers":{...}},"responseTime":15,"msg":"request completed","v":1}

I'm talking about these last logs in the list, "automatic logs of every request/response". (The ones where "msg":"request completed"...)

I need to add a "context" to these logs, e.g. "Http", so that I can filter them out of my log aggregator.

How can I set "context":"Http" on these logs?

How can I ignore specific API routes from being logged?

Hi! Awesome module, thanks!

I have a question though. I've got a Nest.js application and here's my main.ts file:

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { Logger } from 'nestjs-pino/dist';

async function bootstrap() {
  process.env.NODE_ENV = process.env.NODE_ENV || 'DEV';
  const app = await NestFactory.create(AppModule, {logger: false});
  app.useLogger(app.get(Logger));
  await app.listen(process.env.PORT || 3000);
}
bootstrap();

After I set app.useLogger(...) I can see all the requests coming into the app in stdout. However I have a health check endpoint, which I'd like to prevent from being logged. How can I achieve it with this module?

Thanks in advance.

[QUESTION] How to log req.id only?

It's overloaded to log req object with every log. Is there a way to just print req.id only?
Of course, the pinoHttp.autoLogging should be turned on. the request completed log and error logs should contain req and req completely.
Thanks in advance.

[QUESTION] Logging ExecutionContext's data

Does this library support logging the user associated with the request?

My application uses a custom @nestjs/passport strategy to handle authentication:

class MyStrategy extends PassportStrategy(BasicStrategy, 'custom') {
  async validate(username: string, password: string): Promise<IUser> {...}
}

When I need to access the user in a guard, for example, I do the following:

class PermissionGuard implements CanActivate {
  canActivate(context: ExecutionContext) {
    const args = context.switchToHttp();

    const request = args.getRequest();
    const user = request.user as IUser;
    ...
  }
}

Is there a way to automatically add the user to the log context?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.