Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

anylogger

Package Overview
Dependencies
Maintainers
1
Versions
40
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

anylogger - npm Package Compare versions

Comparing version 0.5.0 to 0.6.0

70

any.js

@@ -0,1 +1,10 @@

/**
* A N Y L O G G E R
* Get a logger. Any logger.
*
* © 2019 by Stijn de Witt, some rights reserved
* Licensed under the MIT Open Source license
* https://opensource.org/licenses/MIT
* Removal of this message in production builds is permitted.
*/
(function(m,a){

@@ -8,3 +17,3 @@ // stores log modules keyed by name

*
* The main anylogger function creates a new or returns an existing logger
* The main `anylogger` function creates a new or returns an existing logger
* with the given `name`. It maintains a registry of all created loggers,

@@ -15,3 +24,3 @@ * which it returns when called without a name, or with an empty name.

*/
a = module.exports = function(n,o){
a = function(n,o){
// return the existing logger, or create a new one. if no name was given, return all loggers

@@ -26,15 +35,16 @@ return n ? m[n] || (m[n] = a.create(n,o)) : m

*
* The lowest level of logging (none at all) has value `0`, whereas the highest
* level of logging is named `trace` and has value `60`. Default log levels
* are spaced out by 10 units each so to make room for additional log levels
* in between.
* The lowest level of logging (none at all) has value `0`. Higher levels have
* higher values. To be compliant with the anylogger API, loggers should support
* at least the default levels, but they may define additional levels.
*/
a.levels = {error:10, warn:20, info:30, log:40, debug:50, trace:60}
a.levels = {error:1, warn:2, info:3, log:4, debug:5, trace:6}
/**
* The anylogger console, defaults to the native console, or undefined.
* The anylogger console.
*
* This object is used to perform the actual logging. If it is undefined, the
* Defaults to the native console or false if no native console is available.
*
* This object is used to perform the actual logging. If it is false, the
* log methods on the logger will all be noop methods.
*
*
* The anylogger console may be overridden by a different object to intercept

@@ -45,24 +55,32 @@ * individual logging calls. For example this property could be overridden

* When a method is not available on the anylogger console, but
* `anylogger.con.log` is defined, `anylogger.con.log` will be used. So you
* `anylogger.out.log` is defined, `anylogger.out.log` will be used. So you
* can define a level `silly` and it will create a method `silly()` which is
* an alias for `anylogger.con.log`.
* an alias for `anylogger.out.log`.
*/
a.con = (typeof console != 'undefined') && console
a.out = typeof console != 'undefined' && console
/**
* Returns the logger with the given name, or creates it by calling `anylogger.new`
* and extending the created log function by calling `anylogger.ext` on the result.
* Called when a logger needs to be created.
*
* You can replace this method with a custom factory, or leave this one in place
* and instead override `anylogger.ext` and/or `anylogger.new` separately.
* `anylogger.create(name, options)`
*
* Creates a new logger by calling `anylogger.new`, then extends it by calling
* `anylogger.ext` on the result.
*
* You can replace this method with a custom factory, or leave this one in
* place and instead override `anylogger.ext` and/or `anylogger.new` separately.
*
* @param name String, The name of the logger to create
* @param options Object, An optional options object
*
* @returns A new logger with the given `name` and `options`.
*/
a.create = function(n,o) {
return a.ext(a.new(n),n,o)
return a.ext(a.new(n,o))
}
/**
* Called when a logger needs to be created.
*
* `anylogger.new(name)`
* `anylogger.new(name, options)`
*

@@ -73,6 +91,8 @@ * Creates and returns a new named function that calls `anylogger.log` to

*
* @param n String The name of the logger to create
* @param name String The name of the logger to create
* @param options Object An optional options object
*
* @return function log([level='log'], args...)
*/
a.new = function(n,r) {
a.new = function(n,o,r) {
// use eval to create a named function, this method has best cross-browser

@@ -108,3 +128,3 @@ // support and allows us to create functions with names containing symbols

*
* `anylogger.ext(logger, name, options) => logger`
* `anylogger.ext(logger) => logger`
*

@@ -119,5 +139,7 @@ * This method must ensure that a log method is available on the logger for

for (v in a.levels)
l[v] = a.con[v] || a.con.log || function(){}
l[v] = a.out[v] || a.out.log || function(){}
return l;
}
module.exports = a
})()

@@ -1,1 +0,1 @@

!function(m,a){m=Object.create(null),a=window.anylogger=function(n,e){return n?m[n]||(m[n]=a.create(n,e)):m},a.levels={error:10,warn:20,info:30,log:40,debug:50,trace:60},a.con="undefined"!=typeof console&&console,a.create=function(n,e){return a.ext(a.new(n),n,e)},a.new=function(n,r){return eval("r = {'"+n+"': function(){a.log(n, [].slice.call(arguments))}}[n]"),r.name?r:Object.defineProperty(r,"name",{get:function(){return n}})},a.log=function(n,e){m[n][1<e.length&&a.levels[e[0]]?e.shift():"log"].apply(m[n],e)},a.ext=function(n){for(v in a.levels)n[v]=a.con[v]||a.con.log||function(){};return n}}();
!function(m,a){m=Object.create(null),a=function(n,e){return n?m[n]||(m[n]=a.create(n,e)):m},a.levels={error:1,warn:2,info:3,log:4,debug:5,trace:6},a.out="undefined"!=typeof console&&console,a.create=function(n,e){return a.ext(a.new(n,e))},a.new=function(n,o,r){return eval("r = {'"+n+"': function(){a.log(n, [].slice.call(arguments))}}[n]"),r.name?r:Object.defineProperty(r,"name",{get:function(){return n}})},a.log=function(n,e){m[n][1<e.length&&a.levels[e[0]]?e.shift():"log"].apply(m[n],e)},a.ext=function(n){for(v in a.levels)n[v]=a.out[v]||a.out.log||function(){};return n},window.anylogger=a}();
{
"name": "anylogger",
"version": "0.5.0",
"version": "0.6.0",
"description": "Get a logger. Any logger.",

@@ -5,0 +5,0 @@ "main": "any.js",

@@ -1,2 +0,2 @@

# anylogger <sub><sup>v0.5.0</sup></sub>
# anylogger <sub><sup>v0.6.0</sup></sub>
### Get a logger. Any logger.

@@ -12,14 +12,21 @@

Get whatever logging framework is present in the host project, or a wrapper
around the console, or a dummy. Anything really, that will let your library
do logging without you having to decide what logging framework the app using
your library should use.
## A logger for libraries
Get whatever logging framework the host project is using, or a wrapper around
the console, or a dummy log object that does nothing. Anything really, that
will let your library do logging without you having to decide what logging
framework the app using your library should use.
Anylogger will let the user of your library pick the logger for his app, and
will let your library pick up on whatever choice he made and run with it.
By choosing anylogger, you are explicitly not choosing any specific logging
framework, but instead are limiting yourself to the
[Anylogger API](#anylogger-api), a small API that only captures the bare
essentials for logging, but because of that, is compatible with nearly every
logging library out there.
## What is this?
**A logging facade.**
**A logging facade**

@@ -50,7 +57,7 @@ We, the Javascript community, really need a logging facade. Initially, the

`anylogger` and for just 0.5 kB shared between all libraries doing this, we can
plug in any framework of our choice and all of them will automatically start to
use that framework. Wouldn't it be much better and easier?
plug in any framework of our choice and all libraries will automatically
start to use that framework. Wouldn't it be much better and easier?
At the application level, the app developer chooses their logging framework
of choice and installs the anylogger-to-their-framework adapter. They make
At the application level, the app developers choose whatever logging framework
they prefer and install the anylogger-to-their-framework adapter. They make
sure to require the adapter in the application entry point and from that point

@@ -63,4 +70,4 @@ on, any library using anylogger will automatically start using the selected

* [any.js](https://unpkg.com/anylogger@0.5.0/any.js) (fully commented source ~5kB)
* [any.min.js](https://unpkg.com/anylogger@0.5.0/any.min.js) (minified and gzipped ~0.5 kB)
* [any.js](https://unpkg.com/anylogger@0.6.0/any.js) (fully commented source ~5kB)
* [any.min.js](https://unpkg.com/anylogger@0.6.0/any.min.js) (minified and gzipped ~0.5 kB)

@@ -72,3 +79,3 @@

```html
<script src="https://unpkg.com/anylogger@0.5.0/any.min.js"></script>
<script src="https://unpkg.com/anylogger@0.6.0/any.min.js"></script>
<script>(function(){ // IIFE

@@ -93,4 +100,43 @@ var log = anylogger('index.html')

Done.
This will add `anylogger` as a dependency to your `package.json`:
```json
{
"dependencies": {
"anylogger": ">= 0.6.0 < 2"
}
}
```
I recommend to expand the version range here. By default NPM will set a
range looking like `"^0.6.0"`, which is equivalent to `"0.6.x"` or
`">= 0.6.0 < 0.7.0"`. This version range is probably too narrow. When
multiple libraries depend on the same library, if their version ranges overlap,
NPM will be able to make them all use the same version. But if their version
ranges do not overlap, NPM will bundle multiple versions of the same library.
So ideally we make sure version ranges always overlap. To that end, this
project will be very conservative towards any code changes and will take 2
major versions for any compatibility breaking changes; in the first major
version, deprecation notices will be added but stuff will still work.
In the next major version, the change will be implemented. So if your code is
working without any deprecation notices, it should continue to work with all
upcoming versions including the next major, up to (but not including) the
second next major.
So I recommend accepting everything up to the second next major release.
That means that currently while at version `0.6.0`, we should set the version
range to everything equal to or above `0.6.0` and below `2.0.0`:
```json
{
"dependencies": {
"anylogger": ">= 0.6.0 < 2.0.0"
}
}
```
This should minimize our chances of getting multiple conflicting versions
added to our app.
### Install in an application project

@@ -107,2 +153,8 @@ If you are building an application project and have selected a logging

> Changing the version range here is less important as NPM install will
> install the latest version by default, and this project will not be
> used within other projects anyway. As long as the version ranges of the
> libraries the project is using cover the currently installed version,
> everything should work out fine.
or, for [ulog](https://npmjs.com/package/ulog):

@@ -123,3 +175,4 @@

### Include in a library
In your libraries, only use anylogger, to stay framework-independent:
In your libraries, only use anylogger and restrict yourself to the
[Anylogger API](#anylogger-api) to stay framework-independent:

@@ -139,2 +192,3 @@ ### require

### Include in an application project

@@ -156,3 +210,4 @@

In your modules, use only anylogger to stay framework-independant:
In your other modules, use only anylogger and restrict yourself to the
[Anylogger API](#anylogger-api) to stay framework-independent:

@@ -172,2 +227,3 @@ ### require

## Using anylogger

@@ -187,2 +243,13 @@

If you are able to restrict yourself to the [Anylogger API](#anylogger-api),
your code will be framework independent and will work with any logger.
```js
log.info('Logging is easy!')
// Avoid using methods like log.silly() and log.time() etc which are only
// supported in some frameworks and not in others and your code will work
// with any supported logging framework without any changes
```
## Anylogger API

@@ -195,8 +262,7 @@

```js
function anylogger(name, options)
function anylogger(name, options) => logger
```
The main function to call to get a logger.
Returns a logger based on two arguments, both of
which are optional.
Accepts two arguments.

@@ -209,3 +275,5 @@ #### name

used by the highly popular `debug` module. But you are free to pick any name
you want. You only get a logger if you supply a name.
you want. You only get a logger if you supply a name. If the name is
not given `anylogger()` will return an object containing all loggers,
keyed by name.

@@ -231,7 +299,8 @@ #### options

The logger returned by `anylogger` is a function that can do logging on it's own:
The logger returned by `anylogger` is a function that can do logging on it's
own:
```js
log('message') // logs a message at debug level
log('info', 'message') // logs a message at info level
log('message') // logs a message at `log` level
log('info', 'message') // logs a message at `info` level
```

@@ -261,29 +330,27 @@

And that's about it. However this covers the basic logging needs for most
logging libraries, while at the same time leaving the details surrounding
configuration to be decided upon by specific implementations.
And that's about it. However this covers the basic logging needs.
In fact, in most cases you should be able to replace the library you are
currently using with anylogger without many changes to your code, if any.
> Note that all logging methods here are part of the upcoming
> [Console standard](https://console.spec.whatwg.org/), but not all platforms
> and frameworks support all of them. In particular the `debug` method is not
> available everywhere. Anylogger will make sure that the `debug` function is
> polyfilled if needed.
Note that all logging methods here are part of the default [console API](https://developer.mozilla.org/en-US/docs/Web/API/Console) as specified on MDN,
but not all platforms and frameworks support all of them. In particular the `debug`
method is not available everywhere and the `trace` method functions different on
different platforms. On Node JS it will print a stacktrace with each message.
Anylogger will make sure that the `debug` function is polyfilled if needed, but it
does not attempt to change the actual implementation of any method.
## Write an anylogger adapter
To write an anylogger adapter, you need to make a project that includes both anylogger
and the logging framework the adapter is for as peer dependencies. It then needs to
modify one or more of the [anylogger extension points](#anylogger-extension-points)
so the created loggers will be compliant with both the anylogger [Logging API](#logging-api)
as well as with the logging framework's own API.
To write an anylogger adapter, you need to make a project that includes both
anylogger and the logging framework the adapter is for as peer dependencies.
Again, make sure to choose a wide version range; 2 major versions is
recommended.
It is recommended you call your library `anylogger-adapter`, where `adapter`
should be replaced with the name of the logging framework the adapter is for.
For example, the adapter for `ulog` is called `anylogger-ulog`.
You then need to modify one or more of the
[anylogger extension points](#anylogger-extension-points)
so the created loggers will be compliant with both the anylogger
[Logging API](#logging-api) as well as with the logging framework's own API.
It is recommended you call your library `anylogger-[adapter]`, where
`[adapter]` should be replaced with the name of the logging framework the
adapter is for. For example, the adapter for `ulog` is called `anylogger-ulog`.
In addition, it is recommended you add the keyword `"anylogger"` to the

@@ -301,9 +368,9 @@ *package.json* file of your adapter project, so it will show up in the list of

An object describing log levels, keyed by name.
You can replace or amend this object to include levels corresponding with
You can replace or change this object to include levels corresponding with
those available in the framework you are writing an adapter for. Please
make sure to always include the existing levels as well so all code can
make sure to always include the default levels as well so all code can
rely on the 6 console methods `error`, `warn`, `info`, `log`, `debug` and
`trace` to always be there.
#### anylogger.con
#### anylogger.out
An object (defaults to the native `console`, or `undefined`) containing the

@@ -316,19 +383,43 @@ log methods to perform the actual log calls. You can replace this object

#### anylogger.create
A method that is called whenever a new logger is created. Calls `anylogger.new`
and `anylogger.ext`. You can override this method with your own factory, but
it is probably easier to override just `anylogger.ext`.
A method that is called whenever a new logger is created. Calls
`anylogger.new` and `anylogger.ext`. You can override this method
with your own factory, but it is probably easier to override just
`anylogger.new`, chaining the old method.
#### anylogger.new
A method that is called to create the logger function.
If you want to customize the way log invocation is handled, consider overriding
`anylogger.log` instead.
A method that is called to create the logger function. You can chain
this method and include any one-time customizations here:
```js
import anylogger from 'anylogger'
// save the original function
const make = anylogger.new
// override anylogger.new
anylogger.new = function(name, options) {
// call the original function to chain it
var logger = make(name, options)
// add your customizations
logger.myCoolFeature = function(){logger.info('My cool feature!')}
// return the customized logger
return logger
}
```
If you need to re-apply customizations any time relevant config changes (such as
active log level changing), override `anylogger.ext`.
#### anylogger.ext
A method that is called to extend the logger function. It loops over the
`anylogger.levels` and creates log methods for each level.
You can override or chain this method to add additional methods or properties
to the logger. In case of frameworks supporting dynamic log levels, it is
expected that `anylogger.ext` is called again whenever config changes that
might influence the log level. This allows adapters to re-extend the logger
so that the new configuration takes effect.
A method that is called to extend the logger function. The default
implementation loops over the `anylogger.levels` and creates log methods for
each level. You can override or chain this method to change the way the log
methods are (re-)created. By default, all log methods will delegate to the
native console. But in a library that supports log levels, all methods
corresponding to log levels lower than the currently active levels might be
replaced with no-op methods instead. Or maybe the destination of the log
messages might change dynamically based on configuration. Apply such changes
in `anylogger.ext` as it will be called again whenever relevant config
changes. This allows adapters to re-extend the logger so that the new
configuration takes effect.

@@ -339,6 +430,6 @@ #### anylogger.log

through this method. Calls to the log methods, e.g. to `log.info`, are routed
directly to the corresponding method on `any.con`. Hence `any.con` is a better
directly to the corresponding method on `any.out`. Hence `any.out` is a better
extension point when you need to intercept *all* log invocation.
Please have a look at the [source](https://unpkg.com/anylogger@0.5.0/any.js)
Please have a look at the [source](https://unpkg.com/anylogger@0.6.0/any.js)
it should make it more clear how to write an adapter. Also consider studying

@@ -349,2 +440,8 @@ the [available adapters](https://www.npmjs.com/search?q=keywords:anylogger)

## Give something back
If you wrote an `anylogger` adapter, make sure to share it back with the
community. Publish it to NPM for all to use!
## Issues

@@ -358,3 +455,3 @@

Copyright 2019 by [Stijn de Witt](http://StijnDeWitt.com).
Copyright 2019 by [Stijn de Witt](http://StijnDeWitt.com). Some rights reserved.

@@ -364,2 +461,2 @@

Licensed under the MIT Open Source license.
Licensed under the [MIT Open Source license](https://opensource.org/licenses/MIT).
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc