loglevel-metamask

pimterry/loglevel

https://github.com/pimterry/loglevelhtml

 

Minimal lightweight simple logging for JavaScript. loglevel replaces console.log() and friends with level-based logging and filtering, with none of console's downsides.node

loglevel是JavaScript的最小輕量級日誌記錄,它沒有控制檯的缺點,替代了console.log()而且對於基於級別的日誌和過濾是十分友好的git

This is a barebones reliable everyday logging library. It does not do fancy things, it does not let you reconfigure appenders or add complex log filtering rules or boil tea (more's the pity), but it does have the all core functionality that you actually use:github

這是一個可靠的日誌庫。它不作花哨的事情,不容許從新配置輸出源,不容許添加複雜的日誌過濾規則,但它確實具備你實際使用的全部核心功能npm

Features

Simple

  • Log things at a given level (trace/debug/info/warn/error) to the console object (as seen in all modern browsers & node.js)將給定級別的內容(跟蹤/調試/信息/警告/錯誤)記錄到控制檯對象
  • Filter logging by level (all the above or 'silent'), so you can disable all but error logging in production, and then run log.setLevel("trace") in your console to turn it all back on for a furious debugging session     按級別過濾日誌記錄,所以你能夠在生產中禁用除錯誤日誌記錄以外的全部日誌記錄,而後在控制檯中運行log.setLevel(「trace」)來向前追溯,以生成調試會話
  • Single file, no dependencies, weighs in at 1.1KB minified and gzipped單個文件,沒有依賴項,縮小和壓縮後的重量爲1.1KB

 

Effective

  • Log methods gracefully fall back to simpler console logging methods if more specific ones aren't available: so calls to log.debug() go to console.debug() if possible, or console.log() if not。若是沒有更具體的日誌方法,日誌方法會優雅地退回到更簡單的控制檯日誌方法:所以,若是可能的話,對Log .debug()的調用會轉到console.debug(),若是沒有,就會轉到console.log()
  • Logging calls still succeed even if there's no console object at all, so your site doesn't break when people visit with old browsers that don't support the console object (here's looking at you IE) and similar即便根本沒有控制檯對象,日誌調用仍然會成功,因此當人們訪問不支持控制檯對象(這裏是你的IE)和相似的舊瀏覽器時,你的站點不會崩潰
  • This then comes together giving a consistent reliable API that works in every JavaScript environment with a console available, and never breaks anything anywhere else這樣就提供了一個一致可靠的API,它能夠在每一個JavaScript環境中工做,而且有一個可用的控制檯,而且不會破壞任何其餘地方

 

Convenient

  • Log output keeps line numbers: most JS logging frameworks call console.log methods through wrapper functions, clobbering your stacktrace and making the extra info many browsers provide useless. We'll have none of that thanks.日誌輸出保持行號:大多數JS日誌框架經過包裝函數調用console.log,攻擊你的堆棧跟蹤,並使許多瀏覽器提供的額外信息無用。
  • It works with all the standard JavaScript loading systems out of the box (CommonJS, AMD, or just as a global)它適用於全部的標準JavaScript加載系統
  • Logging is filtered to "warn" level by default, to keep your live site clean in normal usage (or you can trivially re-enable everything with an initial log.enableAll() call)默認狀況下,日誌被過濾爲「warn」級別,以保持你的活動站點在正常使用中保持乾淨
  • Magically handles situations where console logging is not initially available (IE8/9), and automatically enables logging as soon as it does become available (when developer console is opened)神奇地解決了控制檯日誌最初不可用的狀況(IE8/9),並在日誌可用時自動啓用日誌

  • Extensible, to add other log redirection, filtering, or formatting functionality, while keeping all the above (except you will clobber your stacktrace, see Plugins below)可擴展,以添加其餘日誌重定向、過濾或格式化功能,同時保留上述全部功能

Downloading loglevel

npm install loglevel -g 或
npm install loglevel --save

 

Setting it up

CommonsJS (e.g. Node)

var log = require('loglevel');
log.warn("unreasonably simple");

 

With noConflict():

If you're using another JavaScript library that exposes a 'log' global, you can run into conflicts with loglevel. Similarly to jQuery, you can solve this by putting loglevel into no-conflict mode immediately after it is loaded onto the page. This resets to 'log' global to its value before loglevel was loaded (typically undefined), and returns the loglevel object, which you can then bind to another name yourself.json

若是你使用的另外一個JavaScript庫公開了「log」全局變量,那麼你可能會遇到與loglevel衝突的狀況.與下面jQuery狀況相似,你能夠在loglevel加載到頁面後當即將其設置爲無衝突模式,從而解決這個問題。這將在加載loglevel(一般未定義)以前將全局值重置爲「log」,並返回loglevel對象,而後你能夠本身綁定到另外一個名稱(在這裏改成logging)。瀏覽器

<script src="loglevel.min.js"></script>
<script>
var logging = log.noConflict();

logging.warn("still pretty easy");
</script>

 

Documentation

The loglevel API is extremely minimal. All methods are available on the root loglevel object, which it's suggested you name 'log' (this is the default if you import it in globally, and is what's set up in the above examples). The API consists of:服務器

loglevel API很是小。全部的方法在根loglevel對象上都是可用的,它建議你將其命名爲「log」(若是你全局地導入它,這是默認值,上面的示例中設置了這個值)。它的API有:cookie

  • 5 actual logging methods, ordered and available as:session

    • log.trace(msg)
    • log.debug(msg)
    • log.info(msg)
    • log.warn(msg)
    • log.error(msg)

    log.log(msg) is also available, as an alias for log.debug(msg), to improve compatibility with console, and make migration easier.  log.log(msg)也是可行的,它實際上是log.debug(msg)的別名,用來改善與控制檯的兼容性,使得移植更加簡單

    Exact output formatting of these will depend on the console available in the current context of your application. For example, many environments will include a full stack trace with all trace() calls, and icons or similar to highlight other calls.具體的輸出格式取決於應用程序當前上下文中可用的控制檯。例如,許多環境將包含包含全部trace()調用的完整堆棧跟蹤,以及圖標或相似於突出顯示其餘調用的圖標

    These methods should never fail in any environment, even if no console object is currently available, and should always fall back to an available log method even if the specific method called (e.g. warn) isn't available.這些方法在任何環境中都不該該失敗,即便當前沒有可用的控制檯對象,並且即便調用的特定方法(例如warn)不可用,也應該老是返回到可用的日誌方法

    Be aware that all this means that these method won't necessarily always produce exactly the output you expect in every environment; loglevel only guarantees that these methods will never explode on you, and that it will call the most relevant method it can find, with your argument. Firefox is a notable example here: due to a current Firefox buglog.trace(msg) calls in Firefox will print only the stacktrace, and won't include any passed message arguments.注意,全部這些都意味着這些方法不必定老是產生你在每一個環境中指望的輸出;loglevel只保證這些方法不會出錯,而且它會使用你的參數調用它能找到的最相關的方法。Firefox就是一個很顯著的例子:因爲Firefox中有一個當前的Firefox bug .trace(msg)調用,Firefox將只打印stacktrace,不會包含任何傳遞的消息參數

  • A log.setLevel(level, [persist]) method.

    This disables all logging below the given level, so that after a log.setLevel("warn") call log.warn("something") or log.error("something") will output messages, but log.info("something") will not.這將禁用全部低於給定級別的日誌記錄,所以在log.setLevel(「warn」)調用log.warn(「something」)或log.error(「something」)以後將輸出消息,可是log.info(「something」)不會

    This can take either a log level name or 'silent' (which disables everything) in one of a few forms:這能夠如下面的幾種形式去使用日誌級別的名稱,也可使用「silent」(這將禁用全部內容)

    • As a log level from the internal levels list, e.g. log.levels.SILENT ← for type safety,一種是log.levels.SILENT
    • As a string, like 'error' (case-insensitive) ← for a reasonable practical balance 另外一種是字符串形式'error'
    • As a numeric index from 0 (trace) to 5 (silent) ← deliciously terse, and more easily programmable (...although, why?)或者數字

    Where possible the log level will be persisted. LocalStorage will be used if available, falling back to cookies if not. If neither is available in the current environment (i.e. in Node), or if you pass false as the optional 'persist' second argument, persistence will be skipped.在可能的狀況下,日誌級別將被持久化。若是LocalStorage可使用就使用它,不然就使用cookie來保證日誌級別的持久性。若是這兩個參數在當前環境中都不可用(例如在Node中),或者若是傳遞false做爲可選的「persist」第二個參數,則將跳過持久性

    If log.setLevel() is called when a console object is not available (in IE 8 or 9 before the developer tools have been opened, for example) logging will remain silent until the console becomes available, and then begin logging at the requested level.若是在控制檯對象不可用時調用log.setLevel()(例如,在IE 8或9中,在開發工具打開以前),日誌記錄將保持靜默,直到控制檯可用,而後開始在請求的級別進行日誌記錄。

 

  • A log.setDefaultLevel(level) method.

    This sets the current log level only if one has not been persisted and can’t be loaded. This is useful when initializing scripts; if a developer or user has previously called setLevel(), this won’t alter their settings. For example, your application might set the log level to error in a production environment, but when debugging an issue, you might call setLevel("trace") on the console to see all the logs. If that error setting was set using setDefaultLevel(), it will still say as trace on subsequent page loads and refreshes instead of resetting to error.只有當一個日誌沒有被持久化且不能被加載時,纔會設置當前日誌級別。這在初始化腳本時頗有用;若是開發人員或用戶之前調用過setLevel(),這不會改變他們的設置。例如,你的應用程序可能會在生產環境中將日誌級別設置爲error,可是在調試問題時,你可能會在控制檯調用setLevel(「trace」)來查看全部日誌。若是error設置是使用setDefaultLevel()設置的,那麼它仍然會在後續頁面加載和刷新時寫入trace,而不是從新設置爲error。由於setLevel()會覆蓋setDefaultLevel()的初始化設置

    The level argument takes is the same values that you might pass to setLevel(). Levels set using setDefaultLevel() never persist to subsequent page loads.level參數的值與傳遞給setLevel()的值相同。使用setDefaultLevel()設置的級別永遠不會持續到後續頁面加載,會被setLevel()覆蓋

 

  • log.enableAll() and log.disableAll() methods.

    These enable or disable all log messages, and are equivalent to log.setLevel("trace") and log.setLevel("silent") respectively.這些消息能夠啓用或禁用全部日誌消息,它們分別等效於log. setlevel(「trace」)和log. setlevel(「silent」)

 

  • A log.getLevel() method.

    Returns the current logging level, as a number from 0 (trace) to 5 (silent) 返回目前的日誌級別,以數字的格式返回

    It's very unlikely you'll need to use this for normal application logging; it's provided partly to help plugin development, and partly to let you optimize logging code as below, where debug data is only generated if the level is set such that it'll actually be logged. This probably doesn't affect you, unless you've run profiling on your code and you have hard numbers telling you that your log data generation is a real performance problem.在正常的應用程序日誌記錄中,不太可能須要使用這個;它的提供部分是爲了幫助插件開發,部分是爲了讓你像下面這樣優化日誌記錄代碼,在這裏,調試數據只在級別設置爲可以實際記錄的狀況下生成。這可能不會影響到你,除非你已經在代碼上運行了分析,而且你有可靠的數據告訴你日誌數據生成是一個真正的性能問題

if (log.getLevel() <= log.levels.DEBUG) {
  var logData = runExpensiveDataGeneration();
  log.debug(logData);
}

This notably isn't the right solution to avoid the cost of string concatenation in your logging. Firstly, it's very unlikely that string concatenation in your logging is really an important performance problem. Even if you do genuinely have hard metrics showing that it is though, the better solution that wrapping your log statements in this is to use multiple arguments, as below. The underlying console API will automatically concatenate these for you if logging is enabled, and if it isn't then all log methods are no-ops, and no concatenation will be done at all.

這顯然不是避免日誌記錄中字符串鏈接成本的正確解決方案。首先,日誌記錄中的字符串鏈接不太多是一個重要的性能問題。即便你確實有確鑿的指標顯示它是,但將日誌語句包裝在其中的更好的解決方案是使用多個參數,以下所示。若是啓用了日誌記錄,底層控制檯API將自動爲你鏈接這些日誌記錄,若是沒有,那麼全部的日誌方法都是no-ops,而且根本不會進行鏈接。

// Prints 'My concatenated log message'
log.debug("My ", "concatenated ", "log message");
  • A log.getLogger(loggerName) method.

    This gets you a new logger object that works exactly like the root log object, but can have its level and logging methods set independently. All loggers must have a name (which is a non-empty string). Calling getLogger() multiple times with the same name will return an identical logger object.這將得到一個新的記錄器對象,它的工做方式與根日誌對象徹底相同,可是能夠獨立地設置其級別和日誌方法。全部日誌記錄器都必須有一個名稱(它是非空字符串)。屢次使用相同的名稱調用getLogger()將返回相同的logger對象

    In large applications, it can be incredibly useful to turn logging on and off for particular modules as you are working with them. Using the getLogger() method lets you create a separate logger for each part of your application with its own logging level.在大型應用程序中,當你使用特定模塊時,打開和關閉登陸時它可能很是有用。使用getLogger()方法,你能夠爲應用程序的每一個部分建立單獨的日誌記錄程序,並具備本身的日誌記錄級別

    Likewise, for small, independent modules, using a named logger instead of the default root logger allows developers using your module to selectively turn on deep, trace-level logging when trying to debug problems, while logging only errors or silencing logging altogether under normal circumstances.一樣,對於小型、獨立的模塊,使用命名日誌記錄器(而不是默認的根日誌記錄器)容許使用模塊的開發人員在調試問題時選擇性地打開深度跟蹤級別的日誌記錄,而在正常狀況下只記錄錯誤或徹底中止日誌記錄

    Example usage (using CommonJS modules, but you could do the same with any module system)例子:

// In module-one.js:
var log = require("loglevel").getLogger("module-one");
function doSomethingAmazing() {
  log.debug("Amazing message from module one.");
}

// In module-two.js:
var log = require("loglevel").getLogger("module-two");
function doSomethingSpecial() {
  log.debug("Special message from module two.");
}

// In your main application module:
var log = require("loglevel");
var moduleOne = require("module-one");
var moduleTwo = require("module-two");
log.getLogger("module-two").setLevel("TRACE");

moduleOne.doSomethingAmazing();
moduleTwo.doSomethingSpecial();
// logs "Special message from module two."
// (but nothing from module one.)

Loggers returned by getLogger() support all the same properties and methods as the default root logger, excepting noConflict() and the getLogger() method itself.getLogger()返回的記錄器支持全部與默認根記錄器相同的屬性和方法,noConflict()和getLogger()方法自己除外

Like the root logger, other loggers can have their logging level saved. If a logger’s level has not been saved, it will inherit the root logger’s level when it is first created. If the root logger’s level changes later, the new level will not affect other loggers that have already been created.與根日誌記錄器同樣,其餘日誌記錄器也能夠保存日誌記錄級別。若是未保存日誌記錄器的級別,則在第一次建立時它將繼承根日誌記錄器的級別。若是根日誌記錄器的級別稍後更改,新級別不會影響已經建立的其餘日誌記錄器。

Likewise, loggers will inherit the root logger’s methodFactory. After creation, each logger can have its methodFactory independently set. See the plugins section below for more about methodFactory.一樣,日誌記錄器將繼承根日誌記錄器的methodFactory。建立以後,每一個日誌記錄器均可以獨立地設置其methodFactory。有關methodFactory的更多信息,請參閱下面的插件部分。

  • A log.getLoggers() method.

    This will return you the dictionary of all loggers created with getLogger, keyed off of their names.返回全部的日誌信息

 

Plugins

Existing plugins:

loglevel-plugin-prefix - plugin for loglevel message prefixing.

loglevel-plugin-remote - plugin for sending loglevel messages to a remote log server.

ServerSend - https://github.com/artemyarulin/loglevel-serverSend - Forward your log messages to a remote server.

Standard Streams - https://github.com/NatLibFi/loglevel-std-streams - Route logging through STDERR in Node for easier log management.

Message Prefix - https://github.com/NatLibFi/loglevel-message-prefix - Dynamic (timestamp/level) and static ('foo') message prefixing.

Message Buffer - https://github.com/NatLibFi/loglevel-message-buffer - Buffer messages, and flush them on-demand later.

DEBUG - https://github.com/vectrlabs/loglevel-debug - Control logging from a DEBUG environmental variable (similar to the classic Debug module)

 

Writing plugins:

Loglevel provides a simple reliable minimal base for console logging that works everywhere. This means it doesn't include lots of fancy functionality that might be useful in some cases, such as log formatting and redirection (e.g. also sending log messages to a server over AJAX)Loglevel爲控制檯日誌記錄提供了一個簡單可靠的最低基礎,它在任何地方均可以工做。這意味着它不包含許多在某些狀況下可能有用的奇特功能,好比日誌格式化和重定向(例如,還經過AJAX向服務器發送日誌消息)

Including that would increase the size and complexity of the library, but more importantly would remove stacktrace information. Currently log methods are either disabled, or enabled with directly bound versions of the console.log methods (where possible). This means your browser shows the log message as coming from your code at the call to log.info("message!") not from within loglevel, since it really calls the bound console method directly, without indirection. The indirection required to dynamically format, further filter, or redirect log messages would stop this.包含這些操做將增長庫的大小和複雜性,但更重要的是將刪除stacktrace信息。目前,日誌方法要麼是禁用的,要麼是經過控制檯的直接綁定版本啓用的。這意味着瀏覽器在調用log.info(「message!」)時將日誌消息顯示爲來自代碼,而不是來自loglevel,由於它實際上直接調用綁定控制檯方法,而不是間接調用。動態格式化、進一步過濾或重定向日誌消息所需的間接方式將中止此操做

There's clearly enough enthusiasm for this even at that cost though that loglevel now includes a plugin API. To use it, redefine log.methodFactory(methodName, logLevel, loggerName) with a function of your own. This will be called for each enabled method each time the level is set (including initially), and should return a function to be used for the given log method, at the given level, for a logger with the given name. If you'd like to retain all the reliability and features of loglevel, it's recommended that this wraps the initially provided value of log.methodFactory儘管loglevel如今已經包含了一個插件API,但即便以這樣的代價來看,人們對此仍是有足夠的熱情。要使用它,須要從新定義log。methodFactory(methodName, logLevel, loggerName)有本身的功能。這將在每次設置級別(包括初始級別)時爲每一個啓用的方法調用,而且應該返回一個函數,用於給定的日誌方法,在給定級別,用於具備給定名稱的日誌記錄器。若是您但願保留loglevel的全部可靠性和特性,建議將最初提供的log.methodFactory的值包裝起來

For example, a plugin to prefix all log messages with "Newsflash: " would look like添加前綴的plugin:

var originalFactory = log.methodFactory;
log.methodFactory = function (methodName, logLevel, loggerName) {
    var rawMethod = originalFactory(methodName, logLevel, loggerName);

    return function (message) {
        rawMethod("Newsflash: " + message);
    };
};
log.setLevel(log.getLevel()); // Be sure to call setLevel method in order to apply plugin

(The above supports only a single log.warn("") argument for clarity, but it's easy to extend to a fuller varadic version)

If you develop and release a plugin, please get in contact! I'd be happy to reference it here for future users. Some consistency is helpful; naming your plugin 'loglevel-PLUGINNAME' (e.g. loglevel-newsflash) is preferred, as is giving it the 'loglevel-plugin' keyword in your package.json若是你開發和發佈一個插件,請聯繫!我很樂意在這裏爲將來的用戶提供參考。一些一致性是有幫助的;最好將你的插件命名爲「loglevel-PLUGINNAME」(例如,「loglevel-newsflash」),就像在你的package.json中賦予它「loglevel-plugin」關鍵字同樣

 

有一個很好的例子,你們能夠好好看看:http://demo.jb51.net/js/Blackbird/index.html

本站公眾號
   歡迎關注本站公眾號,獲取更多信息