Writing AngularJS logs to Server
Many a time there is a need to write front-end error to the back-end. Especially with frameworks like angularJS where the thick-client paradigm is in practice, logging to the server has its benefits. Here to accomplish this task, we use the built in $log service provided by angular to get the job done. Here we use the decorator design pattern to leverage the existing functionality.
Advantages of this approach is we leverage the already existing features:
- With the $logProvider we can enable/disable debug level messages (just like in our logback or log4j)
https://docs.angularjs.org/api/ng/provider/$logProvider - Any uncaught exception in angular expressions is delegated to $exceptionHandler service. The default implementation simply delegates to $log.error which logs it into the browser console.
https://docs.angularjs.org/api/ng/service/$exceptionHandler
Also there is a configuration option to:
- set the default log level.
- hide the console logs.
Log Level | log | debug | info | warn | error |
log | Y | Y | Y | Y | Y |
debug | N | Y | Y | Y | Y |
info | N | N | Y | Y | Y |
warn | N | N | N | Y | Y |
error | N | N | N | N | Y |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 | <!DOCTYPE html> <html lang="en" ng-app="myApp"> <head> <meta charset="UTF-8"> <title>AngularJS log handling, sending to server Example</title> <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script> <script type="text/javascript"> var app = angular.module('myApp', []); app.config(function ($provide,serverLogServiceProvider) { //setting the loglevel to error, hence only error logs are written to server serverLogServiceProvider.setLogLevel('error'); //optionally we can hide the logs on the console serverLogServiceProvider.hideConsoleLogs(true); $provide.decorator('$log', ['$delegate', 'serverLogService','$window', function ($delegate, serverLogService,$window) { //having a method on window so that we can force show console //logs even after the initial setting was to not show the console logs $window.forceShowConsoleLogs = function(){ serverLogService.forceShowConsoleLogs(); } //saving the original methods into variables var log = $delegate.log; var info = $delegate.info; var warn = $delegate.warn; var error = $delegate.error; var debug = $delegate.debug; function customLog(level, message,callback) { serverLogService.log(level, message.stack ? message.stack : message,callback); } //decorating the original method with our new functionality $delegate.log = function (message) { customLog('log', message,log); }; //decorating the original method with our new functionality $delegate.warn = function (message) { customLog('warn', message,warn); }; //decorating the original method with our new functionality $delegate.error = function (message) { customLog('error', message,error); }; //decorating the original method with our new functionality $delegate.debug = function (message) { customLog('debug', message,debug); }; //decorating the original method with our new functionality $delegate.info= function (message) { customLog('info', message,info); }; return $delegate; }]); }); app.provider('serverLogService', function () { this.loglevel = 'log'; this.hideLogs = false; this.$get = function () { var configLevel = this.loglevel; var hideLogs = this.hideLogs; return { log: function (logLevel, message,callback) { var logLevelArr = ['log', 'debug', 'info', 'warn', 'error']; if (logLevelArr.indexOf(configLevel) <= logLevelArr.indexOf(logLevel)) { //this is where a RESTful server log endpoint should go alert(logLevel + ':' + message); if(!hideLogs){ callback(message); } } }, forceShowConsoleLogs:function(){ hideLogs=false; } } }; this.setLogLevel = function (value) { this.loglevel = value; } this.hideConsoleLogs = function (value) { this.hideLogs = value; }; }); app.controller('myCtrl', function ($log) { var vm = this; vm.name='rushi'; vm.greet = function () { vm.msg = 'rushi'; $log.log('log message'); $log.debug('debug message'); $log.info('info message'); $log.warn('warn message'); $log.error('error message'); throw Error('gone wrong in greet'); } }); </script> </head> <body ng-controller="myCtrl as ctrl"> <input type="text" ng-model="ctrl.name" /> <input type="button" value="Greet" ng-click="ctrl.greet()" /> <br/>Click the Greet button to trigger all logs:{{ctrl.msg}} </body> </html> |
“Keep learning.”
-Rushi
-Rushi
anuragupadhyay
Hi Rushi,
when i try to call server from line where mention “//this is where a RESTful server log endpoint should go” $http is not define
what are the ways to inject $http, please provide complete example 🙂