Logging in AngularJS with JSNLog

Introduction
Gỡ rối lỗi client-side là không dễ dàng khi bạn không biết những gì một người dùng đang làm và nhìn thấy.AngularJS xử lý các lỗi này rất tốt; nó sẽ bắt lỗi client-side và hiển thị chúng trong giao diện điều khiển trình duyệt cho phép ứng dụng của bạn để tiếp tục.Vấn đề là ngay cả một người sử dụng sẽ không biết rằng một lỗi đã xảy ra và các chi tiết của lỗi trừ khi người sử dụng biết những gì một giao diện điều khiển trình duyệt và làm thế nào để mở nó.
Để giúp cho việc hiện thị lỗi dễ dàng với người dùn,AngularJS đã sử dụng thư viện JSNLog.Bạn có thể tìm thấy tại liệu tham khảo cho JSNlog http://js.jsnlog.com/Documentation/JSNLogJs.

Cách sự dụng JSNLog
Trước tiên, tải jsnlog.min.js và thêm nó vào dự án của bạn.Sau đó khai báo các listener vào trong AngularJS:

(function () {
    'use strict'

    // Create new module logToServer with new $log service
    angular.module('logToServer', [])
        // Make AngularJS do JavaScript logging through JSNLog so we can log to the server by replacing the $log service
        .service('$log', function () {
            this.log = function (msg) {
                JL('Angular').trace(msg);
            }
            this.debug = function (msg) {
                JL('Angular').debug(msg);
            }
            this.info = function (msg) {
                JL('Angular').info(msg);
            }
            this.warn = function (msg) {
                JL('Angular').warn(msg);
            }
            this.error = function (msg) {
                JL('Angular').error(msg);
            }
        })
        // Replace the factory that creates the standard $exceptionHandler service
        .factory('$exceptionHandler', function () {
            return function (exception, cause) {
                JL('Angular').fatalException(cause, exception);
                throw exception;
            };
        })
        // Add a factory to create the interceptor to the logToServer module
        .factory('logToServerInterceptor', ['$q', function ($q) {
            var myInterceptor = {
                'request': function (config) {
                    config.msBeforeAjaxCall = new Date().getTime();
                    return config;
                },
                'response': function (response) {
                    if (response.config.warningAfter) {
                        var msAfterAjaxCall = new Date().getTime();
                        var timeTakenInMs = msAfterAjaxCall - response.config.msBeforeAjaxCall;
                        if (timeTakenInMs > response.config.warningAfter) {
                            JL('Angular.Ajax').warn({
                                timeTakenInMs: timeTakenInMs,
                                config: response.config,
                                data: response.data
                            });
                        }
                    }
                    return response;
                },
                'responseError': function (rejection) {
                    var errorMessage = "timeout";
                    if (rejection.status != 0) {
                        errorMessage = rejection.data.ExceptionMessage;
                    }
                    JL('Angular.Ajax').fatalException({
                        errorMessage: errorMessage,
                        status: rejection.status,
                        config: rejection.config
                    }, rejection.data);
                    return $q.reject(rejection);
                }
            };
            return myInterceptor;
        }]);

})();

angular.module('ArticlesModule', ['logToServer'])
    // Register the controller
    .controller('ArticlesController', ['$scope', '$http', ArticlesController])
    // Add the new interceptor to the interceptor pipeline of the main module
    .config(['$httpProvider', function ($httpProvider) {
        $httpProvider.interceptors.push('logToServerInterceptor');
    }]);

Cuối cùng là thiết lập url để gửi log .Trong thực tế, có thể sử dụng một webservices RESTful
JL.setOptions({
    'defaultAjaxUrl': 'LogDetails.aspx'
})

Trong các ứng dụng JavaScript việc thực hiện AJAX được sử dụng rất nhiều và điều quan trọng là ghi lại lỗi AJAX và thời lượng của nó. ví dụ:

.factory('logToServerInterceptor', ['$q', function ($q) {
    var myInterceptor = {
        // The request function is called before the AJAX request is sent
        'request': function (config) {
            config.msBeforeAjaxCall = new Date().getTime();
            return config;
        },
        // The response function is called after receiving a good response from the server
        'response': function (response) {
            var msAfterAjaxCall = new Date().getTime();
            var timeTakenInMs = msAfterAjaxCall - response.config.msBeforeAjaxCall;
            JL('Angular.Ajax').info({
                url: response.config.url,
                timeTakenInMs: timeTakenInMs
            });
            return response;
        },
        // The responseError function is called when an error response was received, or when a timeout happened.
        'responseError': function (rejection) {
            var errorMessage = "unknown";
            JL('Angular.Ajax').fatalException({
                status: rejection.status,
                url: rejection.config.url,
                errorMessage: rejection.data.error
            });
            return $q.reject(rejection);
        }
    };
    return myInterceptor;
}]);


nếu AJAX gọi successful, logged sẽ đc ghi như sau:

{"r":"index.htm","lg":[{"l":3000,"m":"{"url":"https://api.codeproject.com/v1/Articles?page=1","timeTakenInMs":606}","n":"Angular.Ajax","t":1421543626142}]}

và nếu AJAX failed:

{"r":"index.htm","lg":[{"l":6000,"m":"{"status":400,"url":"https://api.codeproject.com/token","errorMessage":"invalid_client"}","n":"Angular.Ajax","t":1421543588139}]}