loglevel-metamask

pimterry/loglevel

https://github.com/pimterry/loglevel

 

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

loglevel是JavaScript的最小轻量级日志记录,它没有控制台的缺点,替代了console.log()并且对于基于级别的日志和过滤是十分友好的

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:

这是一个可靠的日志库。它不做花哨的事情,不允许重新配置输出源,不允许添加复杂的日志过滤规则,但它确实具有你实际使用的所有核心功能

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.

如果你使用的另一个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有:

  • 5 actual logging methods, ordered and available as:

    • 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

posted @ 2018-11-07 17:33  慢行厚积  阅读(847)  评论(0编辑  收藏  举报