DEV Community

Cover image for Understanding the NestJS Logger: Format Specifiers and Logging Best Practices
Brandon Wie
Brandon Wie

Posted on

Understanding the NestJS Logger: Format Specifiers and Logging Best Practices

NestJS is a powerful framework for building scalable server-side applications, and its built-in logging module is an essential tool for monitoring and debugging. While working with the @nestjs/common logger, you might wonder about its capabilities, particularly whether it supports format specifiers like %s and %d in the same way console.log does.

In this blog post, we'll explore the @nestjs/common logger, its support for format specifiers, and some best practices for effective logging in your NestJS applications.

The Basics of NestJS Logger

NestJS provides a built-in logging module that comes with various methods like log, error, warn, debug, and verbose. These methods allow developers to log messages at different levels of severity. Here’s a simple example of using the NestJS logger:

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

class AppService {
  private readonly logger = new Logger(AppService.name);

  getHello(): string {
    this.logger.log('Hello World!');
    return 'Hello World!';
  }
}
Enter fullscreen mode Exit fullscreen mode

Support for Format Specifiers

Through practical testing, it has been confirmed that the @nestjs/common logger supports format specifiers such as %s, %d, and more. This feature can be extremely useful for creating formatted log messages. Here are some examples:

this.logger.warn('%s is deprecated', 'activity'); // Logs: activity is deprecated
this.logger.error('%d errors occurred', 5); // Logs: 5 errors occurred
Enter fullscreen mode Exit fullscreen mode

Limitations and Best Practices

While the NestJS logger supports format specifiers, it does not support logging a string followed by an object as parameters directly. Here are some examples to illustrate what is supported and what isn't:

Supported:

this.logger.error('%s', 'test'); // Logs: test
this.logger.error({ test: 'test' }); // Logs: { test: 'test' }
this.logger.error(`test: ${{ test: 'test' }}`); // Logs: test: [object Object]
Enter fullscreen mode Exit fullscreen mode

Not Supported:

this.logger.error('test', { test: 'tester' }); // This will not log the object properly
Enter fullscreen mode Exit fullscreen mode

Recommendations for Effective Logging

  1. Use Template Literals for Complex Logs: When you need to include variables or objects in your logs, use template literals for clarity and readability.

    const user = { id: 1, name: 'John' };
    this.logger.log(`User logged in: ${JSON.stringify(user)}`);
    
  2. Log Levels: Use appropriate log levels (log, warn, error, debug, verbose) to categorize your logs based on their importance.

  3. Structured Logging: For more complex logging needs, consider using structured logging with JSON. This can be especially useful for logging services like Elasticsearch, Logstash, and Kibana (ELK stack).

  4. External Libraries: For advanced logging features, consider integrating with libraries like nestjs-pino which supports JSON logging and has better performance characteristics.

    import { LoggerModule } from 'nestjs-pino';
    
    @Module({
      imports: [
        LoggerModule.forRoot(),
      ],
      controllers: [AppController],
      providers: [AppService],
    })
    export class AppModule {}
    

Conclusion

The @nestjs/common logger is a robust tool that supports format specifiers, making it easier to format your log messages. However, it has some limitations when it comes to logging objects directly with string messages. By understanding these capabilities and adopting best practices, you can enhance your logging strategy and make your NestJS applications more maintainable and easier to debug.


References

Top comments (0)