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:

Also there is a configuration option to:

  1. set the default log level.
  2. hide the console logs.
Log
Level
logdebuginfowarnerror
logYYYYY
debugNYYYY
infoNNYYY
warnNNNYY
errorNNNNY

View it in Plunker

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
  1. 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 🙂

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes:

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>