Last Updated: February 25, 2016
·
32.5K
· otupman

Logging in Angular apps ... and how to filter those log messages

The classic way to log in JavaScript is through the delightful console.log call; it's pretty brute-force - it logs. That's it. No filtering log messages, no log levels (i.e. warn, error, etc.).

What's nice is that Angular provides us a handy service that wraps console.log and it's called, funnily enough, $log.

$log is a simple service that, when included in your code, provides four methods:

  1. error: for, well, errors - also gives you a stack trace
  2. info: for informational messages
  3. log: uh, log messages?
  4. warn: warning messages, duh

2 of those are pretty obvious as to their function: warn & error. How you use info and log are really up to you; to be, they're pretty similar. I typically use log to mean debug. Info would be for generalised informational messages (such as a service saying "Hey, I'm using the staging server")

Obtaining the Angular $log is pretty simple, just declare it as a dependency in your particular 'thing', so for a controller:

function SomeCtrl($scope, $log) {
    $log.info('SomeCtrl - starting up, yeah!');
}

Filtering those $log messages

Saying all of that, getting a lot of log in the console can be a little like receiving a ton of spam. Plus, maybe you don't want to log everything. Maybe you want to send errors to a remote server.

So, Angular provides us with the concept of 'decorators' and these allow us to wrap the original $log service and provide our own implementations (or wrap the original ones).

The following example (borrowed from this Google Group thread) is silent when it comes to log messages (because, for me, they're debug messages) and decides to call alert() for any error messages.

myApp.config(function($provide) {
  $provide.decorator('$log', function($delegate, $sniffer) {
        var _log = $delegate.log; //Saving the original behavior

        $delegate.log = function(message) { };
        $delegate.error = function(message) {
            alert(msg);
        }

        return $delegate;
    });
})

A little more info on $log can be found on the Angular documentation page here.

6 Responses
Add your response

it would be nice if the $log service could be configured on an module / entity (controller, directive, factory, ...) level too, as all Java logging frameworks support

over 1 year ago ·

One of the things I love about Angular.js is how I keep learning formal computer science terms using it. 'Decorators' - nice.

over 1 year ago ·

@andywoodly - if I understand you correctly, you can completely override the behaviour by completely overriding the service returned when the $log is injected. This can be done by simply defining your own service called '$log'. As simple as that. The catch however is that Angular itself uses the $log service internally to emit logs. so ensure that whatever you do, you maintain the default interface, i.e., provide the 4 default methods $log.log(), $log.info(), $log.warn(), $log.error(). Even if as empty stubs.

bPratik.in

over 1 year ago ·

Actually the console API has .log, .warn, .error and other methods, not just .log.

In fact it has .assert, .count and other useful methods. See https://developer.chrome.com/devtools/docs/console-api

over 1 year ago ·

Angular, (as of 1.1?) has $log.debug as well. So once again, I'm at a loss as to where to use .log() vs .info()

over 1 year ago ·