DEV Community

Cover image for Angular Debugging Made Simple: Building a Custom Logging Service
ArunKumar Nadikattu
ArunKumar Nadikattu

Posted on

Angular Debugging Made Simple: Building a Custom Logging Service

Are you still using console.log for debugging your Angular applications? Do you want to create a custom logging service that suits your application’s specific needs? If so, this guide is for you.

Why use a custom logging service?

Though console.log and other console methods are useful for application debugging, they have their own limitations. They are not fully flexible and not very idle to disable all logs in one go in production. So, a custom logging service can be helpful in providing more detailed information such as user actions and the state of application. Moreover, we can customize the service to log only specific information, especially in production.

First let’s see a simple logging service

// Simple Logging Service
export class SimpleLoggingService {
  log(...data: any[]) {
    console.log(...data);
  }
}

// Usage
export class SimpleLoggingComponent implements OnInit, AfterViewInit {
  private $simpleLogger = inject(SimpleLoggingService);

  constructor() {}

  ngOnInit() {
    this.$simpleLogger.log('SimpleLoggingComponent - initialized');
  }

  ngAfterViewInit() {
    this.$simpleLogger.log('SimpleLoggingComponent - view initialized');
  }
}
Enter fullscreen mode Exit fullscreen mode

This works fine. but what about the line of code which logged.

Logs from Simple Logger

Even though the log is called in component, the console shows the log with line number of services’ console.log. What is the solution then?

Let’s try the geeky way.

Bing the console.log with itself and call it as a function in the component. Sounds geeky? Check the below snippet.

// Custom Logging Service
export class CustomLoggingService {
 /**
  * Here we bind console.log with itself and return the binded method
  */
  log = console.log.bind(console.log);
}

// Usage
export class CustomLoggingComponent implements OnInit, AfterViewInit {
  private $logger = inject(CustomLoggingService)

  ngOnInit() {
    this.$logger.log('CustomLoggingComponent - initialized');
  }

  ngAfterViewInit() {
    this.$logger.log('CustomLoggingComponent - view initialized');
  }
}
Enter fullscreen mode Exit fullscreen mode

And the result …

Logs from Custom Logger

DevTools' Console logs exact file and line number where the log is called.

Now let’s enhance the logging service.

We can further extend the service with any other console method we wish to have in our application. for example,

export const SHOULD_DISABLE_LOGGER = 
    new InjectionToken<Boolean>('SHOULD_DISABLE_LOGGER');

export class CustomLoggingService {
  log = console.log.bind(console.log);
  error = console.error.bind(console.error);
  warn = console.warn.bind(console.warn);
  debug = console.debug.bind(console. Debug);

  constructor(
    @Inject(SHOULD_DISABLE_LOGGER) shouldDisableLogger: boolean
  ) {
      if (shouldDisableLogger) {
        this.debug = (...data: any[]) => {};
      }
  }
}
Enter fullscreen mode Exit fullscreen mode

On a personal note, I prefer to use console.debug method for general logging. This requires you to enable verbose logging in DevTools console to see the debug logs. And followed by using an injectable token to disable debug logs in production.

You can see my Preferred Custom Service here

Here is the Source code(stackblitz) containing the example shown above.

That’s it — have fun and happy debugging ;)


ArunKumar Nadikattu

Top comments (0)