JSNLog integrate to AngularJS

  • 286
  • 0
  • Log
  • 2016-05-18

基於上一篇提到的在前端紀錄 log 會有個問題

如果拋出錯的程式碼沒有用 try catch 包起來就無法紀錄 log

AngularJS 提供了 $exceptionHandler 這個好用的東西

在 「Angular 世界」中可以攔截到任何 uncaught exception

官方提供的 Sample Code 和 Documentation 其實非常清楚

連模組都幫你寫好了, 下載回來再把模組依賴進去就可以使用了

根本懶人包, 感覺底下就有人會回 「你媽知道你在這邊發廢文嗎 ?」

如果你只求安裝施工及如何使用的話其實看到這裡就不用繼續往下看

官方提供的 logToServer.js 的代碼是直接覆寫掉 $log 跟 $exceptionHandler

可以用 decorator 方法去攔截並擴充

這種修飾子的做法我覺得非常棒, 可以在不影響原有的功能下去擴充功能

改寫 $log 跟 $exceptionHandler 的部分如下 :

logToServerProvide.$inject = ['$provide'];
logDecorator.$inject = ['$delegate'];
exceptionDecorator.$inject = ['$delegate'];

function logToServerProvide($provide) {
   $provide.decorator('$log', logDecorator);
   $provide.decorator('$exceptionHandler', exceptionDecorator);
}

function logDecorator($delegate) {
   var origLog = $delegate.log;
   var origInfo = $delegate.info;
   var origDebug = $delegate.debug;
   var origWarn = $delegate.warn;
   var origError = $delegate.error;
   
   $delegate.log = function (msg) {
      JL().trace(msg);
      origLog.call(null, msg)
   };

   $delegate.info = function (msg) {
      JL().info(msg);
      origInfo.call(null, msg)
   };

   $delegate.debug = function (msg) {
      JL().debug(msg);
      origDebug.call(null, msg)
   };

   $delegate.warn = function (msg) {
      JL().warn(msg);
      origWarn.call(null, msg)
   };

   $delegate.error = function (msg) {
      JL().error(msg);
      origError.call(null, msg)
   };

   return $delegate;
}

function exceptionDecorator($delegate) {
   return function (exception, cause) {
      $delegate(exception, cause);
      JL().fatalException(cause, exception);
   };
}

angular.module('logToServer', [])
   .config(logToServerProvide)

至於 Interceptor 的部分跟 AOP 概念一致

並不會影響原本的流程只是多掛上一個攔截器去處理 log

也是一個非常漂亮的設計跟寫法 

範例一樣是接續之前放在 GitHub 上的 JSNLogWithNet 

參考文章 :

後記 :

不知道有沒有人遇到跟我一樣的問題 ?

預設 JL().trace() Method 是不會打到後端

就算改了 ajaxAppender level 也無法打去後端

angular.module('logToServer', [])
.service('$log', function () {
    this.log = function (msg) {
        JL('Angular').trace(msg); // not send to back-end
    }

    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);
    }
})