Angular Debugging Made Simple: Building a Custom Logging Service
Tags: angular, typescript, javascript, productivity
Published: 2023-04-25 10:43:19

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

```js
// 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');
  }
}
```

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

![Logs from Simple Logger](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7sqeo9xs71fs2m35ycfs.png)

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.

```js
// 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');
  }
}
```

And the result …

![Logs from Custom Logger](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gsg368vkv1c5huowwbbu.png)

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,

```js
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[]) => {};
      }
  }
}
```

_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](https://stackblitz.com/edit/angular-cvau7r?file=src%2Fmy-preferred-logging.service.ts)

Here is the [Source code(stackblitz)](https://stackblitz.com/edit/angular-cvau7r) containing the example shown above.

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

---

ArunKumar Nadikattu
 - https://www.linkedin.com/in/aru-ku
 - http://twitter.com/0xAruKu