Giter VIP home page Giter VIP logo

logdown.js's Introduction

logdown.js

Travis CI Lib Size Codecov npm

logdown is a debug utility for the browser and the server with Markdown support, providing a single interface and a similar behavior between the browser and the server.

It doesn't have any dependencies for the browser version and it's only 2K gzipped.

You can see it in action in the example page or in the preview below.

Installation

$ npm install --save logdown

Preview

Out-of-the box colors work well on both light and dark themes.

Browser DevTools dark

Browser DevTools light

Node

Usage

logdown exports a function. For the simplest use case, pass the name of your module and it will return a decorated console.

const logdown = require('logdown')
const logger = logdown('foo')

Or in a more idiomatic way:

const logger = require('logdown')('foo')

Just like debug.js and node core's debuglog, the enviroment variable NODE_DEBUG is used to decide which module will print debug information.

$ NODE_DEBUG=foo node example/node.js

The corresponding command for browsers is:

window.localStorage.debug = 'foo'

Multiple comma-separated logger names and wildcards can be specified as well.

With the isEnabled state a specific logger instance can always be enabled, independent of the NODE_DEBUG setting:

const logger = require('logdown')('foo')
logger.state.isEnabled = true
logger.log('I will always log.')

Logging

After creating your object, you can use the regular log, warn, info and error methods as we have on console, but now with Markdown support. If a method is not provided by logdown, it will just delegate to the original console object or opts.logger if passed.

logger.log('lorem *ipsum*')
logger.info('dolor _sit_ amet')
logger.warn('consectetur `adipiscing` elit')

As the native APIs, multiple arguments are supported.

logger.log('lorem', '*ipsum*')
logger.info('dolor _sit_', 'amet')
logger.warn('consectetur', '`adipiscing` elit')

Options

The following options can be used for configuration.

prefix

  • Type: String
const logger = logdown('foo')
logger.log('Lorem ipsum')
var fooBarLogger = logdown('foo:bar')
fooBarLogger.log('Lorem ipsum')

var fooQuzLogger = logdown('foo:quz')
fooQuzLogger.log('Lorem Ipsum')

markdown

  • Type: Boolean
  • Default: true

If setted to false, markdown will not be parsed.

var logger = logdown({ markdown: false })
logger.log('Lorem *ipsum*') // Will not parse the markdown

For Markdown, the following mark-up is supported:

// Bold with "*"" between words
logger.log('lorem *ipsum*')

// Italic with "_" between words
logger.log('lorem _ipsum_')

// Code with "`" (backtick) between words
logger.log('lorem `ipsum`')

prefixColor

  • type: String
  • default: next value after last used on the logdown.prefixColors array.

Hex value for a custom color.

const logger1 = logdown('foo', { prefixColor: '#FF0000' }) // Red prefix
const logger2 = logdown('bar', { prefixColor: '#00FF00' }) // Green prefix
const logger3 = logdown('quz', { prefixColor: '#0000FF' }) // Blue prefix

logger

  • type: 'Object'
  • default: console

Custom logger. On Node it's possible to instantiate a new console setting it's output to a different stream other than stdout and stderr.

const output = fs.createWriteStream('./stdout.log');
const errorOutput = fs.createWriteStream('./stderr.log');
const fileLogger =  new console.Console(output, errorOutput)

const logger = logdown('foo', {
  logger: fileLogger
})

plaintext (Node.js only)

  • type: 'Boolean'
  • default: false

This will enable plaintext logging, that means, all objects will be stringified and the logging function will use only one argument (i.e. console.log('[my project] my message') instead of console.log('[my project]', 'my message').).

const logger = logdown('foo', { plaintext: 'true' })

State

isEnabled

  • type: 'Boolean'
  • default: default value is derived from localStorage.debug on browser and from env var NODE_DEBUG on node.

Used to enable/disable a given instance at runtime.

// Prevents `logger` to output debug info
logger.state.isEnabled = false

Enabling/disabling instances

logdown is compatible with Node.js util.debuglog and debug.js as it uses the NODE_DEBUG enviroment variable to control which instances are enabled to output debug info.

For the browser use localStorage.debug.

# Will enable instances with *foo* prefix
NODE_DEBUG=foo node foo.js
// Will enable instances with *foo* prefix
localStorage.debug = 'foo'

Multiple instances should be separated by comma

# Will enable instance with *foo* or *bar* prefix
NODE_DEBUG=foo,bar node foo.js
// Will enable instance with *foo* or *bar* prefix
localStorage.debug = 'foo,bar'

Wildcards

Wildcard * is supported.

# Enables all instances
NODE_DEBUG=* node foo.js

# Enables all instances with a prefix starting with *foo*
NODE_DEBUG=foo* node foo.js

Use - to do a negation.

# Enables all instances but the ones with *foo* prefix
NODE_DEBUG=*,-foo node foo.js

# Enables all intances with foo in the prefix and disable *foobar*
NODE_DEBUG=*foo*,-foobar node foo.js

Additional transports integration

If you'd like to send some part of logs into e.g. sentry or some file. You can extend logdown by adding a transport functions:

logdown.transports = [ transport, transport2, ... ]

logdown.transports is simply an array of functions. You can modify it at runtime in any way you like.

Each transport function will be called with an Object as an argument. The object has the following fields:

  • state: Object — contains the current state object
  • instance: string — the instance name, you've specified, when created a logger instance
  • level: string — the name of the method, that was called (e.g. 'warn' for logger.warn('foo'))
  • args: Array<any> — an array of arguments passed to logging method
  • msg: string — contains a string with instance name and concatenated args (except objects). For logdown('foo')('bar', {quz: 1}, 'baz') it will produce [foo] bar baz

Please note, that transport functions will be called even if the logger.state.isEnabled === false. You must decide inside your transport function whether you want to consider the global isEnabled state.

Example of transport implementation:

function transport({ msg, level, args, state }) {
  if (!state.isEnabled) {
    // We dont care, but we can use this if we want
  }

  const levelMap = {
    warn: 'warning',
    error: 'error'
  }

  if (levelMap[level] && process.env.NODE_ENV === 'production') {
    Raven.captureException(msg, {
      level: levelMap[level],
      extra: args[1]
    })
  }
}

logdown.transports = [ transport ]

Conventions

If you're using this in one or more of your libraries, you should use the name of your library so that developers may toggle debugging as desired without guessing names. If you have more than one debuggers you should prefix them with your library name and use ":" to separate features. For example "bodyParser" from Connect would then be "connect:bodyParser".

Plugins

FAQ

Link

Sponsor

If you found this library useful and are willing to donate, transfer some bitcoins to 1BqqKiZA8Tq43CdukdBEwCdDD42jxuX9UY.

Credits


caiogondim.com  ·  GitHub @caiogondim  ·  Twitter @caio_gondim

logdown.js's People

Contributors

aga5tya avatar ahsanayaz avatar bahmutov avatar bennycode avatar caiogondim avatar dan-luk avatar david-byng avatar dependabot-support avatar ffflorian avatar lipis avatar reactiveraven avatar reqshark avatar robbestad avatar sleepwalker avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

logdown.js's Issues

Support logging of things other than strings

Logdown logging of non-strings:

var log = new Logdown();
log.log(log); // TypeError: e.replace is not a function
log.info(1); // TypeError: e.replace is not a function
log.info(false); // TypeError: e.replace is not a function
log.warn({ ABC: 'Easy', as: [1,2,3] }); // TypeError: e.replace is not a function
log.error(new Error('test')); // TypeError: e.replace is not a function

Compared to the built-in console object:

var log = console;
log.log(log); //Console {memory: MemoryInfo, debug: function, error: function, info: function, log: function…}
log.info(1); // 1
log.info(false); // false
log.warn({ ABC: 'Easy', as: [1,2,3] }); // Object {ABC: "Easy", as: Array[3]}
log.error(new Error('test')); // Error: test {stack: (...), message: "test"}

Rename "index.js" to "logdown.js"

Logdown's output for Bower is called index.js. When people execute bower install logdown, they get an index.js file out of the box, which need to be included the following way:

<script src="/bower_components/logdown/dist/index.js"></script>

I think it would be nicer to have:

<script src="/bower_components/logdown/dist/logdown.js"></script>

Especially if you have a Bower copy task which just dumps all files from "bower_components" into a flat hierarchy. This way logdown would not overwrite another library (which also might use the name index.js).

Other very famous libraries (like boostrap) also use their name as output (in this case bootstrap.js).

Logdown's current output:

capture

Support logging objects

With the Browser's console it's possible to log objects like:

var demo = new Logdown({
  prefix: 'demo',
  alignOuput: true
});

console.log('Hello World!', demo);

Which will result into this output:

unbenannt

logdown.js unfortunately stringifies objects, so that they cannot be accessed via the Browser's console:

unbenannt

It would be nice if logdown.js treats objects like the standard JavaScript console does.

Here is some demo code:

var demo = new Logdown({
  prefix: 'demo',
  alignOuput: true
});

demo.log('Hello World!', demo);

RFC: 2.0 API

Using the same idea as debug for their V3 release, let's discuss ideas for our V2 release.

My current ideas are:

  • Move test suite to Jest
    I don't see value on using Karma and just test if the methods were called with the right values.
    Moving to Jest should make everything faster and more straight forward.

  • Use static typing (Flow type or Typescript)
    Should make the lib more stable.

  • Modularize code
    Babel in case of Flow type, Typescript all way down otherwise.

  • Test coverage report
    For free in Jest

  • Full compatibility with debug
    The idea is to make logdown a drop in replacement for debug.
    We should run their test suite against our code.
    I see this as a high gain, high effort task.

  • Move repo to an organization
    This project is not only mine anymore, and I don't think it's fair to keep it in my name since we have other contributors.
    The downside would be SEO.

  • Website
    logdown.js.org ?

Thoughts?

Showing Dates / Timestamps for log entries

I really like the logdown.js project but does it support timestamps in front of log messages?

We are looking for something that can replace our current log library which gives us these features:

unbenannt

Escaping special characters

call the `foo\_bar` method on the `quux\_service` endpoint

rendersas

call the foo\_bar method on the quux_service endpoint

Source Maps

I realized that we don't distribute a source map file (dist/logdown.js.map). For proper debugging we should offer this.

"alignOutput" doesn't work across different Logdown versions

I have a webpacked module (cryptobox.js), which bundles my application together with Logdown.

In my main application I am loading this module and I am loading another Logdown via the script tag, to log inside my main application (because the bundled Logdown is not accessible from the outside).

Doing this I realized that the alignment is different:

logdown

Maybe it would be a good idea to allow numbers as values for alignOutput, so that you can set the spacing manually as a fallback. @caiogondim: WDYT?

Here is my code:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>Demo</title>
    <link rel="shortcut icon" href="data:image/x-icon;" type="image/x-icon" />
    <script src="lib/dynamic/logdown/index.js"></script>
    <script src="bundle/wire-webapp-cryptobox.js"></script>
  </head>
  <body>
    <script>
      var storage = new cryptobox.store.IndexedDB('bundle_test');
      var box = new cryptobox.Cryptobox(storage, 10);

      box.init().then(function() {
        var logger = new Logdown({prefix: 'bundle_test', alignOutput: true});
        var fingerprint = box.identity.public_key.fingerprint();
        var message = 'Local Identity: ' + fingerprint;
        logger.log(message);
      });
    </script>
  </body>
</html>

Support global Logdown options

It would be nice if you could set a preset for every newly created Logdown instance.

Example:

If I always want to have logger instances which don't render Markdown but align output, I should be able to do something like this:

Logdown.preset({
  alignOuput: true,
  markdown: false
});

var firstLogger = new Logdown({prefix: 'firstLogger'});
var secondLogger = new Logdown({prefix: 'secondLogger'});

This should be equivalent to:

var firstLogger = new Logdown({
  prefix: 'firstLogger',
  alignOuput: true,
  markdown: false
});

var secondLogger = new Logdown({
  prefix: 'secondLogger',
  alignOuput: true,
  markdown: false
});

Add different and extendable logging transports

It would be nice if Logdown could write to log files.

The atma-logger for example is able to write to the filesystem or to a remote server (via HTTP): https://github.com/atmajs/atma-logger#transports

There is also winston, a multi-transport async logging library. With winston logging transports can be changed the following way:

winston = require('winston');

winston.add(winston.transports.File, {
  filename: config.logging_file,
  handleExceptions: true,
})
.remove(winston.transports.Console)
.info('Name', 'Message');

Would be great to have something similar with Logdown. 😃

Upload favicon

Upload favicon to prevent this error on example page:
screen shot 2016-04-03 at 23 44 41

backticks reserved by es6

Hi guys,

Since backticks are increasingly used by people moving to ES6, for all kinds of strings, could the code formatting be changed to not clash with that?

Cheers.

The "prefixColor" should be configurable

It should be possible to set a fixed color for a Markdown logger, like:

var logger = new Logdown({
  alignOuput: true,
  prefix: 'cryptobox.store.IndexedDB',
  prefixColor: '#B58900'
});

Support for Microsoft Edge

I just realized that Logdown looks a bit odd in Microsoft Edge v14 (the latest one). We should fix this. 💃

Screenshot:

logdown

Color the actual logged text as well

Is it possible to add color to the logged text as well, of course a slightly different color than the one of the prefix ?

Also, I just noticed that the prefix text isn't getting colored in the correct color, it's stuck on the yellow one, which is the first in the colors array as well...

Documentation

In a Pull Request we discussed the usage of GitHub wiki pages. Because wiki pages are specific to GitHub we had the idea of using Markdown files within the repository to describe how to use Logdown and how to do things like deploying a new Logdown version, etc.

I just found this service http://documentup.com/ which could be nice in finding the right headlines for our Markdown files. Here is what we get from our root readme.md file:

Support "timestamp" property

It should be possible to force a Logdown instance printing it's logs together with a timestamp. It should be configurable by a timestamp property like this:

// Prints timestamp in the format `2016-08-13` or `YYYY-MM-DD`
const logger1 = new Logdown({
  prefix: 'lorem',
  timestamp: true
})

// If a string is passed, we use it as a template for formatting the timestamp
const logger2 = new Logdown({
  prefix: 'lorem',
  timestamp: 'MM/DD/YYYY'
})

// Throws an error in case we can't parse the string passed as template
const logger3 = new Logdown({
  prefix: 'lorem',
  timestamp: 'ipsum'
})

Allow function value for "prefix" property

At the moment the prefix property of a Logdown instance must be a string value:

var prefix = opts.prefix === undefined ? '' : opts.prefix

To enhance the flexbility of the prefix creation, it should be allowed to set function values too.

Example:

var demoLogger = new Logdown({
  prefix: function() {
    return new Date().toISOString() + ' MyLogger';
  }
});

Simplify use with transparent constructor

It would be awesome if we could simply var debug = require('logdown')({prefix: 'foo}); instead of having to call new on Logdown. I think browser-people used to use jQuery would also prefer Logdown({prefix: 'foo'});.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.