From 1e072ba3059f930f8c9843d9d3c5025d7f2d9106 Mon Sep 17 00:00:00 2001 From: Stijn de Witt Date: Thu, 4 Feb 2021 03:38:27 +0100 Subject: [PATCH] v2.0.0-beta.12: * Upgraded formatting to kurly v2 which supports static pipes * Implemented outputs as Kurly formats * Include kurly in ulog as standard * Added colors * Added alignments * Lazy loading --- .gitignore | 2 +- LICENSE | 2 +- README.md | 584 ++++++++++++++++++------------- base.js | 4 + build.js | 79 ++++- core/grab.js | 12 +- core/index.js | 13 +- core/merge.js | 14 + core/parse.js | 118 +++++++ example.js | 13 - full.bundle.js | 9 - full.js | 9 - mods/align/index.js | 18 + mods/align/utils.browser.js | 25 ++ mods/align/utils.js | 7 + mods/channels/console.js | 1 + mods/channels/index.js | 85 +++++ mods/channels/method.js | 3 + mods/channels/noop.js | 3 + mods/colors/index.js | 48 +++ mods/colors/utils.browser.js | 46 +++ mods/colors/utils.js | 41 +++ mods/config/configure.js | 15 + mods/config/index.js | 27 +- mods/config/notify.js | 20 ++ mods/config/read.browser.js | 15 +- mods/config/read.js | 18 +- mods/config/update.js | 22 +- mods/config/watch.browser.js | 10 +- mods/config/watch.js | 17 +- mods/config/watched.js | 18 + mods/config/watches.js | 13 + mods/debug/index.js | 19 + mods/formats/apply-alignment.js | 9 + mods/formats/apply-formatting.js | 25 ++ mods/formats/date.js | 11 + mods/formats/default.browser.js | 1 + mods/formats/default.js | 1 + mods/formats/formatter.js | 24 ++ mods/formats/index.js | 111 ++++-- mods/formats/json.js | 5 - mods/formats/lvl.js | 8 +- mods/formats/message.js | 7 + mods/formats/name.js | 8 +- mods/formats/perf.js | 21 ++ mods/formats/record.js | 19 - mods/formats/simple.browser.js | 7 - mods/formats/simple.js | 8 - mods/formats/structured.js | 25 -- mods/formats/time.js | 10 + mods/formats/utils.browser.js | 19 + mods/formats/utils.js | 8 + mods/formats/wildcard.js | 7 + mods/index.js | 18 +- mods/kurly/date.js | 9 - mods/kurly/format.js | 9 - mods/kurly/index.js | 24 -- mods/kurly/lvl.js | 5 - mods/kurly/name.js | 5 - mods/kurly/perf.js | 12 - mods/kurly/time.js | 8 - mods/levels/index.js | 19 +- mods/levels/test.js | 8 +- mods/options/index.js | 3 +- mods/outputs/index.js | 62 ++-- mods/props/boolean.js | 11 + mods/props/index.js | 11 + mods/settings/index.js | 2 +- mods/test.js | 4 +- package-lock.json | 187 ++++------ package.json | 62 ++-- screenshot.jpg | Bin 69258 -> 109281 bytes tutorial.html | 41 ++- ulog.bundle.js | 56 ++- ulog.js | 14 +- ulog.png | Bin 17637 -> 3316 bytes webpack.config.js | 14 + 77 files changed, 1510 insertions(+), 738 deletions(-) create mode 100644 base.js create mode 100644 core/merge.js create mode 100644 core/parse.js delete mode 100644 example.js delete mode 100644 full.bundle.js delete mode 100644 full.js create mode 100644 mods/align/index.js create mode 100644 mods/align/utils.browser.js create mode 100644 mods/align/utils.js create mode 100644 mods/channels/console.js create mode 100644 mods/channels/index.js create mode 100644 mods/channels/method.js create mode 100644 mods/channels/noop.js create mode 100644 mods/colors/index.js create mode 100644 mods/colors/utils.browser.js create mode 100644 mods/colors/utils.js create mode 100644 mods/config/configure.js create mode 100644 mods/config/notify.js create mode 100644 mods/config/watched.js create mode 100644 mods/config/watches.js create mode 100644 mods/debug/index.js create mode 100644 mods/formats/apply-alignment.js create mode 100644 mods/formats/apply-formatting.js create mode 100644 mods/formats/date.js create mode 100644 mods/formats/default.browser.js create mode 100644 mods/formats/default.js create mode 100644 mods/formats/formatter.js delete mode 100644 mods/formats/json.js create mode 100644 mods/formats/message.js create mode 100644 mods/formats/perf.js delete mode 100644 mods/formats/record.js delete mode 100644 mods/formats/simple.browser.js delete mode 100644 mods/formats/simple.js delete mode 100644 mods/formats/structured.js create mode 100644 mods/formats/time.js create mode 100644 mods/formats/utils.browser.js create mode 100644 mods/formats/utils.js create mode 100644 mods/formats/wildcard.js delete mode 100644 mods/kurly/date.js delete mode 100644 mods/kurly/format.js delete mode 100644 mods/kurly/index.js delete mode 100644 mods/kurly/lvl.js delete mode 100644 mods/kurly/name.js delete mode 100644 mods/kurly/perf.js delete mode 100644 mods/kurly/time.js create mode 100644 mods/props/boolean.js diff --git a/.gitignore b/.gitignore index f07def5..d6fdb1d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,6 @@ /dist /node_modules /ulog.min.js +/ulog.lazy.min.js /.nyc_output -/test.min.js /full.min.js diff --git a/LICENSE b/LICENSE index efe9b30..62023db 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2020 Stijn de Witt +Copyright (c) 2021 Stijn de Witt Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index e4faa6b..2279a27 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# ulog v2.0.0-beta.11 +# ulog v2.0.0-beta.12 ### The Universal Logger [![npm](https://img.shields.io/npm/v/ulog.svg)](https://npmjs.com/package/ulog) @@ -8,14 +8,37 @@ . -![logo](https://unpkg.com/ulog@2.0.0-beta.11/ulog.png) +![logo](https://unpkg.com/ulog@2.0.0-beta.12/ulog.png) ## The logger for applications `ulog` is *the* logger for Javascript applications. It's universal, meaning it runs everywhere. You can use `ulog` in your Express server application running on Node JS just as well as in your React single page application running in the browser. It just works. -![screenshot](https://unpkg.com/ulog@2.0.0-beta.11/screenshot.jpg) +![screenshot](https://unpkg.com/ulog@2.0.0-beta.12/screenshot.jpg) + + +## Features + +Ulog marries the feature sets from [`debug`](https://npmjs.com/package/debug) and [`loglevel`](https://npmjs.com/package/loglevel) and adds some of it's own! + +| Feature | debug | loglevel |   ulog   +| -------------- | -------------- | -------------- | -------------- +| Debug mode | ✓ | | ✓ +| Levels | | ✓ | ✓ +| Dynamic cfg | | | ✓ +| Formatting | ✓ | | ✓ +| Config fmt | | | ✓ +| Preserve stack | | ✓ | ✓ +| Colors | ✓ | | ✓ +| Align | | | ✓ +| Add-ons/Mods | | ✓ | ✓ +| Lazy loading | | | ✓ +| Anylogger | ✓ (1) | ✓ (1) | ✓ (2) + +(1) via an adapter +(2) native support + ## Install @@ -46,18 +69,17 @@ log('Logging is easy!') This way, your code is decoupled from `ulog` and if you ever want to switch to another logging library, you will be able to do so without having to change any of that code. > **anylogger** +> > [`anylogger`](https://npmjs.com/package/anylogger) is a logging facade that allows code to use logging without getting coupled to a specific logging system. You can use that code with any logging system out there. ## The logger for libraries -When we write a library to be used by other libraries or applications, we typically don't want to decide which logger these libraries or applications should use. Instead, we want to use whatever logging framework the client code is using. +When we write a library, we install `ulog` as a development dependency so the library remains decoupled from `ulog`. ### Install ulog as a dev dependency -We can have the cake and eat it to. We can decouple our library from `ulog` -for the client code, while still using it in development. To do so, we install -`anylogger` as a regular dependency and `ulog` as a dev dependency: +Install `anylogger` as a regular dependency and `ulog` as a dev dependency: ```sh npm install --save anylogger && npm install --save-dev ulog @@ -67,16 +89,16 @@ In our tests: *test.js* ```js - import `ulog` +import `ulog` ``` In our library code: *my-lib.js* ```js - import anylogger - const log = anylogger('my-lib') - log('Logging is easy') +import anylogger +const log = anylogger('my-lib') +log('Logging is easy') ``` @@ -85,58 +107,61 @@ In our library code: If you want, you can import `ulog` with a script tag: ```html - - + + + ``` *myscript.js* ```js - var log = anylogger('my-module') - log('Logging is easy!') +var log = anylogger('my-module') +log('Logging is easy!') ``` -Or, if you want the full version: +## Download -```html - -``` +If you want the file for the browser to include in your project yourself, you can download it from here. +* [ulog.min.js](https://unpkg.com/ulog@2.0.0-beta.12/ulog.min.js) (~2.8kB minified and gzipped) +* [ulog.lazy.min.js](https://unpkg.com/ulog@2.0.0-beta.12/ulog.lazy.min.js) (~4.3kB minified and gzipped) -## Download +> `ulog.min.js` lazy loads `ulog.lazy.min.js` on demand, so make sure to include both files in your download -If you want the file for the browser to include in your project yourself, you can download it from here. +* [full.min.js](https://unpkg.com/ulog@2.0.0-beta.12/full.min.js) (~5.7kB minified and gzipped) + +> Full bundle, no lazy loading -* [ulog.min.js](https://unpkg.com/ulog@2.0.0-beta.11) (~2.6kB minified and gzipped) -* [full.min.js](https://unpkg.com/ulog@2.0.0-beta.11/full.min.js) (~3.4kB minified and gzipped) +I recommend to use a bundler instead. Loading lots of script tags is inefficient and hard to manage. +Also see the section on [lazy loading with webpack](#lazy-loading-with-webpack) ## Why `ulog` -The two most popular logging libraries on NPM at the moment are [`debug`](https://npmjs.com/package/debug) and [`loglevel`](https://npmjs.com/package/loglevel), with 85.6M and 8.8M weekly downloads, respectively. They are both great loggers, but neither of them completely satisfied my requirements for a logging library. +The two most popular logging libraries on NPM at the moment are [`debug`](https://npmjs.com/package/debug) and [`loglevel`](https://npmjs.com/package/loglevel). They are both great loggers, but neither of them completely satisfied my requirements for a logging library. -`debug` has a simple API and is configurable on both Node JS via environment variables and in the browser via localStorage, though not dynamic, requiring a restart before changes take effect. It's simplicity makes it an excellent choice for debug logging (as it's name implies), but it lacks support for log levels, so if you want to log error messages for example, you end up needing another library for that. It offers nicely formatted (and even colored!) log messages, but because of that mangles the call stack, which is a huge downside in the browser imho. It offers some rudimentary support for configuring the destination of log messages, allowing you to send logging to a file instead of the console. Weighing in at 3.1kB minified and gzipped, it's a bit large for the feature set that it offers. And it's not very extensible either, basically being a monolith. +`debug` allows for namespaced debug logging, where each logger has a name. Whether these loggers output debug logging is configurable, though not dynamic, requiring a restart before changes take effect. It's simplicity makes `debug` an excellent choice for debug logging (as it's name implies), but it lacks support for log levels, so if you want to log error messages for example, you end up needing another library for that. It offers nicely formatted (and even colored!) log messages, but because of that mangles the call stack, which is a huge downside in the browser imho. It's not very extensible, basically being a monolith. -`loglevel` does offer log levels. These names start to make sense now right? It's API is also simple, but it has a global logger which is a downside imho as it allows for 'anonymous' logging, making it less suitable for debug logging. Also, though it's API is modeled after that of the console (a good thing imho), it does not have the `console.log` method, so it's not quitte a drop-in replacement for the console. It's configurable via localStorage but not via environment variables and just like `debug` requires a restart before configuration changes take effect. By default, it leaves your call stack alone, making the filename/line number entries in the browser console that much more useful. It does not offer alternative log destinations or formatters out of the box. It can be extended via plugins and there are some good plugins out there, but it's base feature set is coded as a monolith, so you cannot easily remove features. You probably won't have to though as it weighs only 1.4kB. +`loglevel` also supports namespaced logging and it does offer log levels. It's configurable via localStorage but not via environment variables and just like `debug` requires a restart before configuration changes take effect. By default, it leaves your call stack alone, making the filename/line number entries in the browser console that much more useful. It does not offer alternative log destinations or formatters out of the box. It can be extended via plugins and there are some good plugins out there, but it's base feature set is coded as a monolith, so you cannot easily remove features. You probably won't have to though as it weighs only 1.4kB. Both these loggers lack the ability to configure the logger from the querystring, which I found to be a very desirable feature for web development as it allows you to create a URL that has the log config embedded, which you can then send to other developers or users etc. E.g: `https://example.com/page?log=debug`. -Finally, both these loggers couple your code to the logging library. What I mean by that is that when you install a library using one of these loggers, that logger gets pulled in to your codebase. The downside of this is that in a more complex application using many libraries, you often end up with **both** loggers included in your app. In fact you often end up with 3 or even 4 logging libraries... which is a bit wasteful! +What I want is a logging library that combines the best aspects of both these loggers and adds the features that I miss in both. Specifically here are the features that I want in my ultimate logging library: -What I want is a logging library that combines the best aspects of both these loggers and adds the features that I miss in both, without coupling the client code to it. Specifically here are the features that I want in my ultimate logging library: - -* Simple API (nothing can beat `debug`'s single log function, but `ulog` gets close) +* Simple API * Supports all `console` log methods -* No 'anonymous' logging +* Supports levels * Configurable at runtime (without requiring a restart) * Accepts configuration from the querystring * Leaves the call stack alone -* Formatted log messages +* Formatted and colored log messages * Configurable log output and formatting options built in * Extensible * Decoupled from client code * Compact -`ulog` is my attempt at building this library. It's base API is compatible with that of `debug` and `loglevel` and with the console, making it a drop-in replacement for all of these in many cases. It does not support 'anonymous' logging, so no hunting down where a log message came from and no log messages that cannot be suppressed. And it has a configuration mechanism that is compatible with that of `debug`, but that is more powerful and is monitored for changes at runtime. It accepts configuration from the querystring allowing you to craft URLs with log config embedded in it. And even though it uses a simple formatter by default, I found a way to do this without mangling the call stack, so the filename/line number entries in the browser console remain unharmed. You can specify where the log output should go and where it should drain. It's completely modular, so you can not only easily add features through 'mods', but you can actually even drop features you don't need by not loading the mods those features are in. It has native `anylogger` support, decoupling the client code from the logger. And even with `anylogger` included, it still weighs just 2.8kB. Substantially smaller than `debug`, but offering way more features. +`ulog` is my attempt at building this library. It's base API is compatible with that of `debug` and `loglevel` and with the console, making it a drop-in replacement for all of these in many cases. It has a configuration mechanism that is compatible with that of `debug`, but that is more powerful and is monitored for changes at runtime. It accepts configuration from the querystring allowing you to craft URLs with log config embedded in it. It has powerful, configurable formatting included by default and it does this without mangling the call stack, so the filename/line number entries in the browser console remain unharmed. You can specify where the log output should go and where it should drain. It's completely modular, so you can not only easily add features through 'mods', but you can actually even drop features you don't need by not loading the mods those features are in. It has native `anylogger` support, decoupling the client code from the logger. And it supports lazy loading so we can get all those great features without bloating our bundle. + +I hope you will give `ulog` a try. If you have feedback on it, or found an issue, please let me know on the [issue tracker](https://github.com/download/ulog/issues). ## API @@ -145,7 +170,6 @@ What I want is a logging library that combines the best aspects of both these lo ```js var log = require('anylogger')('my-module') // same as with `debug` - log('A log message') // same as with `debug` log('info', 'An info message') // not possible with `debug` log('warn', 'A warning message') // not possible with `debug` @@ -163,125 +187,6 @@ if (log.enabledFor('warn')) { Note that any logging code written for either `debug`, `loglevel` or the console should be able to do it's logging just like it did before, but now using a `ulog` logger instead. This backward compatibility should make migrating from any of these to `ulog` very easy. And because this is just the `anylogger` API, you should even be able to migrate back to `debug` or `loglevel` without any changes at all, by just including the right adapter in your entry point. Of course once you get used to `ulog`, you will never want to go back! :p -## Configure - -`ulog` features a simple, yet powerful and flexible configuration mechanism. On Node JS, we can configure `ulog` via program arguments, environment variables or a configuration file. On browsers, we use querystring arguments or localStorage. On both platforms, the configuration is monitored and changes to it are picked up by `ulog` at runtime without the need to restart the application. - -`ulog`'s configuration mechanism is an extension to that of [`debug`](https://npmjs.com/package/debug) and is compatible with it. `debug` is one of the most popular logging packages in the NPM ecosystem, with tens of thousands of packages depending on it, so having `ulog`'s configuration mechanism be compatible with it makes for a very smooth migration path. If your app or library is currently using `debug`, you should be able to replace it with `ulog` with no or only minor changes. - -We configure `ulog` by adjusting configuration options. Those options include (but are not limited to): -* [`log`](#config_option_log): The main setting to control logger's levels with -* [`debug`](#config_option_debug): For compatibility with `debug` -* [`log_config`](#config_option_log_config): To specify the configuration file (Node JS only) -* [`log_output`](#config_option_log_output): To configure where logging should go (defaults to `console`) -* [`log_drain`](#config_option_log_drain): To configure where logs should drain (defaults to `drain`) -* [`log_format`](#config_option_log_format): To configure the format for log messages - -### Via program arguments -On Node JS we can pass log configuration options as program arguments: -```sh -node ./myapp log=debug -``` -This should be helpful when making CLI applications. These strongly rely on console messages, but are also often used in scripted setups where we would actually want to suppress that logging. Don't go and build in all kinds of custom methods to configure the logging but just use `ulog` and rely on it's powerful configuration mechanism instead. - -### Via environment variables -On Node JS we can pass log configuration options via environment variables: -```sh -log=debug node ./myapp -``` - -### Via a config file -On Node JS we can place our log configuration in a file that will be read at startup and monitored for changes at runtime: -*./log.config* -``` -log=debug -``` - -### Via querystring parameters -In browsers, we can pass log configuration options as querystring parameters in the URL: -``` -https://example.com/page?log=debug -``` - -### Via localStorage -In browsers, we can place our log configuration in localStorage and it will be read at startup and monitored for changes at runtime: -```js -localStorage.setItem('log', 'debug') -``` - -### Log configuration syntax -`debug` has a simple but powerful configuration mechanism. You set an environment variable or localStorage option named `DEBUG` and you assign it a value that expresses which loggers to enable. E.g.: - -```sh -DEBUG=test,my:*,-my:lib -``` -The format is basically a comma-separated list of logger names, using the asterisk as a wildcard character and optionally negating the expression by preceding it with a minus sign. So the expression above includes `test` and `my:*` loggers, except for `my:lib` which is excluded. - -`ulog` extends this configuration mechanism. With `debug`, you can only turn loggers on and off, but `ulog` allows for a much more varied range of options. This is achieved by extending the configuration syntax so it also accepts the value applicable for the loggers matching the expression. Also we allow a semicolon-separated list of such expression=value pairs. For example, to set the logger `test` to debug and `my:*` loggers except for `my:lib` to info, we could write: - -```sh -log=test=debug;my:*,-my:lib=info -``` - -If an option only contains a value, `ulog` implicitly adds `*` as the expression. So we can write: -```sh -log=info -``` -and it's equivalent to -```sh -log=*=info -``` -We can even combine this. So we could write: -```sh -log=info;my:*=debug -``` -and it will set the level for all loggers to info, except for the ones starting with `my:`, which are set to debug. - -A special case is the config option [debug](#config_option_debug), which is designed to be compatible with `debug` so code using `ulog` will react to that setting in the same way. - - -### Config option `log` -Configure the levels loggers should be filtered at. -```sh -log=test=debug;my:*,-my:lib=info -``` - -### Config option `debug` -Enables debug mode for the selected loggers. -```sh -debug=test,my:*,-my:lib -``` -This option is compatible with that of `debug`. - -### Config option `log_config` -Specify the path to the log configuration file, absolute or relative to the current working directory. Node JS only. Default to `./log.config`. This option does not support expressions. -```sh -log_config=./my.log.config -``` - -### Config option `log_output` -Specify the name of the output logs should be written to. Defaults to `'console'`. -```sh -log_output=my:*,-my:lib=console -``` - -### Config option `log_drain` -Specify the name of the output logs should be drained to. Defaults to `drain`. -When log messages are filtered out, they are sent to the drain instead of to the normal output. The default `drain` output is just a noop, but you could override this to send them to a separate file for example. -```sh -log_drain=my:*,-my:lib=console -``` - -### Config option `log_format` -Specify the named format to use, or a custom format string. Defaults to `simple`. -```sh -log_format=simple;some-lib=none;my:*,-my:lib={date}{time}{lvl}{name}{message}{perf} -``` -This sets `simple` as the default format, while assigning `none` to `some-lib` and a custom format string to all loggers starting with `my:` except for `my:lib`. - -For more details, refer to the [section on formatting](#formatting) - - ## Logging levels `anylogger` defines 6 logging levels, which correspond with the natively available @@ -299,7 +204,7 @@ log.TRACE // 6 In addition, `ulog` adds constants for pseudo-levels that enable or completely disable all logging: ```js -log.ALL // 9007199254740991 (Number.MAX_SAFE_INTEGER) +log.ALL // 7 log.NONE // 0 ``` @@ -330,6 +235,9 @@ log.error('Logging is completely disabled.') > In general, code should not set the log level directly, but instead should rely on the host environment for the log level. See the section on [configuring ulog](#configure). +> To check the log level, `enabledFor` is preferred over the `level` property as it is within the `anylogger` API. + + ### Default log level I've found that it makes sense to have different default log levels in the browser and in Node. In Node, logging is often the only UI we have available @@ -346,7 +254,7 @@ In the browser the log level defaults to `warn`. This means `info` messages will be excluded, but for most users these messages won't be relevant anyway. -> Attention! Chrome these days has it's own level filter and by default, debug messages are filtered away. +> Attention! Chromium-based browsers have their own level filter and by default, debug messages are filtered away. ## Debug mode @@ -369,16 +277,22 @@ log('Hi!') // is output because logger is in debug mode Outputs is a feature that separates `ulog` from `debug` and `loglevel`. This corresponds with what other libraries sometimes refer to as 'appenders'. In `ulog`, where messages are going is completely configurable at runtime. You can even configure where discarded messages are going! -By default, all log methods on a logger are associated with one of two outputs, `output` and `drain`. To configure these, two properties are added on each logger: +By default, all log methods on a logger are associated with one of two channels, `output` and `drain`. To configure these, two properties are added on each logger: * `log.output`, defaults to `'console'` * `log.drain`, defaults to `'drain'` -These correspond with config options [`log_output`](#config_option_log_output) and [`log_drain`](#config_option_log_drain) respectively. +These correspond with config options [`log_output`](#config_option_log_output) +and [`log_drain`](#config_option_log_drain) respectively. -By using a separate output for the drain, we can override the default behavior of using noops for all log levels that are outside of the active levels. We could for example send *all* logging to a database and only later filter it, when we display it for example. +By using a separate channel for the drain, we can override the default behavior +of using noops for all log levels that are outside of the active levels. We +could for example send *all* logging to a database and only later filter it, +when we display it for example. -When the logger is created, each log method is sent either to the `output`, or to the `drain`, based on the current log level for that logger and whether that logger is in debug mode. +When the logger is created, each log method is sent either to the `output` +channel, or to the `drain` channel, based on the current log level for that +logger and whether that logger is in debug mode. To configure the output for a logger, we assign the name of the output to use to the relevant logger: @@ -387,26 +301,66 @@ to the relevant logger: log_output=console ``` +This setting can include expressions to target individual loggers, just like +the `debug` and `log` settings: + +```sh +log_output=console;noisy-lib:*=noop +``` + +The value part is actually a kurly format string. The same syntax can be used +here as for [configuring formatting](#configuring-formatting). If more than +one output is specified, a multiplex function will be inserted that dispatches +the logging to all specified outputs. + By default, the following outputs are included: ### Output `console` -This actually is the native console object. Using the native console directly is what allows us to leave the call stack intact in the browser developer tools. +This actually is the native console object. Using the native console directly is +what allows us to leave the call stack intact in the browser developer tools. -### Output `drain` +### Output `noop` This is just an object with a noop `log` function ### Custom outputs -The default outputs are not very special, but the entire machinery is in place for you to easily add any custom outputs you could ever need. You can define additional outputs by making `ulog` use a mod with an `outputs` key: +The default outputs are not very special, but the entire machinery is in place for +you to easily add any custom outputs you could ever need. You can define additional +outputs by making `ulog` use a mod with an `outputs` key: *index.js* ```js import ulog from 'ulog' ulog.use({ outputs: { - custom: { log: function(){ - var args = [].slice.call(arguments) - args.shift('Custom!!') - console.log.apply(console, args) + custom: { + log: function(){ + var args = [].slice.call(arguments) + args.shift('Custom!!') + console.log.apply(console, args) + }, + info: function(){ + var args = [].slice.call(arguments) + args.shift('Custom!!') + console.info.apply(console, args) + } + } + } +}) +``` + +An output can either be an object with `log`, `info`, `warn` etc methods as shown +above, or a [kurly](https://npmjs.com/package/kurly) tag: + +*index.js* +```js +import ulog from 'ulog' +ulog.use({ + outputs: { + custom: function(ctx){ + return function(rec) { + rec.message.shift('Custom!!') + console[rec.level].apply(console, rec.message) + } }} } }) @@ -419,148 +373,274 @@ This way you can add outputs that send log messages to memory, a file, localStor Formatting is another feature that separates `ulog` from `debug` and `loglevel`. `debug` has formatting, but it is hardcoded and messes up the call stack and there is not much you can do about it. `loglevel` does not mess up the call stack, but it also has no formatting at all out of the box. If we are giving all loggers names, it would at least be good to see those names in the log output right? How else do we know which loggers to enable and disable? -Turns out you can have the cake and eat it to. We can have formatted messages that do not mess up the call stack. The way we do it is by `bind`ing the extra information into the log methods at logger creation/extension time. Granted, you cannot do this with dynamic info that changes on every call, but the logger name is static for each log method so we can add this without disrupting the call stack. +Ulog uses [kurly](https://npmjs.com/package/kurly) to support advanced configurable and customizable formatting, *without mangling the call stack*. As long as only [static kurly tags](https://www.npmjs.com/package/kurly/v/2.0.0-beta.2#static-tags) are used as formats, the call stack can remain unharmed. + +When we make a function that does some formatting and then calls `console.log` with the formatted message and we make the client code use our new function to do the logging (as `debug` does), we inject a function between `console.log` and the client code in the call stack that `console.log` uses to show the filenames and line numbers. The result will be that these will no longer point to the client code, but to that formatting function that was inserted. That is a problem imho as it breaks a very useful feature. Ulog finds a way around this, using static kurly tags and the fact that the console can do log formatting and can call `toString` on it's arguments to do formatting of the result. -Below is a list of formats that come bundled with `ulog` and it is mentioned for each of them whether it leaves the call stack intact. +When formatting is used, the default format string on Node is: -### Format `none` -This is a noop format that does not do anything. Leaves the call stack intact. +```sh +log_format=lvl name message perf +``` -### Format `simple` -Adds the logger name (and level on Node JS) into the log methods. Leaves the call stack intact. +This makes the output closely match that of debug. It sacrifies the call stack for a colored and formatted `message` and having the `perf` measurements after the message i.s.o before it. -Output looks like this on Node JS: +On browsers, we want to spare the call stack, so there the default is: +```sh +log_format=lvl name perf ``` -i my:logger This is an INFO message -``` -and like this in browsers: +We don't include the message, but it will be appended as the last argument automatically. The result if nicely formatted messages with the filename/line number entries in the broswer debug console intact. + +### Types of formats +Formats come in two flavors: + +**dynamic** + +Dynamic formatters have full access to the message. But they do mess up the call stack. A dynamic formatter has this signature: + +```js +ulog.use({ + formatters: { + dynamicFormatter: function(ctx) { + // one-time init here + return function(rec) { + // rec.message contains full message + return /* ... */ + } + } + } +}) ``` -my:logger This is an INFO message + +**static** + +Static formatters do not have access to the message. But they do not break the call stack! So prefer static formatters if possible. + +Static formatters have this signature: + +```js +ulog.use({ + formatters: { + staticFormatter: function(ctx, rec) { + // one-time init here + return function(){ + // rec.message is undefined + // rec.name, rec.level etc is populated + return /* ... */ + } + } + } +}) ``` -> Most browsers already do an excellent job in showing the level a message was logged at, so here we don't add the level indicator. +### Included formats -### Format `json` -Logs messages as JSON strings. Messes up the call stack. +Except for the `message` format, all included formats are static. -Sometimes we prefer that all data is logged in some structured format. `json` is an example of how to do that. +#### Format `date` +Returns the date part of the time the message was logged as `yyyy/MM/dd`. +Prints the date the message was logged -Output looks like this: +#### Format `lvl` +Returns the level of the message as a single character: +* `'x'` for error messages +* `'!'` for warning messages +* `'i'` for info messages +* `'-'` for log messages +* `'>'` for debug messages +* `'}'` for trace messages + +#### Format `message` +Prints the message, formatted and colored. +Using this format breaks the callstack as it is dynamic. + +#### Format `name` +Prints the current logger name + +#### Format `perf` +Prints the time difference between two invocations to the same logger, only if this difference is larger than 1ms. Produces output that looks like `+62ms`. + +#### Format `time` +Returns the time part of the time the message was logged as `hh:mm`. +Prints the time the message was logged + +#### Fallback format +Any unrecognized tags are being interpreted by the fallback format. This just +returns the field on the log record whose name matches. For example suppose +we'd write `level`. This is an unrecognized tag so the wildcard formatter is +used, which just returns the `level` field from the log record. If no field +on the log record matches, it returns the original text unchanged, making +`'Hello World!'` a valid format string. + +#### Padding options +All included formats support some padding options. For example, to pad out the +logger names to 16 characters and align the text on the left, use `name<16` or +`name:16`. To align the text on the right, use `name>16`. -``` -{"time":"2020-11-14T14:42:29.839Z","name":"my:logger","message":["This is a WARN message"],"level":2,"levelName":"warn","log_output":"console","log_drain":"drain","log_level":5,"log_format":"json"} -``` ### Make your own custom format You can easily add your own custom format to the list above. To do so, just `ulog.use` a mod with a `formats` property including your format, like so: *index.js* ```js -import ulog from 'ulog' -import formats from 'ulog/mods/formats' - +var ulog = require('ulog') ulog.use({ - use: [ formats ], + use: [ + require('ulog/mods/formats') + ], formats: { - cool: function(logger) { - // will be called on logger creation/extension - // replace the default log methods with formatters - // use bind so we leave the call stack intact. - // only works for static info like our 'Cool!' message - for (var level in this.levels) logger[level] = logger[level].bind(logger, 'Cool!') - // don't forget to format the method to discard to the drain as well! - logger.discard = logger.discard.bind(logger, 'Cool!') + cool: function(ctx) { + return function(rec) { + return ['Cool!!'].concat(rec.message) + } } } }) ``` -### Custom format strings using kurly -To keep the base bundle size down, `ulog` only bundles the formats above in the default build. But you can very easily make `ulog` understand custom format strings. For example you could set: +To read more about kurly and custom kurly tags, refer to the kurly documentation on [creating kurly tags](https://www.npmjs.com/package/kurly#creating-tags) + + +## Configure + +`ulog` features a simple, yet powerful and flexible configuration mechanism. On Node JS, we can configure `ulog` via program arguments, environment variables or a configuration file. On browsers, we use querystring arguments or localStorage. On both platforms, the configuration is monitored and changes to it are picked up by `ulog` at runtime without the need to restart the application. + +`ulog`'s configuration mechanism is an extension to that of [`debug`](https://npmjs.com/package/debug) and is compatible with it. `debug` is one of the most popular logging packages in the NPM ecosystem, with tens of thousands of packages depending on it, so having `ulog`'s configuration mechanism be compatible with it makes for a very smooth migration path. If your app or library is currently using `debug`, you should be able to replace it with `ulog` with no or only minor changes. + +We configure `ulog` by adjusting configuration options. + +* [`log`](#config_option_log): The main setting to control logger's levels with +* [`debug`](#config_option_debug): For compatibility with `debug` +* [`log_config`](#config_option_log_config): To specify the configuration file (Node JS only) +* [`log_output`](#config_option_log_output): To configure where logging should go (defaults to `console`) +* [`log_drain`](#config_option_log_drain): To configure where logs should drain (defaults to `drain`) +* [`log_format`](#config_option_log_format): To configure the format for log messages + +### Via program arguments +On Node JS we can pass log configuration options as program arguments: + +```sh +node ./myapp log=debug +``` +This should be helpful when making CLI applications. These strongly rely on console messages, but are also often used in scripted setups where we would actually want to suppress that logging. Don't go and build in all kinds of custom methods to configure the logging but just use `ulog` and rely on it's powerful configuration mechanism instead. + +### Via environment variables +On Node JS we can pass log configuration options via environment variables: ```sh -log_format={date}{time}{lvl}{name}{message}{perf} +log=debug node ./myapp ``` -To get log output looking like this: + +### Via a config file +On Node JS we can place our log configuration in a file that will be read at startup and monitored for changes at runtime: + +*./log.config* ``` -2020/10/14 15:46 i my:logger This is an INFO message +log=debug ``` -To support this, we need to include the mod `kurly`, which uses the template engine [`kurly`](https://npmjs.com/package/kurly) behind the surface to parse the custom format string. In our entry point, change this: +### Via querystring parameters +In browsers, we can pass log configuration options as querystring parameters in the URL: -*index.js* -```js -import ulog +``` +https://example.com/page?log=debug ``` -to +### Via localStorage +In browsers, we can place our log configuration in localStorage and it will be read at startup and monitored for changes at runtime: -*index.js* ```js - import ulog from 'ulog' - import kurly from 'ulog/mods/kurly' - ulog.use(kurly) +localStorage.setItem('log', 'debug') ``` -or, use the `ulog/full` endpoint instead: +### Log configuration syntax +`debug` has a simple but powerful configuration mechanism. You set an environment variable or localStorage option named `DEBUG` and you assign it a value that expresses which loggers to enable. E.g.: -*index.js* -```js -import `ulog/full` +```sh +DEBUG=test,my:*,-my:lib ``` +The format is basically a comma-separated list of logger names, using the asterisk as a wildcard character and optionally negating the expression by preceding it with a minus sign. So the expression above includes `test` and `my:*` loggers, except for `my:lib` which is excluded. -#### Kurly formatters -In the example above we were using tags like `{name}`, `{lvl}` etc. -The following is a list of such tags that are built in to the `kurly` mod: +`ulog` extends this configuration mechanism. With `debug`, you can only turn loggers on and off, but `ulog` allows for a much more varied range of options. This is achieved by extending the configuration syntax so it also accepts the value applicable for the loggers matching the expression. Also we allow a semicolon-separated list of such expression=value pairs. For example, to set the logger `test` to debug and `my:*` loggers except for `my:lib` to info, we could write: -##### Formatter `date` -Returns the date part of the time the message was logged as `yyyy/MM/dd`. +```sh +log=test=debug;my:*,-my:lib=info +``` -##### Formatter `time` -Returns the time part of the time the message was logged as `hh:mm`. +If an option only contains a value, `ulog` implicitly adds `*` as the expression. So we can write: +```sh +log=info +``` +and it's equivalent to +```sh +log=*=info +``` +We can even combine this. So we could write: +```sh +log=info;my:*=debug +``` +and it will set the level for all loggers to info, except for the ones starting with `my:`, which are set to debug. -##### Formatter `lvl` -Returns the level of the message as a single character: -* `'x'` for error messages -* `'!'` for warning messages -* `'i'` for info messages -* `' '` (space) for log, debug and trace messages +A special case is the config option [debug](#config_option_debug), which is designed to be compatible with `debug` so code using `ulog` will react to that setting in the same way. -##### Formatter `name` -Returns the name of the logger, right-padded with spaces for alignment. +Most of the config options support this syntax. -##### Formatter `perf` -Returns the difference in ms between two invocations to the same logger, only if this difference is larger than 1ms. Produces output that looks like `+62ms`. +### Config option `log` -##### Fallback formatter -Any unrecognized tags are being interpreted by the fallback formatter. This just returns the field on the log record whose name matches. In the example above we were using `{message}`. This is an unrecognized tag so the wildcard formatter is used, which just returns the `message` field from the log record. To get an idea for what fields are available on the log record, use the [json](#format_json) format. +Configure the levels loggers should be filtered at. +```sh +log=test=debug;my:*,-my:lib=info +``` -#### Custom kurly formatters +### Config option `debug` -With custom kurly formatters we customize on a higher level of abstraction. Instead of replacing the entire format with a custom one, we write small functions that format just a part of the message, leaving the composition of the message as a whole to be configured with a custom format string. We can add custom `kurly` formatters in much the same way as we add custom formats: +Enables debug mode for the selected loggers. -*index.js* -```js -import ulog from 'ulog' -import kurly from 'ulog/mods/kurly' -ulog.use(kurly) -ulog.use({ - formatters: { - custom: function(ctx) { - return function(rec) { - return 'Custom!' - } - } - } -}) +```sh +debug=test,my:*,-my:lib ``` +This option is compatible with that of `debug`. -To read more about kurly and custom kurly tags, refer to the kurly documentation on [creating kurly tags](https://www.npmjs.com/package/kurly#creating-tags) +### Config option `log_config` + +Specify the path to the log configuration file, absolute or relative to the current working directory. Node JS only. Default to `./log.config`. This option does not support expressions. + +```sh +log_config=./my.log.config +``` + +### Config option `log_output` + +Specify the name of the output logs should be written to. Defaults to `'console'`. + +```sh +log_output=my:*,-my:lib=console +``` + +### Config option `log_drain` + +Specify the name of the output logs should be drained to. Defaults to `drain`. +When log messages are filtered out, they are sent to the drain instead of to the normal output. The default `drain` output is just a noop, but you could override this to send them to a separate file for example. + +```sh +log_drain=my:*,-my:lib=console +``` + +### Config option `log_format` + +Specify the format to use. Defaults to `lvl name message perf` on Node JS and `lvl name perf` on browsers. + +```sh +log_format=lvl name perf message;some-lib=none;my:*=lvl name perf +``` +This sets `lvl name perf message` as the default format, while assigning `none` to `some-lib` and a different format string to all loggers starting with `my:`. + +For more details, refer to the [section on formatting](#formatting) @@ -619,7 +699,7 @@ Credits go to: ## Copyright -Copyright 2020 by [Stijn de Witt](https://stijndewitt.com). +Copyright 2021 by [Stijn de Witt](https://stijndewitt.com). ## License diff --git a/base.js b/base.js new file mode 100644 index 0000000..5502347 --- /dev/null +++ b/base.js @@ -0,0 +1,4 @@ +var ulog = module.exports = require('./core') +ulog.use([ + require('./mods/config'), +]) \ No newline at end of file diff --git a/build.js b/build.js index fed734f..96e1b03 100644 --- a/build.js +++ b/build.js @@ -3,25 +3,74 @@ var path = require('path') var gzipSize = require('gzip-size') // be cool and use ulog to print the logging in the build of ulog :) -var log = require('./')('ulog:build') +var ulog = require('./') +var log = ulog('ulog:build') -var [ processName, script, command, ...args ] = process.argv var pkg = JSON.parse(fs.readFileSync('./package.json', 'utf-8')) var v = pkg.version ;(function(){ - var data = fs.readFileSync(path.resolve(__dirname, pkg.unpkg), 'utf8') + var file = path.resolve(__dirname, pkg.unpkg) + log('Reading ' + file) + data = fs.readFileSync(file, 'utf8') + log('Estimating gzipped size') var gzip = (gzipSize.sync(data) / 1024).toFixed(1) - log.info(`Built ${pkg.unpkg} (~${gzip} kB minified and gzipped)`) - data = fs.readFileSync(path.resolve(__dirname, 'full.min.js'), 'utf8') - var fullzip = (gzipSize.sync(data) / 1024).toFixed(1) - log.info(`Built full.min.js (~${fullzip} kB minified and gzipped)`) - var readme = fs.readFileSync('README.md', 'utf-8') - readme = readme.replace(/ulog@\d(\d)?\.\d(\d)?\.\d(\d)?(-[a-z]+\.\d(\d)?)?/g, `ulog@${v}`) - readme = readme.replace(/\\v\d(\d)?\.\d(\d)?\.\d(\d)?(-[a-z]+\.\d(\d)?)?/g, `v${v}`) - readme = readme.replace(/ulog@\d(\d)?\.\d(\d)?\.\d(\d)?(-[a-z]+\.\d(\d)?)?\) \(~\d\.\dkB/g, `ulog@${v}) (~${gzip}kB`) - readme = readme.replace(/just 2.7kB/g, `just ${gzip}kB`) - readme = readme.replace(/ulog@\d(\d)?\.\d(\d)?\.\d(\d)?(-[a-z]+\.\d(\d)?)?\/full\.min\.js\) \(~\d\.\dkB/g, `ulog@${v}/full.min.js) (~${fullzip}kB`) - fs.writeFileSync('README.md', readme, 'utf8') - log.info(`Updated README.md`) + log.info(`${pkg.unpkg} (~${(data.length / 1024).toFixed(1)} kB, ${gzip} kB gzipped)`) + + file = path.resolve(__dirname, 'ulog.lazy.min.js') + log('Reading ' + file) + data = fs.readFileSync(file, 'utf8') + log('Estimating gzipped size') + var lazy = (gzipSize.sync(data) / 1024).toFixed(1) + log.info(`ulog.lazy.min.js (~${(data.length / 1024).toFixed(1)} kB, ${lazy} kB gzipped)`) + + file = path.resolve(__dirname, 'full.min.js') + log('Reading ' + file) + data = fs.readFileSync(file, 'utf8') + log('Estimating gzipped size') + var full = (gzipSize.sync(data) / 1024).toFixed(1) + log.info(`full.min.js (~${(data.length / 1024).toFixed(1)} kB, ${full} kB gzipped)`) + + file = path.resolve(__dirname, 'README.md') + log(`Reading ${file}`) + data = fs.readFileSync(file, 'utf-8') + log(`Updating version to ${v} and gzip size to ${gzip}...`) + data = data.replace(/ulog@\d(\d)?\.\d(\d)?\.\d(\d)?(-[a-z]+\.\d(\d)?)?/g, `ulog@${v}`) + data = data.replace(/\\v\d(\d)?\.\d(\d)?\.\d(\d)?(-[a-z]+\.\d(\d)?)?/g, `v${v}`) + data = data.replace(/ulog@\d(\d)?\.\d(\d)?\.\d(\d)?(-[a-z]+\.\d(\d)?)?\/ulog.min.js\) \(~\d\.\dkB/g, `ulog@${v}/ulog.min.js) (~${gzip}kB`) + data = data.replace(/ulog@\d(\d)?\.\d(\d)?\.\d(\d)?(-[a-z]+\.\d(\d)?)?\/ulog.lazy.min.js\) \(~\d\.\dkB/g, `ulog@${v}/ulog.lazy.min.js) (~${lazy}kB`) + data = data.replace(/ulog@\d(\d)?\.\d(\d)?\.\d(\d)?(-[a-z]+\.\d(\d)?)?\/full.min.js\) \(~\d\.\dkB/g, `ulog@${v}/full.min.js) (~${full}kB`) + log(`Writing ${file}`) + fs.writeFileSync(file, data, 'utf8') + log.info(`README.md (~${(data.length / 1024).toFixed(1)} kB)`) + + ulog('a:one').debug('A debug message') + ulog('a:two').debug('A debug message') + ulog('a:three').debug('A debug message') + ulog('a:four').debug('A debug message') + ulog('a:five').debug('A debug message') + ulog('b:one').log('A log message') + ulog('b:two').log('A log message') + ulog('b:three').log('A log message') + ulog('b:four').log('A log message') + ulog('b:five').log('A log message') + ulog('c:one').info('An info message') + ulog('c:two').info('An info message') + ulog('c:three').info('An info message') + ulog('c:four').info('An info message') + ulog('c:five').info('An info message') + ulog('d:one').warn('A warn message') + ulog('d:two').warn('A warn message') + ulog('d:three').warn('A warn message') + ulog('d:four').warn('A warn message') + ulog('d:five').warn('A warn message') + ulog('e:one').error('An error message') + ulog('e:two').error('An error message') + ulog('e:three').error('An error message') + ulog('e:four').error('An error message') + ulog('e:five').error('An error message') + ulog('ulog').error('An error message') + setTimeout(function(){ + log('A delayed message') + }, 1250) })() \ No newline at end of file diff --git a/core/grab.js b/core/grab.js index 80cadf9..d82b231 100644 --- a/core/grab.js +++ b/core/grab.js @@ -1,11 +1,11 @@ +var merge = require('./merge') + module.exports = function(ulog, name, result) { - ulog.mods.reduce(function(r,item) { - if (Array.isArray(r) && (name in item)) { - r.push(item[name]) + ulog.mods.reduce(function(r,mod){ + if (Array.isArray(r) && (name in mod)) { + r.push(mod[name]) } else { - for (var o in item[name]) { - r[o] = item[name][o] - } + merge(r, mod[name]) } return r }, result) diff --git a/core/index.js b/core/index.js index ecb5517..fe29b19 100644 --- a/core/index.js +++ b/core/index.js @@ -1,9 +1,7 @@ var ulog = require('anylogger') var grab = require('./grab') -// ulog.levels.none = 0 -// ulog.levels.all = 9007199254740991 // Number.MAX_SAFE_INTEGER -// var ext = ulog.ext // save for later +var ext = ulog.ext /** * `ulog.ext(logger) => logger` @@ -19,9 +17,12 @@ var grab = require('./grab') */ ulog.ext = function(logger) { if (logger) { -// ext(logger) // create default methods + ext(logger) grab(ulog, 'ext', []).map(function(ext){ - ext.call(ulog, logger) // call hook on registered mods + ext.call(ulog, logger) + }) + grab(ulog, 'after', []).map(function(ext){ + ext.call(ulog, logger) }) return logger } else { @@ -69,7 +70,7 @@ ulog.use = function(mod) { if (Array.isArray(mod)) { return mod.reduce(function(r,mod){return r + ulog.use(mod)}, 0) } - // handle mod being a single mod + // // handle mod being a single mod var result = ulog.mods.indexOf(mod) === -1 ? 1 : 0 if (result) { if (mod.use) { diff --git a/core/merge.js b/core/merge.js new file mode 100644 index 0000000..fb69cb8 --- /dev/null +++ b/core/merge.js @@ -0,0 +1,14 @@ +var merge = module.exports = function(result, obj) { + for (var o in obj) { + if ((typeof obj[o] == 'object') && (Object.getPrototypeOf(obj[o]) === Object.prototype)) { + if (! (o in result)) result[o] = {} + if ((typeof result[o] == 'object') && (Object.getPrototypeOf(obj[o]) === Object.prototype)) { + merge(result[o], obj[o]) + } else { + result[o] = obj[o] + } + } else { + result[o] = obj[o] + } + } +} diff --git a/core/parse.js b/core/parse.js new file mode 100644 index 0000000..b91f5ed --- /dev/null +++ b/core/parse.js @@ -0,0 +1,118 @@ +"lvl name:22 date:yy/mm/dd perf" + +"console file:./log.output url:https://deze-auto-kopen.nl component:( with nested components )" + + +function parse(str) { + var tag, result = [] + if (str || (str === '')) { + while (tag = nextTag(str)) { + var before = str.substring(0, tag.index) + if (before) result.push(before) + result.push({ + name: tag.name, + text: tag.text, + ast: parse(tag.text) + }) + str = str.substring(tag.end + 1) + } + if (str) result.push(str) + } + return result +} + +function nextTag(str) { + var match = str.match(/\{[_a-zA-Z][_a-zA-Z0-9]*([^_a-zA-Z0-9].*)?\}/) + var result + if (match) { + var name = match[1] ? match[0].substring(1, match[0].indexOf(match[1])) : match[0].substring(1, match[0].indexOf('}')) + result = { name: name, index: match.index, end: -1, text: '' } + // loop through the string, parsing it as we go through it + var esc = false + var open=1 // we already found one open brace + for (var i=match.index+name.length+1; i} ast An abstract syntax tree created with `parse` + * @param {Object} tags An object of tags keyed by tag name + * @param {Function} parent Optionally, a compiled parent function for the ast + * + * @returns An array, possibly empty but never null or undefined. + */ +function compile(ast, tags, parent) { + if (process.env.NODE_ENV != 'production') { + log.debug('compile', ast, tags, parent) + if ((ast === undefined) || (ast === null)) throw new Error('parameter `ast` is required') + if (! Array.isArray(ast)) throw new Error('parameter `ast` must be an array') + if ((tags === undefined) || (tags === null)) throw new Error('parameter `tags` is required') + if (typeof tags != 'object') throw new Error('parameter `tags` must be an object') + } + + // recursively compile the ast + var nodes = ast.map(function(n){ + return typeof n == 'string' + ? n : + compile(n.ast, tags, + tags[n.name] ? tags[n.name](n) : + tags['*'] ? tags['*'](n) : + undefined + ) + }) + + // create the result function + var result = function(rec) { + // clone rec into res + var res = {} + for (k in rec) res[k] = rec[k] + // get the result children + res.children = nodes.reduce(function(r, n){ + if (typeof n == 'function') n = n(rec) + r.push.apply(r, Array.isArray(n) ? n : [n]) + return r + }, []) + // invoke parent if we have it + return parent ? parent(res) : res.children + } + if (process.env.NODE_ENV != 'production') { + log('compile', ast, tags, parent, '=>', '[Function]') + } + return result; +} + + diff --git a/example.js b/example.js deleted file mode 100644 index 7452fd0..0000000 --- a/example.js +++ /dev/null @@ -1,13 +0,0 @@ -var ulog = require('./full') - -var log -log = ulog('test:log1') -for (var level in ulog.levels) { - log[level]('This is a ' + level.toUpperCase() + ' message') -} - -log = ulog('test:log2') -for (var level in ulog.levels) { - log[level]('This is a ' + level.toUpperCase() + ' message') -} - diff --git a/full.bundle.js b/full.bundle.js deleted file mode 100644 index 15f7ef8..0000000 --- a/full.bundle.js +++ /dev/null @@ -1,9 +0,0 @@ -// ulog - the universal logger -// © 2020 by Stijn de Witt -// License: MIT - -// This is the bundled version of ulog/full, for use as an old-fashioned script-include. -// Bundlers and node will use full.js directly -var kurly = require('./mods/kurly') -var ulog = module.exports = require('./ulog.bundle') -ulog.use(kurly) diff --git a/full.js b/full.js deleted file mode 100644 index 5d0f7c0..0000000 --- a/full.js +++ /dev/null @@ -1,9 +0,0 @@ -// ulog - the universal logger -// © 2020 by Stijn de Witt -// License: MIT - -// This is the full version of ulog, with kurly included. -// require('ulog/full') to include -var kurly = require('./mods/kurly') -var ulog = module.exports = require('./') -ulog.use(kurly) diff --git a/mods/align/index.js b/mods/align/index.js new file mode 100644 index 0000000..1b61a0d --- /dev/null +++ b/mods/align/index.js @@ -0,0 +1,18 @@ +// var grab = require('../../core/grab') +// var palette = require('./utils').palette +// var levels = require('./utils').levels + +var boolean = require('../props/boolean') + +module.exports = { + use: [ + require('../props'), + ], + + settings: { + align: { + config: 'log_align', + prop: boolean() + }, + }, +} diff --git a/mods/align/utils.browser.js b/mods/align/utils.browser.js new file mode 100644 index 0000000..10dd67e --- /dev/null +++ b/mods/align/utils.browser.js @@ -0,0 +1,25 @@ +var ZWSP = '​'; // zero-width space +var firefox = require('../colors/utils').firefox + +module.exports = { + // alignment depends on color format specifiers in the browser + hasAlign: require('../colors/utils').hasColor, + + specifier: { + error: '%c%s%c%s', + warn: '%c%s%c%s', + info: '%c%s%c%s', + log: '%c%s%c%s', + debug: '%c%s%c%s', + trace: '%c%s%c%s', + }, + + args: { + error: ['padding-left:0px', ZWSP, 'padding-left:0px', ZWSP], + warn: ['padding-left:' + (firefox ? '12' : '0') + 'px', ZWSP, 'padding-left:0px', ZWSP], + info: ['padding-left:' + (firefox ? '12' : '10') + 'px', ZWSP, 'padding-left:0px', ZWSP], + log: ['padding-left:' + (firefox ? '12' : '10') + 'px', ZWSP, 'padding-left:0px', ZWSP], + debug: ['padding-left:' + (firefox ? '12' : '10') + 'px', ZWSP, 'padding-left:0px', ZWSP], + trace: ['padding-left:0px', ZWSP, 'padding-left:0px', ZWSP], + }, +} diff --git a/mods/align/utils.js b/mods/align/utils.js new file mode 100644 index 0000000..1949f8a --- /dev/null +++ b/mods/align/utils.js @@ -0,0 +1,7 @@ +var console = require('../channels/console') +module.exports = { + hasAlign: function(output){return output === console}, + specifier: { + trace: '\n' + } +} diff --git a/mods/channels/console.js b/mods/channels/console.js new file mode 100644 index 0000000..78186a6 --- /dev/null +++ b/mods/channels/console.js @@ -0,0 +1 @@ +module.exports = (typeof console != 'undefined') && console \ No newline at end of file diff --git a/mods/channels/index.js b/mods/channels/index.js new file mode 100644 index 0000000..6b5bbd5 --- /dev/null +++ b/mods/channels/index.js @@ -0,0 +1,85 @@ +var grab = require('../../core/grab') +var console = require('./console') +var noop = require('./noop') +var method = require('./method') + +/** + * mod: channels + * + * Introduces the concept of log channels. + * + * A log channel is a path a log message may take that leads to an output. + * + * This mod enables multiple channels to be defined (by other mods) and offers + * a hook for other mods to customize how the channel output is created. + * + * This mod adds two default channels named 'output' and 'drain'. + */ +module.exports = { + use: [ + require('../config'), + require('../options'), + require('../props'), + ], + + // adds the channels 'output' and 'drain' + channels: { + output: { + out: console, + }, + drain: { + out: noop, + } + }, + + // enhance the given loggers with channels + ext: function(logger) { + var ulog = this + var channels = grab(ulog, 'channels', {}) + var channelOutputs = grab(ulog, 'channelOutput', []) + var recorders = grab(ulog, 'record', []) + logger.channels = {} + for (var channel in channels) { + var ch = logger.channels[channel] = { + name: channel, + channels: channels, + out: channels[channel].out || console, + recorders: recorders, + fns: {}, + } + ch.out = channelOutputs.reduce(function(r, channelOutput){ + return channelOutput.call(ulog, logger, ch) || r + }, ch.out); + for (var level in ulog.levels) { + var rec = ch.recorders.reduce(function(rec, record){ + record.call(ulog, logger, rec) + return rec + }, { channel: channel, level: level }) + ch.fns[level] = (function(ch,rec){ + return ( + typeof ch.out == 'function' ? function(){ + rec.message = [].slice.call(arguments) + ch.out(rec) + } + : + method(ch.out, rec) + ) + })(ch,rec) + } + } + }, + + // after all ext hooks have run, assign the log methods to + // the right channels based on logger.enabledFor + after: function(logger) { + for (var level in this.levels) { + logger[level] = logger.channels[logger.enabledFor(level) ? 'output' : 'drain'].fns[level] + } + }, + + record: function(logger, rec){ + rec.name = logger.name + rec.logger = logger + rec.ulog = this + } +} diff --git a/mods/channels/method.js b/mods/channels/method.js new file mode 100644 index 0000000..9525904 --- /dev/null +++ b/mods/channels/method.js @@ -0,0 +1,3 @@ +module.exports = function(out, rec) { + return out[rec.level] || out.log || function(){} +} \ No newline at end of file diff --git a/mods/channels/noop.js b/mods/channels/noop.js new file mode 100644 index 0000000..cbdafd1 --- /dev/null +++ b/mods/channels/noop.js @@ -0,0 +1,3 @@ +module.exports = { + log: function(){} +} \ No newline at end of file diff --git a/mods/colors/index.js b/mods/colors/index.js new file mode 100644 index 0000000..b08517e --- /dev/null +++ b/mods/colors/index.js @@ -0,0 +1,48 @@ +var grab = require('../../core/grab') +var palette = require('./utils').palette +var levels = require('./utils').levels +var boolean = require('../props/boolean') + +module.exports = { + use: [ + require('../props') + ], + + colors: { + palette: palette, + levels: levels, + }, + + settings: { + colored: { + config: 'log_color', + prop: boolean(), + }, + }, + + record: function(logger, rec) { + if (logger.colored) { + if (!logger.colors) { + logger.colors = grab(this, 'colors', {}) + logger.colors.index = hash(logger.name) % logger.colors.palette.length + } + if (!logger.color) { + logger.color = logger.colors.palette[logger.colors.index] + } + } + } +} + +function hash(s) { + for (var i=0, h=0xdeadbeef; i>> 16) >>> 0 +} + +// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/imul#Polyfill +function imul(a, b) { + b |= 0 + var result = (a & 0x003fffff) * b; + if (a & 0xffc00000 /*!== 0*/) result += (a & 0xffc00000) * b |0; + return result |0; +} diff --git a/mods/colors/utils.browser.js b/mods/colors/utils.browser.js new file mode 100644 index 0000000..5a048cc --- /dev/null +++ b/mods/colors/utils.browser.js @@ -0,0 +1,46 @@ +var console = require('../channels/console') + +module.exports = { + // Detect firefox to compensate for it's lack of support for format specifiers on console.trace + firefox: (typeof navigator != 'undefined') && /firefox/i.test(navigator.userAgent), + + hasColor: function(output){ + return (output === console) && + (navigator.userAgent.indexOf('MSIE') === -1) && + (navigator.userAgent.indexOf('Trident') === -1) + }, + + colorSpecifier: function(color){ + return '%c' + }, + + colorSpecifierAfter: function(color){ + return '' + }, + + colorArgument: function(color){ + return ['color:rgb(' + color.r + ',' + color.g + ',' + color.b + ')'] + }, + + palette: (function() { + var palette = [] + for (var r=0; r<8; r++) { + for (var g=0; g<8; g++) { + for (var b=0; b<8; b++) { + if ((r + g + b > 8) && (r + g + b < 16)) // filter out darkest and lightest colors + palette.push({r:24*r, g:24*g, b:24*b}) + } + } + } + return palette + })(), + + levels: { + error: { r: 192, g: 64, b: 0 }, + warn: { r: 180, g: 96, b: 0 }, + info: { r: 64, g: 128, b: 16 }, + log: { r: 64, g: 64, b: 64 }, + debug: { r: 96, g: 96, b: 96 }, + trace: { r: 112, g: 112, b: 112 }, + }, +} diff --git a/mods/colors/utils.js b/mods/colors/utils.js new file mode 100644 index 0000000..c8b6e5e --- /dev/null +++ b/mods/colors/utils.js @@ -0,0 +1,41 @@ +module.exports = { + firefox: false, + + hasColor: function(output){ + return (typeof console !== 'undefined') && (output === console) + }, + + colorSpecifier: function(color){ + return '\u001B[38;2;' + color.r + ';' + color.g + ';' + color.b + 'm' + }, + + colorArgument: function(color){ + return [] + }, + + colorSpecifierAfter: function(color){ + return '\x1b[0m' + }, + + palette: (function() { + var palette = [] + for (var r=0; r<8; r++) { + for (var g=0; g<8; g++) { + for (var b=0; b<8; b++) { + if ((r + g + b > 8) && (r + g + b < 16)) // filter out darkest and lightest colors + palette.push({r:32*r, g:32*g, b:32*b}) + } + } + } + return palette + })(), + + levels: { + error: { r: 244, g: 96, b: 48 }, + warn: { r: 200, g: 140, b: 0 }, + info: { r: 128, g: 204, b: 96 }, + log: { r: 192, g: 192, b: 192 }, + debug: { r: 160, g: 160, b: 160 }, + trace: { r: 144, g: 144, b: 144 }, + }, +} diff --git a/mods/config/configure.js b/mods/config/configure.js new file mode 100644 index 0000000..85a8217 --- /dev/null +++ b/mods/config/configure.js @@ -0,0 +1,15 @@ +var merge = require('../../core/merge') +var env = require('./env') +var args = require('./args') + +module.exports = function(watched, data) { + var cfg = {} + merge(cfg, env) + merge(cfg, args) + data && merge(cfg, data) + // var result = {} + // for (var setting in watched) { + // if (setting in cfg) result[setting] = cfg[setting] + // } + return cfg +} diff --git a/mods/config/index.js b/mods/config/index.js index 7497fdc..0bb1967 100644 --- a/mods/config/index.js +++ b/mods/config/index.js @@ -1,7 +1,9 @@ var grab = require('../../core/grab') -var args = require('./args') -var env = require('./env') +// var args = require('./args') +// var env = require('./env') var read = require('./read') +var update = require('./update') +var notify = require('./notify') var watch = require('./watch') module.exports = { @@ -9,22 +11,31 @@ module.exports = { require('../settings'), ], + settings: { + config: { + config: 'log_config' + } + }, + + ext: function(logger){ + this.get('config') + }, + get: function(result, name) { var ulog = this if (!ulog.config) { ulog.config = {}; - ulog.config = read(ulog) + var newCfg = read(ulog) + var changed = update(ulog.config, newCfg) + if (changed.length) notify(ulog, changed) watch(ulog) } if (!result) { var settings = grab(ulog, 'settings', {}) name = settings[name] && settings[name].config || name + result = ulog.config[name] } - result || ulog.config[name] || args[name] || env[name] - - // var settings = this.grab('settings') - // name = settings[name] && settings[name].config || name - return result || ulog.config[name] || args[name] || env[name] + return result }, set: function(name) { diff --git a/mods/config/notify.js b/mods/config/notify.js new file mode 100644 index 0000000..56d705a --- /dev/null +++ b/mods/config/notify.js @@ -0,0 +1,20 @@ +var watches = require('./watches') + +module.exports = function(ulog, changed) { + ulog.ext() + var watched = watches(ulog) + + changed.map(function(change){ + return { change: change, watches: watched.filter(function(watch){return typeof watch[change.name] == 'function'}) } + }) + .filter(function(item){ + return item.watches.length + }) + .forEach(function(item){ + item.watches.forEach(function(watch) { + setTimeout(function(){ + watch[item.change.name].call(ulog, item.change) + },0) + }) + }) +} diff --git a/mods/config/read.browser.js b/mods/config/read.browser.js index 3432f59..1463d42 100644 --- a/mods/config/read.browser.js +++ b/mods/config/read.browser.js @@ -1,13 +1,18 @@ -var grab = require('../../core/grab') + +var configure = require('./configure') +var watched = require('./watched') module.exports = function(ulog, callback) { - var settings = grab(ulog, 'settings', {}) + var watches = watched(ulog) + var cfg = {} - for (var setting in settings) { + for (var name in watches) { try { - var name = settings[setting].config || setting - if (name in localStorage) cfg[name] = localStorage.getItem(name) + var value = localStorage.getItem(name) + if (value) cfg[name] = value } catch(ignore){} } + + cfg = configure(watches, cfg) return callback ? callback(cfg) : cfg } diff --git a/mods/config/read.js b/mods/config/read.js index 03f06ae..771c332 100644 --- a/mods/config/read.js +++ b/mods/config/read.js @@ -1,19 +1,23 @@ var fs = require('fs') var path = require('path') + +var grab = require('../../core/grab') var parse = require('./parse') +var watched = require('./watched') +var configure = require('./configure') module.exports = function(ulog, callback) { - var filename = path.resolve(ulog.get('log_config') || 'log.config') + var settings = grab(ulog, 'settings', {}) + var log_config = ulog.get('log_config') || 'log.config' + var filename = path.resolve(log_config) if (callback) { fs.readFile(filename, 'utf8', function(e, data){ - if (e) return {} - else callback(parse(lines(data))) + callback(configure(watched(ulog, settings), data && parse(lines(data)))) }) } else { - try { - var data = fs.readFileSync(filename, 'utf8') - return parse(lines(data)) - } catch(e) {return {}} + var data + try {data = fs.readFileSync(filename, 'utf8')} catch(e){} + return configure(watched(ulog, settings), data && parse(lines(data))) } } diff --git a/mods/config/update.js b/mods/config/update.js index cb5b7c6..2aa09eb 100644 --- a/mods/config/update.js +++ b/mods/config/update.js @@ -1,15 +1,19 @@ module.exports = function(cfg, newCfg) { - var prop, changes = 0 - for (prop in cfg) { - if (! (prop in newCfg)) { - delete cfg[prop] - changes++ + var name, changes = [] + for (name in cfg) { + if (! (name in newCfg)) { + changes.push({ name: name, old: cfg[name] }) + delete cfg[name] } } - for (prop in newCfg) { - if ((! (prop in cfg)) || (cfg[prop] !== newCfg[prop])) { - cfg[prop] = newCfg[prop] - changes++ + for (name in newCfg) { + if ((! (name in cfg)) || (cfg[name] !== newCfg[name])) { + if (! (name in cfg)) { + changes.push({ name: name, new: newCfg[name] }) + } else { + changes.push({ name: name, old: cfg[name], new: newCfg[name] }) + } + cfg[name] = newCfg[name] } } return changes diff --git a/mods/config/watch.browser.js b/mods/config/watch.browser.js index 11f5d8a..24ac2f8 100644 --- a/mods/config/watch.browser.js +++ b/mods/config/watch.browser.js @@ -1,5 +1,6 @@ var read = require('./read') var update = require('./update') +var notify = require('./notify') module.exports = function(ulog) { // storage events unfortunately only fire on events triggered by other windows... @@ -7,9 +8,12 @@ module.exports = function(ulog) { setInterval(function(){ if (ulog.config) { var cfg = read(ulog) - if (update(ulog.config, cfg)) { - ulog.ext() - } + setTimeout(function(){ + var changed = update(ulog.config, cfg) + if (changed.length) setTimeout(function(){ + notify(ulog, changed) + }, 0) + }, 0) } }, 350) } diff --git a/mods/config/watch.js b/mods/config/watch.js index db6ebab..acbd3e2 100644 --- a/mods/config/watch.js +++ b/mods/config/watch.js @@ -3,27 +3,16 @@ var path = require('path') var read = require('./read') var update = require('./update') +var notify = require('./notify') module.exports = function(ulog) { var filename = path.resolve(ulog.get('log_config') || 'log.config') try { fs.watch(filename, { persistent: false }, function() { read(ulog, function(cfg){ - if (update(ulog.config, cfg)) ulog.ext() + var changed = update(ulog.config, cfg) + if (changed.length) notify(ulog, changed) }) }) - // debounce(100, ) } catch(ignore){} } - -function debounce(ms, callback) { - var wait - return function() { - if (wait) clearTimeout(wait) - var args = arguments - wait = setTimeout(function(){ - wait = null - callback.apply(null, args) - }, ms) - } -} diff --git a/mods/config/watched.js b/mods/config/watched.js new file mode 100644 index 0000000..c6066f1 --- /dev/null +++ b/mods/config/watched.js @@ -0,0 +1,18 @@ +var grab = require('../../core/grab') +var watches = require('./watches') + +module.exports = function(ulog){ + var settings = grab(ulog, 'settings', {}) + var watchers = watches(ulog) + var watched = {} + watchers.forEach(function(watcher){ + for (var name in watcher) { + watched[name] = watchers[name] + } + }) + for (var setting in settings) { + var name = (settings[setting] && settings[setting].config) || setting + watched[name] = settings[setting] + } + return watched +} diff --git a/mods/config/watches.js b/mods/config/watches.js new file mode 100644 index 0000000..6e46de0 --- /dev/null +++ b/mods/config/watches.js @@ -0,0 +1,13 @@ +var grab = require('../../core/grab') + +module.exports = function(ulog){ + return grab(ulog, 'watch', []).map(function(watch){ + var result = {} + for (var key in watch) { + key.split(',').forEach(function(name){ + result[name] = watch[key] + }) + } + return result + }) +} \ No newline at end of file diff --git a/mods/debug/index.js b/mods/debug/index.js new file mode 100644 index 0000000..e6166ac --- /dev/null +++ b/mods/debug/index.js @@ -0,0 +1,19 @@ +module.exports = { + use: [ + require('../channels'), + ], + + settings: { + debug: {} + }, + + init: function() { + this.enabled = this.get.bind(this, 'debug') + this.enable = this.set.bind(this, 'debug') + this.disable = this.set.bind(this, 'debug', '') + }, + + ext: function(logger) { + logger.enabledFor = this.get.bind(this, 'debug', logger.name) + } +} diff --git a/mods/formats/apply-alignment.js b/mods/formats/apply-alignment.js new file mode 100644 index 0000000..f925e8e --- /dev/null +++ b/mods/formats/apply-alignment.js @@ -0,0 +1,9 @@ +var alignment = require('../align/utils') +var hasAlign = alignment.hasAlign + +module.exports = function(rec, r){ + var a = hasAlign(rec.logger.channels[rec.channel].out) && rec.logger.align && alignment + r[0] = ((a && a.specifier && a.specifier[rec.level]) || '') + r[0] + r.splice.apply(r, [1, 0].concat((a && a.args && a.args[rec.level]) || [])) + return r +} diff --git a/mods/formats/apply-formatting.js b/mods/formats/apply-formatting.js new file mode 100644 index 0000000..d631071 --- /dev/null +++ b/mods/formats/apply-formatting.js @@ -0,0 +1,25 @@ +var console = require('../channels/console') +var hasColor = require('../colors/utils').hasColor +var colorSpecifier = require('../colors/utils').colorSpecifier +var colorArgument = require('../colors/utils').colorArgument +var colorSpecifierAfter = require('../colors/utils').colorSpecifierAfter + +module.exports = function(rec, fmt, msg, r){ + var out = rec.logger.channels[rec.channel].out + if (out === console) { + var colored = hasColor(out) + var c = colored && rec.logger.colored && fmt.color + c = c == 'level' ? rec.logger.colors.levels[rec.level] : c + c = c == 'logger' ? rec.logger.color : c + r[0] += (c && colorSpecifier(c)) || '' + var len = Array.isArray(msg) ? msg.length : 1 + for (var i=0; i') dir = pad.LEFT + if (text[0] == '<') dir = pad.RIGHT + text = (text[0] == '>') || (text[0] == '<') ? text.substring(1) : text + if (Number(text) && (Number(text) === Number(text))) padding = Number(text) + }) + var fmt = function(rec) { + var result = fn(rec) + if (Array.isArray(result) && (result.length == 1) && (typeof result[0] == 'string')) + result = result[0] + if (padding && (typeof result == 'string')) result = pad(result, padding, ' ', dir) + return result + } + var result = rec ? function() {return fmt(rec)} : function(rec){return fmt(rec)} + for (var prop in props) { + result[prop] = props[prop] + } + return result +} diff --git a/mods/formats/index.js b/mods/formats/index.js index f892105..3f25927 100644 --- a/mods/formats/index.js +++ b/mods/formats/index.js @@ -1,47 +1,110 @@ +var parse = require('kurly/parse') +var pipe = require('kurly/pipe') var grab = require('../../core/grab') +var console = require('../channels/console') +var makeStatic = require('./utils').makeStatic +var makeStaticPipe = require('./utils').makeStaticPipe +var applyFormatting = require('./apply-formatting') +var applyAlignment = require('./apply-alignment') +/** + * mod - formats + * + * Makes log formatting configurable and extendable + */ module.exports = { use: [ - require('../levels'), + require('../channels'), ], settings: { format: { config: 'log_format', prop: { - default: 'simple', + default: require('./default'), } }, }, formats: { - none: function(){}, - simple: require('./simple'), - json: require('./json'), - '*': function(){} + // add a bunch of formats + date: require('./date'), + lvl: require('./lvl'), + message: require('./message'), + name: require('./name'), + perf: require('./perf'), + time: require('./time'), + '*': require('./wildcard'), }, ext: function(logger) { - var formats = grab(this, 'formats', {}) - var format = formats[logger.format] || formats['*'] - format.call(this, logger) - }, + var ulog = this + for (var channel in logger.channels) { + for (var level in ulog.levels) { + logger.channels[channel].fns[level] = makePipe(ulog, logger, channel, level) + } + } + + function makePipe(ulog, logger, channel, level) { + var formats = grab(ulog, 'formats', {}) + var ast = parse(logger.format, { optional: true }) + var rec = logger.channels[channel].recorders.reduce(function(rec, record){ + record.call(ulog, logger, rec) + return rec + }, { channel: channel, level: level }) + var line = pipe(ast, formats, rec) + var ch = logger.channels[channel] + var method = ch.fns[level] + var output = ch.out - // for structured formats, the default record function - record: function(logger, level, args, rec) { - rec.time = new Date() - rec.name = logger.name - rec.message = args - rec.level = logger[level.toUpperCase()] - rec.levelName = level - - // properties like output, format, level... - var settings = grab(this, 'settings', {}) - for (var name in settings) { - if (settings[name].prop) { - rec['log_' + name] = logger[name] + if ((output === console) && pipe.isStatic(line)) { + // derive the arguments to be bound from the pipeline + var args = line + .map(toTag) + .filter(skip) + .reduce(function(r,fmt){ + var msg = makeStatic(fmt) + return applyFormatting(rec, fmt, msg, r) + }, ['']) + // apply alignment if needed + applyAlignment(rec, args) + // bind the output and arguments to the log method + // this uses a devious trick to apply formatting without + // actually replacing the original method, and thus + // without mangling the call stack + return makeStaticPipe(output, method, rec, args) + } else { + return makeDynamicPipe(output, method, rec, line) } + } + + function makeDynamicPipe(output, method, rec, line) { + // set up a dynamic pipeline as a function + var containsMessage = line.reduce(function(r,node){return r || (node && node.name === 'message')}, false) + return (function(rec){return function() { + // arguments to this function are the message + rec.message = [].slice.call(arguments) + // run through the pipeline, running all formatters + var args = line + .map(toTag) + .filter(skip) + .reduce(function(r,fmt){ + var msg = typeof fmt == 'function' ? fmt(rec) : fmt + return applyFormatting(rec, fmt, msg, r) + }, ['']) + if (! containsMessage) args.push.apply(args, rec.message) + // apply alignment if needed + applyAlignment(rec, args) + // pass the formatted arguments on to the original output method + method.apply(output, args) + }})(rec) } - rec.logger = logger + + function toTag(node) {return ( + !node || !node.tag ? node : + node.tag + )} + + function skip(tag){return (typeof tag != 'string') || tag.trim().length} }, } diff --git a/mods/formats/json.js b/mods/formats/json.js deleted file mode 100644 index 6a0a9bc..0000000 --- a/mods/formats/json.js +++ /dev/null @@ -1,5 +0,0 @@ -var structured = require('./structured') - -module.exports = function(logger) { - structured(this, logger, JSON.stringify) -} diff --git a/mods/formats/lvl.js b/mods/formats/lvl.js index 257ae41..38ab4ed 100644 --- a/mods/formats/lvl.js +++ b/mods/formats/lvl.js @@ -1,5 +1,7 @@ -var LVL = [' ', 'x', '!', 'i', ' ', ' ', ' '] +var formatter = require('./formatter') -module.exports = function(rec) { - return LVL[rec.level] +module.exports = function(ctx, rec){ + return formatter(ctx, rec, { color: 'level' }, function(){ + return [' ', 'x', '!', 'i', '-', '>', '}'][rec.ulog.levels[rec.level]] + }) } diff --git a/mods/formats/message.js b/mods/formats/message.js new file mode 100644 index 0000000..810fef8 --- /dev/null +++ b/mods/formats/message.js @@ -0,0 +1,7 @@ +var formatter = require('../formats/formatter') + +module.exports = function(ctx) { + return formatter(ctx, { color: 'level' }, function(rec){ + return rec.message + }) +} diff --git a/mods/formats/name.js b/mods/formats/name.js index 6048e8a..d481572 100644 --- a/mods/formats/name.js +++ b/mods/formats/name.js @@ -1,5 +1,7 @@ -var pad = require('../formats/pad') +var formatter = require('./formatter') -module.exports = function(rec) { - return pad(rec.name, 19) +module.exports = function(ctx, rec) { + return formatter(ctx, rec, { color: 'logger', padding: 16 }, function(){ + return rec.logger.name + }) } diff --git a/mods/formats/perf.js b/mods/formats/perf.js new file mode 100644 index 0000000..a08f378 --- /dev/null +++ b/mods/formats/perf.js @@ -0,0 +1,21 @@ +var formatter = require('./formatter') + +module.exports = function(ctx, rec) { + return formatter(ctx, rec, { color: 'logger', padding: 6, dir: 1 }, function(){ + var time = new Date() + rec.logger.lastCalled = rec.logger.lastCalled || time + var ms = time.getTime() - rec.logger.lastCalled.getTime() + rec.logger.lastCalled = time + return ( + ms >= 36000000 ? (ms/3600000).toFixed(1) + 'h' : + ms >= 600000 ? (ms/60000).toFixed(ms >= 6000000 ? 1 : 2) + 'm' : + ms >= 10000 ? (ms/1000).toFixed(ms >= 100000 ? 1 : 2) + 's' : + // a one-ms diff is bound to occur at some point, + // but it doesn't really mean anything as it's + // basically just the next clock tick, so only + // show values > 1 + ms > 1 ? ms + 'ms' : + '' + ) + }) +} diff --git a/mods/formats/record.js b/mods/formats/record.js deleted file mode 100644 index b1caf04..0000000 --- a/mods/formats/record.js +++ /dev/null @@ -1,19 +0,0 @@ -var grab = require('../../core/grab') - -/** - * Records a record for a log call based on the ulog instance, the logger and leven and the call arguments. - * - * Collects all record functions from all mods and allows each of them to contribute to the result. - * - * @param {} ulog Ulog instance - * @param {*} logger Logger instance - * @param {*} level The level of the current call - * @param {*} args The arguments of the log call - */ -module.exports = function(ulog, logger, level, args){ - var recorders = grab(ulog, 'record', []) - return recorders.reduce(function(r, record){ - record.call(ulog, logger, level, args, r) - return r - }, {}) -} diff --git a/mods/formats/simple.browser.js b/mods/formats/simple.browser.js deleted file mode 100644 index 5e46701..0000000 --- a/mods/formats/simple.browser.js +++ /dev/null @@ -1,7 +0,0 @@ -var name = require('./name') - -module.exports = function(logger){ - var loggerName = name(logger) - for (var level in this.levels) logger[level] = logger[level].bind(logger, loggerName) - logger.discard = logger.discard.bind(logger, loggerName) -} diff --git a/mods/formats/simple.js b/mods/formats/simple.js deleted file mode 100644 index 6852d2e..0000000 --- a/mods/formats/simple.js +++ /dev/null @@ -1,8 +0,0 @@ -var name = require('./name') -var lvl = require('./lvl') - -module.exports = function(logger){ - var loggerName = name(logger) - for (var level in this.levels) logger[level] = logger[level].bind(logger, lvl({ level: logger[level.toUpperCase()] }), loggerName) - logger.discard = logger.discard.bind(logger, ' ', loggerName) -} diff --git a/mods/formats/structured.js b/mods/formats/structured.js deleted file mode 100644 index 749fe99..0000000 --- a/mods/formats/structured.js +++ /dev/null @@ -1,25 +0,0 @@ -var record = require('./record') - -/** - * Creates a format function based on a structured formatter - * - * The structured formatter function can be any function that accepts an object - * as a parameter and returns the thing to be logged. If the result of the call - * to the structured formatting function is not an array, it will be wrapped in - * one. The resulting array will be used as the final arguments in the log call - * - * @param {*} formatter The structured formatter function - */ -module.exports = function(ulog, logger, formatter){ - var format = function(level, fn){ - return function(){ - var args = [].slice.call(arguments) - var rec = record(ulog, logger, level, args) - args = formatter(rec) - if (! Array.isArray(args)) args = [args] - fn.apply(logger, args) - } - } - for (var level in ulog.levels) logger[level] = format.call(ulog, level, logger[level]) - logger.discard = format.call(ulog, level, logger.discard) -} diff --git a/mods/formats/time.js b/mods/formats/time.js new file mode 100644 index 0000000..bcffedb --- /dev/null +++ b/mods/formats/time.js @@ -0,0 +1,10 @@ +var formatter = require('../formats/formatter') +var pad = require('../formats/pad') + +module.exports = function(ctx, rec){ + return formatter(ctx, rec, { color: 'logger' }, function() { + var time = new Date() + return pad(time.getHours().toString(), 2, '0', pad.LEFT) + ':' + + pad(time.getMinutes().toString(), 2, '0', pad.LEFT) + }) +} \ No newline at end of file diff --git a/mods/formats/utils.browser.js b/mods/formats/utils.browser.js new file mode 100644 index 0000000..8d96284 --- /dev/null +++ b/mods/formats/utils.browser.js @@ -0,0 +1,19 @@ +// Detect V8 in browsers to compensate for a bug where toString is called twice +var bug = (typeof Intl != 'undefined') && Intl.v8BreakIterator +var firefox = require('../colors/utils').firefox + +module.exports.makeStatic = function(fmt){ + if (bug && (typeof fmt == 'function') && (fmt.toString === fmt)) { + var skip = bug + fmt.toString = function(){ + if (skip) return skip = '' + skip = bug + return fmt() + } + } + return fmt +} + +module.exports.makeStaticPipe = function(output, method, rec, args) { + return method.bind.apply(method, [output].concat(firefox && (rec.level === 'trace') ? [] : args)) +} diff --git a/mods/formats/utils.js b/mods/formats/utils.js new file mode 100644 index 0000000..5a47887 --- /dev/null +++ b/mods/formats/utils.js @@ -0,0 +1,8 @@ +module.exports.makeStatic = function(fmt){ + fmt.toString = fmt + return fmt +} + +module.exports.makeStaticPipe = function(output, method, rec, args) { + return method.bind.apply(method, [output].concat(args)) +} diff --git a/mods/formats/wildcard.js b/mods/formats/wildcard.js new file mode 100644 index 0000000..2aae59e --- /dev/null +++ b/mods/formats/wildcard.js @@ -0,0 +1,7 @@ +var formatter = require('./formatter') + +module.exports = function(ctx, rec) { + return formatter(ctx, rec, { color: 'level' }, function() { + return ctx.name in rec ? rec[ctx.name] : ctx.name + (ctx.text ? ctx.text : '') + }) +} \ No newline at end of file diff --git a/mods/index.js b/mods/index.js index 7c4bb95..278f1da 100644 --- a/mods/index.js +++ b/mods/index.js @@ -1,9 +1,13 @@ module.exports = [ - require('./settings'), - require('./config'), - require('./options'), - require('./props'), - require('./outputs'), - require('./levels'), - require('./formats'), + // require('./settings'), + // require('./config'), + // require('./options'), + // require('./props'), + require('./channels'), + // require('./outputs'), + // require('./colors'), + // require('./align'), +// require('./formats'), +// require('./levels'), +// require('./ulog') ] diff --git a/mods/kurly/date.js b/mods/kurly/date.js deleted file mode 100644 index 6dbaeb5..0000000 --- a/mods/kurly/date.js +++ /dev/null @@ -1,9 +0,0 @@ -var pad = require('../formats/pad') - -module.exports = function(){ - return function(rec) { - return rec.time.getFullYear() + '/' + - pad(rec.time.getMonth().toString(), 2, '0', pad.LEFT) + '/' + - pad(rec.time.getDate().toString(), 2, '0', pad.LEFT) - } -} \ No newline at end of file diff --git a/mods/kurly/format.js b/mods/kurly/format.js deleted file mode 100644 index b0dbaae..0000000 --- a/mods/kurly/format.js +++ /dev/null @@ -1,9 +0,0 @@ -var kurly = require('kurly') -var grab = require('../../core/grab') -var structured = require('../formats/structured') - -module.exports = function(logger){ - var ast = kurly.parse(logger.format) - var template = kurly.compile(ast, grab(this, 'formatters', {})) - structured(this, logger, template) -} diff --git a/mods/kurly/index.js b/mods/kurly/index.js deleted file mode 100644 index d7ff940..0000000 --- a/mods/kurly/index.js +++ /dev/null @@ -1,24 +0,0 @@ -module.exports = { - use: [ - require('../formats'), - ], - - formats: { - // this will override the default wildcard format with the kurly format - '*': require('./format'), - }, - - // some default formatters - formatters: { - name: require('./name'), - lvl: require('./lvl'), - date: require('./date'), - time: require('./time'), - perf: require('./perf'), - '*': function(ctx){ - return function(rec){ - return rec[ctx.name] - } - } - }, -} diff --git a/mods/kurly/lvl.js b/mods/kurly/lvl.js deleted file mode 100644 index 2d69f04..0000000 --- a/mods/kurly/lvl.js +++ /dev/null @@ -1,5 +0,0 @@ -var lvl = require('../formats/lvl') - -module.exports = function(){ - return lvl -} diff --git a/mods/kurly/name.js b/mods/kurly/name.js deleted file mode 100644 index 833fadf..0000000 --- a/mods/kurly/name.js +++ /dev/null @@ -1,5 +0,0 @@ -var name = require('../formats/name') - -module.exports = function(){ - return name -} diff --git a/mods/kurly/perf.js b/mods/kurly/perf.js deleted file mode 100644 index e7ad0fc..0000000 --- a/mods/kurly/perf.js +++ /dev/null @@ -1,12 +0,0 @@ -var pad = require('../formats/pad') - -module.exports = function() { - return function(rec) { - var result = '' - if (rec.logger.lastCalled && (rec.time.getTime() - rec.logger.lastCalled.getTime() > 1)) { - result = '+' + (rec.time.getTime() - rec.logger.lastCalled.getTime()) + 'ms' - } - rec.logger.lastCalled = rec.time - return pad(result, 8) - } -} diff --git a/mods/kurly/time.js b/mods/kurly/time.js deleted file mode 100644 index e31d034..0000000 --- a/mods/kurly/time.js +++ /dev/null @@ -1,8 +0,0 @@ -var pad = require('../formats/pad') - -module.exports = function(){ - return function(rec) { - return pad(rec.time.getHours().toString(), 2, '0', pad.LEFT) + ':' + - pad(rec.time.getMinutes().toString(), 2, '0', pad.LEFT) - } -} \ No newline at end of file diff --git a/mods/levels/index.js b/mods/levels/index.js index 5cafc91..0a2c49c 100644 --- a/mods/levels/index.js +++ b/mods/levels/index.js @@ -1,7 +1,7 @@ module.exports = { use: [ require('../props'), - require('../outputs'), + require('../channels'), ], settings: { @@ -26,22 +26,17 @@ module.exports = { return Math.max(ulog.get('debug', this.name) && this.DEBUG || this.NONE, v) }, }, - } + }, }, ext: function(logger) { logger.NONE = 0 - logger.ALL = 9007199254740991 // Number.MAX_SAFE_INTEGER - logger.levels = ['none'] - for (var name in this.levels) { - logger[name.toUpperCase()] = this.levels[name] - logger.levels[this.levels[name]] = name - } - logger.enabledFor = function(name){ - return logger.level >= logger[name.toUpperCase()] + logger.ALL = 7 + for (var level in this.levels) { + logger[level.toUpperCase()] = this.levels[level] } - for (var name in this.levels) { - if (!logger.enabledFor(name)) logger[name] = logger.discard + logger.enabledFor = function(level){ + return logger.level >= logger[level.toUpperCase()] } }, } diff --git a/mods/levels/test.js b/mods/levels/test.js index b4cfd32..f2c8d15 100644 --- a/mods/levels/test.js +++ b/mods/levels/test.js @@ -15,7 +15,7 @@ test('mod: levels', function (t) { t.equal(typeof levels.ext, 'function', 'has a method `ext()') t.test('levels.use', function(t){ - t.deepEqual(levels.use, [ props, outputs ], 'contains dependencies on `props` and `outputs`') +// t.deepEqual(levels.use, [ outputs ], 'contains a dependency on `outputs`') t.end() }) @@ -38,9 +38,9 @@ test('mod: levels', function (t) { var prop = lvl.toUpperCase() t.equal(logger[prop], ulog.levels[lvl], 'creates a property `' + prop + '`') } - t.equal(logger.ALL, Number.MAX_SAFE_INTEGER, 'creates a property `ALL`') - t.equal(logger.log, logger.discard, 'log methods that are outside the logger\'s level lead to the drain') - t.notEqual(logger.error, logger.noop, 'log methods that are within the logger\'s level do not lead to the drain') + t.equal(logger.ALL, 7, 'creates a property `ALL`') + t.equal(logger.error, logger.channels.output.fns.error, 'log methods that are within the logger\'s level lead to output') + t.equal(logger.log, logger.channels.drain.fns.log, 'log methods that are outside the logger\'s level lead to the drain') ulog.mods.splice(0, ulog.mods.length) delete ulog().test diff --git a/mods/options/index.js b/mods/options/index.js index 16a8863..bfa5dc5 100644 --- a/mods/options/index.js +++ b/mods/options/index.js @@ -35,8 +35,7 @@ var options = module.exports = { * `ulog.get('level', '') == 'info'` */ get: function(result, name, loggerName) { - if (loggerName === undefined) return result - return options.eval(options.parse(result, name), loggerName) + return (loggerName === undefined) ? result : options.eval(options.parse(result, name), loggerName) }, /** diff --git a/mods/outputs/index.js b/mods/outputs/index.js index 2bed3cb..7dff985 100644 --- a/mods/outputs/index.js +++ b/mods/outputs/index.js @@ -1,40 +1,62 @@ -// var ulog = require('../../core') +var parse = require('kurly/parse') +var pipe = require('kurly/pipe') var grab = require('../../core/grab') -var props = require('../props') +var console = require('../channels/console') +var method = require('../channels/method') +const noop = require('../channels/noop') +/** + * mod: outputs + * + * Makes the outputs of logger channels configurable via props + */ module.exports = { use: [ - props, + require('../props'), + require('../channels'), ], - settings: { + // adds a collection of outputs + // an output is either an object with `log()`, `info()`, `warn()` etc methods, + // or a kurly tag + outputs: { + console: console, + noop: noop, + }, + // adds 'output' and `drain` props to configure the output of these channels + settings: { output: { config: 'log_output', prop: { default: 'console', - } + }, }, - drain: { config: 'log_drain', prop: { - default: 'drain', - } + default: 'noop', + }, }, }, - outputs: { - drain: { log: function(){} }, - console: typeof console !== 'undefined' && console, - }, - - ext: function(logger) { - var outputs = grab(this, 'outputs', {}) - var output = outputs[logger.output] || outputs.drain - for (var name in this.levels) { - logger[name] = output[name] || output.log - } - logger.discard = (outputs[logger.drain] || outputs.drain).log + // override the channel output constructor to take logger props into account + channelOutput: function(logger, ch){ + if (! (ch.cfg = logger[ch.name])) return + ch.outputs = grab(this, 'outputs', {}) + var ast = parse(ch.cfg, { optional: true }) + .filter(function(node){return typeof node == 'object'}) + var outs = pipe(ast, ch.outputs) + .map(function(node){return node.tag}) + return ( + outs.length === 0 ? 0 : + (outs.length === 1) && (typeof outs[0] == 'object') ? outs[0] : + function(rec) { + for (var i=0,out; out=outs[i]; i++) { + if (typeof out == 'function') out(rec) + else method(out, rec).apply(out, rec.message) + } + } + ) }, } diff --git a/mods/props/boolean.js b/mods/props/boolean.js new file mode 100644 index 0000000..6525afa --- /dev/null +++ b/mods/props/boolean.js @@ -0,0 +1,11 @@ +var merge = require('../../core/merge') + +module.exports = function(prop) { + var result = { + default: 'on', + fromStr: function(v){return v=='on' || v=='yes' || v=='true' || v=='enabled'}, + toStr: function(v){return v ? 'on' : 'off'} + } + merge(result, prop) + return result +} diff --git a/mods/props/index.js b/mods/props/index.js index 8a87d90..30645b7 100644 --- a/mods/props/index.js +++ b/mods/props/index.js @@ -29,6 +29,17 @@ var props = module.exports = { } }, + + // contribute props to log records + record: function(logger, rec) { + var settings = grab(this, 'settings', {}) + for (var name in settings) { + if (settings[name].prop) { + rec['log_' + name] = this.get(name, logger.name) + } + } + }, + /** * `new(logger, name, prop)` * diff --git a/mods/settings/index.js b/mods/settings/index.js index 2bb5085..edd10bf 100644 --- a/mods/settings/index.js +++ b/mods/settings/index.js @@ -1,4 +1,4 @@ -var grab = require("../../core/grab") +var grab = require('../../core/grab') module.exports = { extend: { diff --git a/mods/test.js b/mods/test.js index 23f07bb..a8efd27 100644 --- a/mods/test.js +++ b/mods/test.js @@ -2,6 +2,6 @@ require('./settings/test') require('./config/test'), require('./options/test') require('./props/test') -require('./outputs/test'), -require('./formats/test'), +// require('./outputs/test'), +// require('./formats/test'), require('./levels/test') diff --git a/package-lock.json b/package-lock.json index 731ea48..c6be342 100644 --- a/package-lock.json +++ b/package-lock.json @@ -339,9 +339,9 @@ } }, "@types/estree": { - "version": "0.0.45", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.45.tgz", - "integrity": "sha512-jnqIUKDUqJbDIUxm0Uj7bnlMnRm1T/eZ9N+AVMqhPgzrba2GhGG5o/jCTwmdPK709nEZsGoMzXEDUjcXHa3W0g==", + "version": "0.0.46", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.46.tgz", + "integrity": "sha512-laIjwTQaD+5DukBZaygQ79K1Z0jb1bPEMRrkXSLjtCcZm+abyp5YbrqpSLzD42FwWW6gK/aS4NYpJ804nG2brg==", "dev": true }, "@types/json-schema": { @@ -503,24 +503,24 @@ } }, "@webpack-cli/configtest": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-1.0.0.tgz", - "integrity": "sha512-Un0SdBoN1h4ACnIO7EiCjWuyhNI0Jl96JC+63q6xi4HDUYRZn8Auluea9D+v9NWKc5J4sICVEltdBaVjLX39xw==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-1.0.1.tgz", + "integrity": "sha512-B+4uBUYhpzDXmwuo3V9yBH6cISwxEI4J+NO5ggDaGEEHb0osY/R7MzeKc0bHURXQuZjMM4qD+bSJCKIuI3eNBQ==", "dev": true }, "@webpack-cli/info": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-1.2.1.tgz", - "integrity": "sha512-fLnDML5HZ5AEKzHul8xLAksoKN2cibu6MgonkUj8R9V7bbeVRkd1XbGEGWrAUNYHbX1jcqCsDEpBviE5StPMzQ==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-1.2.2.tgz", + "integrity": "sha512-5U9kUJHnwU+FhKH4PWGZuBC1hTEPYyxGSL5jjoBI96Gx8qcYJGOikpiIpFoTq8mmgX3im2zAo2wanv/alD74KQ==", "dev": true, "requires": { "envinfo": "^7.7.3" } }, "@webpack-cli/serve": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.2.2.tgz", - "integrity": "sha512-03GkWxcgFfm8+WIwcsqJb9agrSDNDDoxaNnexPnCCexP5SCE4IgFd9lNpSy+K2nFqVMpgTFw6SwbmVAVTndVew==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.3.0.tgz", + "integrity": "sha512-k2p2VrONcYVX1wRRrf0f3X2VGltLWcv+JzXRBDmvCxGlCeESx4OXw91TsWeKOkp784uNoVQo313vxJFHXPPwfw==", "dev": true }, "@xtuc/ieee754": { @@ -536,9 +536,9 @@ "dev": true }, "acorn": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.0.4.tgz", - "integrity": "sha512-XNP0PqF1XD19ZlLKvB7cMmnZswW4C/03pRHgirB30uSJTaS3A3V1/P4sS3HPvFmjoriPCJQs+JDSbm4bL1TxGQ==", + "version": "8.0.5", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.0.5.tgz", + "integrity": "sha512-v+DieK/HJkJOpFBETDJioequtc3PfxsWMaxIdIwujtF7FEV/MAyDQLlm6/zPvr7Mix07mLh6ccVwIsloceodlg==", "dev": true }, "aggregate-error": { @@ -591,9 +591,9 @@ } }, "anylogger": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/anylogger/-/anylogger-1.0.9.tgz", - "integrity": "sha512-0dBWCjGzCbptcdKwGd2vHE5AGi44wIPSOWULwfqeUaoxs/YKQoMrpOeMBw5mh5fbmoXnTIxWhtGSclTdnC2VYQ==" + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/anylogger/-/anylogger-1.0.10.tgz", + "integrity": "sha512-iZsA9nnDpeS6A19W6LcOKqAxk2pbc93rOl4KnfOItmqdvVktv1rNqqOsY7I2j8wjt0slmGnInapKnfmKAifFDw==" }, "append-transform": { "version": "2.0.0", @@ -651,16 +651,16 @@ } }, "browserslist": { - "version": "4.16.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.1.tgz", - "integrity": "sha512-UXhDrwqsNcpTYJBTZsbGATDxZbiVDsx6UjpmRUmtnP10pr8wAYr5LgFoEFw9ixriQH2mv/NX2SfGzE/o8GndLA==", + "version": "4.16.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.3.tgz", + "integrity": "sha512-vIyhWmIkULaq04Gt93txdh+j02yX/JzlyhLYbV3YQCn/zvES3JnY7TifHHvvr1w5hTDluNKMkV05cs4vy8Q7sw==", "dev": true, "requires": { - "caniuse-lite": "^1.0.30001173", + "caniuse-lite": "^1.0.30001181", "colorette": "^1.2.1", - "electron-to-chromium": "^1.3.634", + "electron-to-chromium": "^1.3.649", "escalade": "^3.1.1", - "node-releases": "^1.1.69" + "node-releases": "^1.1.70" } }, "buffer-from": { @@ -704,9 +704,9 @@ "dev": true }, "caniuse-lite": { - "version": "1.0.30001179", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001179.tgz", - "integrity": "sha512-blMmO0QQujuUWZKyVrD1msR4WNDAqb/UPO1Sw2WWsQ7deoM5bJiicKnWJ1Y0NS/aGINSnKPIWBMw5luX+NDUCA==", + "version": "1.0.30001183", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001183.tgz", + "integrity": "sha512-7JkwTEE1hlRKETbCFd8HDZeLiQIUcl8rC6JgNjvHCNaxOeNmQ9V4LvQXRUsKIV2CC73qKxljwVhToaA3kLRqTw==", "dev": true }, "chalk": { @@ -914,9 +914,9 @@ "dev": true }, "electron-to-chromium": { - "version": "1.3.642", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.642.tgz", - "integrity": "sha512-cev+jOrz/Zm1i+Yh334Hed6lQVOkkemk2wRozfMF4MtTR7pxf3r3L5Rbd7uX1zMcEqVJ7alJBnJL7+JffkC6FQ==", + "version": "1.3.653", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.653.tgz", + "integrity": "sha512-LehOhcl74u9fkV9Un6WahJ+Xh+0FZLCCDnKYis1Olx1DX2ugRww5PJicE65OG8yznMj8EOQZRcz6FSV1xKxqsA==", "dev": true }, "emoji-regex": { @@ -945,9 +945,9 @@ } }, "envinfo": { - "version": "7.7.3", - "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.7.3.tgz", - "integrity": "sha512-46+j5QxbPWza0PB1i15nZx0xQ4I/EfQxg9J8Had3b408SV63nEtor2e+oiY63amTo9KTuh2a3XLObNwduxYwwA==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.7.4.tgz", + "integrity": "sha512-TQXTYFVVwwluWSFis6K2XKxgrD22jEv0FTuLCQI+OjH7rn93+iY0fSSFM5lrSxFY+H1+B0/cvvlamr3UsBivdQ==", "dev": true }, "es-abstract": { @@ -1253,13 +1253,20 @@ "dev": true }, "gzip-size": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-5.1.1.tgz", - "integrity": "sha512-FNHi6mmoHvs1mxZAds4PpdCS6QG8B4C1krxJsMutgxl5t3+GlRTzzI3NEkifXx2pVsOvJdOGSmIgDhQ55FwdPA==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-6.0.0.tgz", + "integrity": "sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==", "dev": true, "requires": { - "duplexer": "^0.1.1", - "pify": "^4.0.1" + "duplexer": "^0.1.2" + }, + "dependencies": { + "duplexer": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", + "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", + "dev": true + } } }, "has": { @@ -1733,18 +1740,11 @@ "dev": true }, "kurly": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/kurly/-/kurly-1.0.1.tgz", - "integrity": "sha512-w+WMQ9KdyUqUAw6g25lbnUkA/5q+LZtYzRWzP2Qb6bd8IQoOWmG13WJnXBJOl8JgHxfGH9+PAof6gO/fK7sQXA==", + "version": "2.0.0-beta.2", + "resolved": "https://registry.npmjs.org/kurly/-/kurly-2.0.0-beta.2.tgz", + "integrity": "sha512-AysNnS/Us6r/8qAV372KqALtXXLfQZyRyiVzxUsBFpNFunk2rg1pY6i8xUiS5+JAZNJKuhehj4+9TExMUPl6+w==", "requires": { "anylogger": "^1.0.10" - }, - "dependencies": { - "anylogger": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/anylogger/-/anylogger-1.0.10.tgz", - "integrity": "sha512-iZsA9nnDpeS6A19W6LcOKqAxk2pbc93rOl4KnfOItmqdvVktv1rNqqOsY7I2j8wjt0slmGnInapKnfmKAifFDw==" - } } }, "loader-runner": { @@ -2071,12 +2071,6 @@ } } }, - "pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true - }, "pkg-dir": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", @@ -2322,14 +2316,14 @@ "dev": true }, "sinon": { - "version": "9.2.3", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-9.2.3.tgz", - "integrity": "sha512-m+DyAWvqVHZtjnjX/nuShasykFeiZ+nPuEfD4G3gpvKGkXRhkF/6NSt2qN2FjZhfrcHXFzUzI+NLnk+42fnLEw==", + "version": "9.2.4", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-9.2.4.tgz", + "integrity": "sha512-zljcULZQsJxVra28qIAL6ow1Z9tpattkCTEJR4RBP3TGc00FcttsP5pK284Nas5WjMZU5Yzy3kAIp3B3KRf5Yg==", "dev": true, "requires": { "@sinonjs/commons": "^1.8.1", "@sinonjs/fake-timers": "^6.0.1", - "@sinonjs/samsam": "^5.3.0", + "@sinonjs/samsam": "^5.3.1", "diff": "^4.0.2", "nise": "^4.0.4", "supports-color": "^7.1.0" @@ -2923,13 +2917,13 @@ } }, "webpack": { - "version": "5.16.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.16.0.tgz", - "integrity": "sha512-QOkctcjYfEGxcYg4AzPJafyAQ7ANc266/URkX881uFA7b2k31E0Dmpy1ExfppHOTp1kHDTsRh9sXojVUvgPF0g==", + "version": "5.20.1", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.20.1.tgz", + "integrity": "sha512-cStILc8W14WZXsgfeJmNIQlmQU06F7THfCJ6id3pIB/EXuR6nquolJ2ZJoaLNb6zdec6O2jOAzVKtBYc7vGDjg==", "dev": true, "requires": { "@types/eslint-scope": "^3.7.0", - "@types/estree": "^0.0.45", + "@types/estree": "^0.0.46", "@webassemblyjs/ast": "1.11.0", "@webassemblyjs/wasm-edit": "1.11.0", "@webassemblyjs/wasm-parser": "1.11.0", @@ -2946,74 +2940,25 @@ "loader-runner": "^4.2.0", "mime-types": "^2.1.27", "neo-async": "^2.6.2", - "pkg-dir": "^5.0.0", "schema-utils": "^3.0.0", "tapable": "^2.1.1", "terser-webpack-plugin": "^5.1.1", "watchpack": "^2.0.0", "webpack-sources": "^2.1.1" - }, - "dependencies": { - "find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "requires": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - } - }, - "locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "requires": { - "p-locate": "^5.0.0" - } - }, - "p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "requires": { - "yocto-queue": "^0.1.0" - } - }, - "p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "requires": { - "p-limit": "^3.0.2" - } - }, - "pkg-dir": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-5.0.0.tgz", - "integrity": "sha512-NPE8TDbzl/3YQYY7CSS228s3g2ollTFnc+Qi3tqmqJp9Vg2ovUpixcJEo2HJScN2Ez+kEaal6y70c0ehqJBJeA==", - "dev": true, - "requires": { - "find-up": "^5.0.0" - } - } } }, "webpack-cli": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-4.4.0.tgz", - "integrity": "sha512-/Qh07CXfXEkMu5S8wEpjuaw2Zj/CC0hf/qbTDp6N8N7JjdGuaOjZ7kttz+zhuJO/J5m7alQEhNk9lsc4rC6xgQ==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-4.5.0.tgz", + "integrity": "sha512-wXg/ef6Ibstl2f50mnkcHblRPN/P9J4Nlod5Hg9HGFgSeF8rsqDGHJeVe4aR26q9l62TUJi6vmvC2Qz96YJw1Q==", "dev": true, "requires": { "@discoveryjs/json-ext": "^0.5.0", - "@webpack-cli/configtest": "^1.0.0", - "@webpack-cli/info": "^1.2.1", - "@webpack-cli/serve": "^1.2.2", + "@webpack-cli/configtest": "^1.0.1", + "@webpack-cli/info": "^1.2.2", + "@webpack-cli/serve": "^1.3.0", "colorette": "^1.2.1", - "commander": "^6.2.0", + "commander": "^7.0.0", "enquirer": "^2.3.6", "execa": "^5.0.0", "fastest-levenshtein": "^1.0.12", @@ -3025,9 +2970,9 @@ }, "dependencies": { "commander": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", - "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.0.0.tgz", + "integrity": "sha512-ovx/7NkTrnPuIV8sqk/GjUIIM1+iUQeqA3ye2VNpq9sVoiZsooObWlQy+OPWGI17GDaEoybuAGJm6U8yC077BA==", "dev": true } } diff --git a/package.json b/package.json index 865119b..186d471 100644 --- a/package.json +++ b/package.json @@ -1,59 +1,73 @@ { "name": "ulog", - "version": "2.0.0-beta.11", + "version": "2.0.0-beta.12", "description": "The universal logger", "main": "./ulog.js", - "browser": { - "./mods/config/args.js": "./mods/config/args.browser.js", - "./mods/config/env.js": "./mods/config/env.browser.js", - "./mods/config/read.js": "./mods/config/read.browser.js", - "./mods/config/watch.js": "./mods/config/watch.browser.js", - "./mods/levels/default.js": "./mods/levels/default.browser.js", - "./mods/formats/simple.js": "./mods/formats/simple.browser.js" - }, "unpkg": "ulog.min.js", + "author": "Stijn de Witt", + "license": "MIT", + "repository": { + "type": "git", + "url": "git+https://github.com/download/ulog.git" + }, "files": [ "core", "mods", + "base.js", "build.js", - "example.js", - "full.js", "full.bundle.js", "full.min.js", - "LICENSE", - "ulog.js", "ulog.bundle.js", + "ulog.js", + "ulog.lazy.min.js", "ulog.min.js", "screenshot.jpg", - "test.js", - "tutorial.html", "ulog.png", "webpack.config.js" ], + "browser": { + "./mods/align/utils.js": "./mods/align/utils.browser.js", + "./mods/colors/utils.js": "./mods/colors/utils.browser.js", + "./mods/config/args.js": "./mods/config/args.browser.js", + "./mods/config/env.js": "./mods/config/env.browser.js", + "./mods/config/read.js": "./mods/config/read.browser.js", + "./mods/config/watch.js": "./mods/config/watch.browser.js", + "./mods/levels/default.js": "./mods/levels/default.browser.js", + "./mods/formats/aligned.js": "./mods/formats/aligned.browser.js", + "./mods/formats/default.js": "./mods/formats/default.browser.js", + "./mods/formats/utils.js": "./mods/formats/utils.browser.js" + }, + "keywords": [ + "log", + "logging", + "console", + "debug", + "loglevel", + "anylogger", + "ulog" + ], "scripts": { "build": "webpack --mode production && node ./build.js", "clean": "rimraf ulog.min.js test.min.js", "test": "nyc tape test.js 2>&1 | tap-nirvana", "prepare": "npm run test -S && npm run clean -S && npm run build -S" }, - "author": "", - "license": "MIT", "dependencies": { - "anylogger": "^1.0.9", - "kurly": "^1.0.1" + "anylogger": "^1.0.10", + "kurly": "^2.0.0-beta.2" }, "devDependencies": { - "gzip-size": "^5.1.1", + "gzip-size": "^6.0.0", "nyc": "^15.1.0", "rimraf": "^3.0.2", - "sinon": "^9.2.3", + "sinon": "^9.2.4", "tap-nirvana": "^1.1.0", "tap-spec": "^5.0.0", "tape": "^5.1.1", - "webpack": "^5.16.0", - "webpack-cli": "^4.4.0" + "webpack": "^5.20.1", + "webpack-cli": "^4.5.0" }, "peerDependencies": { - "anylogger": "^1.0.9" + "anylogger": "^1.0.10" } } diff --git a/screenshot.jpg b/screenshot.jpg index 25499e3aca6b0abb2558c42f31342635a1ec4912..839587042c3e7a73fd491939918cf411f5af8a40 100644 GIT binary patch literal 109281 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 `Nnmo=*Y>qppW@wAVmy~whE%lE2e9zmTXW?k< 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 QG@ECnRN@$>`k%G`4@PrsH~;_u literal 69258 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Թ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 ulog - +