In my previous post, we looked at how we can catch all errors in Angular with a global error handler. If you want to keep the errors you capture, you need to implement a reliable logging system. Today, I want to explain why logging is crucial and how you can add simple logging to your Angular applications with ngx logger package.

Why logging is important

As a developer, you are responsible for every line of code you write. If a bug surfaces in the application, you need to pinpoint the issue and provide a fix for it. Undoubtedly, this is easier said than done within a real-world project. In most cases, it can take hours (if not days) to reproduce the issue before you can even fix it. When implemented properly, logging can save your ass big time. Not only will logging save you hours of debugging in the long run but also give you confidence about your solutions.

Basic logging in JavaScript

Logging in vanilla JavaScript is pretty simple – just use the console.log function as shown below.

console.log('info log'); console.warn('warning log');
Code language: JavaScript (javascript)

Although very simple, the console logging can limit what you can do with your logs. Think about it, you are going to be adding log statements all over the project.

What if…

  • you want to disable logging temporarily?
  • enable logging only on production?
  • only log errors & ignore other levels?
  • send logs to server?

It is possible to implement these requirements by hand and provide it as a service in your Angular application. However, infrastructure concerns like logging are essential in any application and you shouldn’t really spend your time building and maintaining these features. Unless there are strict company policies, you should make use of libraries and stop re-inventing the wheel.

Using ngx-logger in Angular

ngx-logger is a very simple logging library for Angular applications. It offers the following features:

  • Pretty printing to the console
  • Enable logging based on the level specified
  • Control log level based on the current environment
  • Send log messages to server via HTTP for centralised logging
  • Indicates log location and line number

Getting up and running with ngx-logger is easy, just create a new Angular app and pull the package from npm:

npm install ngx-logger
Code language: Bash (bash)

Import the library in the root module i.e. app.module.ts:

import { LoggerModule, NgxLoggerLevel } from 'ngx-logger';
Code language: TypeScript (typescript)

The last part is to list the imported module in your application module, passing in a config to intialise the logger:

@NgModule({ imports: [ BrowserModule, FormsModule, LoggerModule.forRoot({ serverLoggingUrl: '/api/logs', level: NgxLoggerLevel.TRACE, serverLogLevel: NgxLoggerLevel.ERROR, disableConsoleLogging: false }) ], declarations: [AppComponent], bootstrap: [AppComponent] }) export class AppModule { }
Code language: TypeScript (typescript)

A few things to note about the configuration object:

  • level defines the minimum log level in the browser. Available levels are: TRACE, DEBUG, INFO, LOG, WARN, ERROR, FATAL and OFF. These values come from NgxLoggerLevelclass.
  • serverLoggingUrl is where you give the full path to your api end-point for logging to server. This is optional, if you don’t need logs to be sen’t to server, delete this line.
  • serverLogLevel defines the minimum log level for server-side logging. =
  • disableConsoleLogging is a flag which helps you to turn console logging completely off.

With the above configuration in place, we should be able to log anywhere in the application. For example:

export class AppComponent { constructor(private logger: NGXLogger) { this.logger.debug("Debug message");"Info message"); this.logger.log("Default log message"); this.logger.warn("Warning message"); this.logger.error("Error message"); } }
Code language: TypeScript (typescript)

Here we are injecting the NGXLogger as a dependency to the AppComponent class, giving us access to the available logging options.

When you run the application, you will see the log messages in the browser console. You will notice that there are errors relating to the server-side logging. This is because we defined that error logs should be sent to the server at /api/logs end-point. Since this URL does not exist, we get an error message.

Console Output from ngx-logger

Environment specific logging in Angular

A common requirement in a real-wold application is that you only want to log errors in production environment while keeping all log levels enabled in development environment.

Changing the configuration every time you deploy to a different environment can be time consuming and annoying thing to do. In particular, recent adaptation of DevOps pipelines often allow organisations to frequently deploy apps. Let’s look at how we can link the log configuration to the Angular environment.

We start by importing the environment dependency in app.component.ts. This dependency will allow us to read the configuration specified in Angular environment files. We then replace the logging configuration to use environment-specific variables.

import { environment } from 'src/environments/environment'; @NgModule({ imports: [ BrowserModule, FormsModule, LoggerModule.forRoot({ serverLoggingUrl: `${environment.apiUrl}api/logs`, level:environment.logLevel, serverLogLevel: environment.serverLogLevel, disableConsoleLogging: false }) ], declarations: [AppComponent], bootstrap: [AppComponent] }) export class AppModule { }
Code language: TypeScript (typescript)

There are two environments in a cli-generated Angular application: development and production. These environments are defined in the Angular.json file in the src folder of the project. Essentially, the development environment uses the environment.ts and the production environment uses the file under src\environments folder. Here, the idea is that you define the same environment variable in each file, provide different values and the corresponding value will be used where you take in the environment dependency. Let’s update the development environment:

import { NgxLoggerLevel } from 'ngx-logger'; export const environment = { production: false, apiUrl: 'http://localhost:68552/', // Replace with local API logLevel: NgxLoggerLevel.WARN, serverLogLevel: NgxLoggerLevel.OFF };
Code language: TypeScript (typescript)

When you run the application with ng serve, the development environment configuration will be used: only the warn logs & above will be logged on the browser. The server-side logging is turned off as we just want to see the errors in the console during development. Let’s also update the production environment (

import { NgxLoggerLevel } from 'ngx-logger'; export const environment = { production: true, apiUrl: '', // Replace with remote API logLevel: NgxLoggerLevel.OFF, serverLogLevel: NgxLoggerLevel.ERROR };
Code language: TypeScript (typescript)

Our production configuration states that there will be no browser logging and only errors will be logged to the server at the specified API URL.The command used to run in production mode is ng serve --configuration=production.

So what do you think? I would be interested to learn about how you perform logging in your apps, let me know in the comments.

Umut Esen

Umut is a certified Microsoft certified developer and has an MSc in Computer Science. He is currently working as a senior software developer in Edinburgh, UK. He is the primary author and the founder of onthecode.

This Post Has 14 Comments

  1. gaurav

    our api is of get or post ? my api is not getting called , can you help

    1. Umut Esen

      Thanks for your comment, the API end-point should be POST. Here is a sample implementation in C#:

      public IActionResult Post([FromBody] LogDto dto)
      var msg = $"MESSAGE: {dto.Message} - " +
      $"FILE: {dto.FileName} - " +
      $"LEVEL: {dto.Level} - " +
      $"LINENUMBER: {dto.LineNumber} - " +
      $"TIMESTAMP: {dto.Timestamp:F}" +
      $"USER: {User.Identity.Name}";


      return Ok();

  2. gaurav

    how can we pass the payload from the angular, can you send the code snippet , thanks for your response

    1. Umut Esen

      Nope, it is still going strong! I have however started using Azure Application insights for automatic logging!

  3. amit

    I tried with latest `ngx-logger` npm and somehow I’m not getting an error that
    POST http://localhost:4200/api/logs/ not found.

    Is this dependent on specific version?

  4. Asad Naeem

    After following your example line by line. I found these errors in the browser. I am using Angular 9.
    core.js:6185 ERROR NullInjectorError: R3InjectorError(AppModule)[NGXLogger -> NGXMapperService -> HttpBackend -> HttpBackend -> HttpBackend]:
    NullInjectorError: No provider for HttpBackend!

    1. Umut Esen

      NGXLogger requires an Http client to post logs to APIs so you would need to provide that dependency in your root/core module.

      1. Neeraj

        Any Update, I am also facing same issue, i want to call my interceptor but due to HttpBackend its skipping my interceptor.

    2. Elijah

      I’m learning this, what was the exact solution to getting past this NullInjectorError?

  5. Like!! I blog quite often and I genuinely thank you for your information. The article has truly peaked my interest.

  6. Taufique

    Hello Umut Esen,
    I have followed line by line everything is working for me, but my concern is that I want to send these logs to the node server please help me if possible.

  7. Terry J. Davis

    Just pulled down the app. I’m running Angular 9.

    this.logger.debug does not write to the console. I have to use this.logger.warn instead.

    export const environment = {
    production: false,
    name: ‘dev’,
    logLevel: NgxLoggerLevel.DEBUG,
    serverLogLevel: NgxLoggerLevel.OFF

    level: environment.logLevel,
    serverLogLevel: environment.serverLogLevel,
    disableConsoleLogging: false

  8. Mikec711

    So, config question (may be more angular scoped but) … a customer calls and i want to change the log level for that customer. Can I have the customer export (unix) into their own environment and pick it up from there? ie: i want customer A to go to debug but want the rest of the world to stay at warning. Thanks

Leave a Reply