AngularJS: $log and Actual Line Number

Example shows use of $log, custom decorations and printing actual line numbers from where $log was called.

by abhishek bhatia

HTML

<div ng-app="ABApp">
    <div ng-controller="MyController">
    <h3>Please open your javascript console to view the logging output.</h3>
    <p>This example uses <a href="https://github.com/lwhiteley/AngularLogExtender/wiki/05.-Set-Component-Class-Name"> Angular Log Extender.</a>, which helps to control and decorate $log console output. It allows the users to customize the prefix for log messages. I have used that concept and added the line number to log prefix. The line number is obtained using a function and line number is of the line from where $log is actually called.
    </p>
    <p>
    Please note as the source for Angular Log Extender does not have a CDN location for its js file, I have used it locally. Thanks to Angular LogExtender team for this open source code. 
    </p>
    <p>
   Please read their wiki for extensive information on configuring this wonderful module. In the console ouput, you will see 4 tokens for each logged line.
    </p>
    <p>
      <ul>
        <li>1st is the line number of $log line.</li>
        <li>2nd is the Date time stamp of when the code was executed.</li>
        <li>3rd is the $log instance name, if used.</li>
        <li>4th is the actual message.</li>
        <li>The separators used are "::" and ">>".</li>
      </ul>
      Thanks to the following resources:
        <ul>
          <li><a href="http://solutionoptimist.com/2013/10/07/enhance-angularjs-logging-using-decorators/#comment-166287">$log Service and Decorators</a></li>
          <li><a href="https://github.com/lwhiteley/AngularLogExtender/">Angular Log Extender</a></li>
          <li><a href="http://stackoverflow.com/a/32539274/6385674"> Ploughing the Net's solution for getting the line number.</a></li>
        </ul>      
      </div>
    </div>

JavaScript

var app = angular.module('ABApp', ["log.ex.uo"]);

app.config(['logExProvider', function(logExProvider) {
    var enabledLogging=true, enableQuietly=false;
    logExProvider.enableLogging(enabledLogging, enableQuietly);
    logExProvider.restrictLogMethods(['error', 'warn', 'info', 'debug', 'log']);
    logExProvider.overrideLogMethodColors({log: 'color:#000000;', warn: 'color: #FF9900; background: #FFFFCC;',  debug: 'color: #990099;'});
    logExProvider.overrideLogPrefix(function (className) 
    {
        var $injector = angular.injector([ 'ng' ]);
        var $filter = $injector.get( '$filter' );
        var separator = " >> ";
        var format = "MMMM-dd-yyyy-h:mm:ssa";
        var now = $filter('date')(new Date(), format);
        var lineNumber = -1;
        var newErr = new Error();
        //Start - Calculate line number
        if (typeof newErr.stack !== 'undefined') {
					lineNumber = getLineNumber(newErr,1,2);
        }
        else {
                try {
                        throw newErr;
                }
                catch (e) {
                        if(!e.stack) {
                                lineLocation=-1;
                        }
                        else {
                        			  lineNumber = getLineNumber(newErr,2,3);
                        }
								}
        }
        //End - Calculate line number
        
        return "" + (lineNumber<=0 ? "" : lineNumber + "::") + now + (!angular.isString(className) ? "" : "::" + className) + separator;
    });
}]);

app.controller('MyController', function ($scope, $log) {
   $log.log("Hello Log");
   $log.info("Hello Info");
   $log.debug("Hello Debug");
   $log.warn("Hello Warn");
   $log.error("Hello Error");
});

app.run( function($rootScope, $location, $http, $log) {
   $log = $log.getInstance("RUN");
   $log.info("I am RUNning");
});

//Anonymous function
function getLineNumber(newErr, sliceIndex1, sliceIndex2)
{
	  var lineNumber = -1;
    var lineLocation;
    
    var...