nest-winston
nest-winston copied to clipboard
how to set the context of the current service?
Hey, I use something like this example, how to set the context of the current service? It is now: (from this issue)
constructor(
private readonly userService: UsersService,
@Inject(WINSTON_MODULE_NEST_PROVIDER)
private readonly logger: LoggerService,
) {
(logger as WinstonLogger).setContext(UsersController.name);
}
It works fine, but it doesn't look like the final answer.
@Inject(WINSTON_MODULE_NEST_PROVIDER)
private readonly logger: Logger,
or
@Inject(WINSTON_MODULE_NEST_PROVIDER)
private readonly logger: WinstonLogger,
The same works fine, why can't it be used like this? What expert advice do you have for me.
I agree this is a bit confusing and me and my fellow engineers have been tripping over this too.
For what it's worth, here's what we do:
First, register WinstonLogger as the Nest application logger:
import { WinstonModule } from 'nest-winston';
async function bootstrap() {
const app = await NestFactory.create(AppModule, {
logger: WinstonModule.createLogger({
// options (same as WinstonModule.forRoot() options)
})
});
await app.listen(3000);
}
bootstrap();
Then, in the class, manually create an instance of NestJS Logger
(not WinstonLogger
):
private readonly logger = new Logger(UsersController.name);
constructor(
private readonly userService: UsersService
) {}
This works because Logger
proxies all of its logging requests to the application logger, in this case WinstonLogger
.
The upside of this is it is clean, easy to write, and very readable.
The downside here is the logger isn't being dependency injected, which is a bit of an ick if you're a DI purist like me. However, practically speaking, in my opinion, this isn't as much of an issue because unit testing your logging is overkill most of the time. Even if you do want to unit test your logs, you can use the Nest hook Logger.overrideLogger()
to replace the logger with a mock logger if necessary.
Would be interested if others think this is the right approach.