No description
Find a file
2014-12-23 05:57:58 -06:00
__misc New README 2014-12-20 15:16:54 +01:00
examples Prepping for heroku 2014-12-22 21:45:59 -06:00
herokuapp Updating target 2014-12-23 05:57:58 -06:00
lib Fix datesExplorer bug 2014-12-22 22:36:30 +01:00
static Updating herokuapp 2014-12-23 05:12:03 -06:00
.gitignore Add npm-debug to .gitignore 2014-11-01 12:24:53 +01:00
.jshintrc Edit jshintrc for angular js files 2014-11-01 12:25:17 +01:00
Gruntfile.js No tests for now 2014-12-20 15:48:42 +01:00
LICENSE-MIT Adding tests and cleaning up directories 2014-08-01 02:28:44 -05:00
package.json Removing serve-static direct dependency 2014-12-22 02:14:46 -06:00
Procfile Updating herokuapp 2014-12-23 05:12:03 -06:00
README.md Chaining loggers 2014-12-21 09:15:28 +01:00
scribe.js Remove trailing whitespace 2014-12-20 10:09:14 +01:00

![Logo](__misc/scribejs design logo [a].png)

Lightweight NodeJS Logging

console.tag("Demo").time().file().log("%s is %s", "ScribeJS", "awesome")

demo

Overview

Unlike many of the libraries out there, Scribe.js allows logging on multiple files and is divided into folders by date. And it is possibly the easiest logging you can implement. And it does everything you need a basic logger to do :

  • Keep using the console object
  • Save messages into json log files organized by user, date, and type or your custom rule
  • Print messages into console using colors indicating level of importance
  • Adding context to logs such as time, tags, filename and line number

And :

  • Logging express requests
  • Providing a rich HTML web panel to access logs from your browser and an API

#Table of contents

Installing

npm install git+https://github.com/bluejamesbond/Scribe.js.git

Examples

A list of examples is provided in /examples.

Documentation

ScribeJS is divided is 4 main modules :

It all starts by adding ScribeJS to your js file :

require('scribe')();

var console = process.console;

Use this import if you don't need do configure anything. It will attach a new Console2 instance on process.console and create basic loggers.

Or :

var scribe = require('scribe')();

Use this import if you want to configure or custom something.

##scribe(config)

Params :

  • config : Optional.
    • rootPath : logs folder for LogWriter. Default /logs
    • createDefaultConsole : Boolean. If true : create a Console2 instance attached to process.console. Default true. See Using Scribe through your modules

Return : an object with this properties

  • console
  • webPanel
  • express
  • LogWriter
  • Console2

###scribe.console(config, logWriter)

Create a new Console2 instance with LogWriter listening. This is the best way to create a console.

Params :

  • config
    • console : Optional. Console2 options
    • logWiter : Optional. Boolean|Object. If false, don't save logs on disk.
      • rootPath : directory where to store logs
    • createBasic : Optional. Boolean. true to create basic loggers. Default true.
  • logWriter : Optional. A custom LogWriter instance to use.

Return : A Console2 instance.

Example :

var console = scribe.console();

var anotherConsole = scribe.console({
    console : myConsole2Config,
    createBasic : false
});

####Basic loggers When passing true as the createBasic config, you ask ScribeJS to create default loggers to the new console you're builting.

These loggers are :

  • log()
  • info()
  • error()
  • warning()
  • dir()

See /examples/basic.js

###scribe.webPanel()

Return : an express router

Example : (assuming you have an app express server)

app.use('/logs', scribe.webPanel());

###scribe.express.logger(console, validate)

Params:

  • console : Optional. An instance of Console2 with an .info() logger. If no console provided, Scribe will try to use process.console if it exists. If not, it will throw an error.
  • validate : a filter function that receive req and res as arguments and should return true in order to Scribe to log that request.

Return : a function that log every request

Example :

app.use(scribe.express.logger());

See also : /examples/expressLogger_custom.js

###scribe.LogWriter

LogWriter constructor

Use the constructor to built your own instance of LogWriter. Usefull when you need, by example, to change to full path of a log file.
Default is : [YYYY]/[MM]/[DD_MM_YY].[logger].json.

You can by example change it to [user]/[logger]/[DD_MMM_YY].[logger].json. See /examples/logWriter_config.js.

###scribe.Console2

Console2 constructor

Don't use it directly but use scribe.console() instead in order to hook LogWriter logic (and others) on the new console.

##Console2(opt)

console2 demo

require('../scribe')(); //loads Scribe (with basic loggers)

//create a local (for the module) console
var console = process.console; 

console.log("Hello");
//you can use printf-like format
console.log("A string %s and a number %d", "hello", "123"); 

//Time
console.time().log("Print the full time");
console.date().log("Just print the date");

//Tags
console.tag("My Tag").log("Add a tag");
console.tag("Tag1", 'Tag2', 123).log("Or multiple tag");
console.tag({msg : 'my-tag', colors : ['red', 'inverse']}).log("Use colors.js colors");

//File and line number
console.file().log("Print the file and the line of the call");

//Object
console.log({just : 'an object'});

//Combos !
console.log(
        "Print many things",
        { key1 : "val 1", key2 : { a: "b", c : []}, key3 : [1234]},
        ['an array'],
        "A String"
);
console.tag("Combo!").time().file().log("A combo");

//Chaining loggers
console.info('Some info').tag('A tag').log('Some logs').warning('Some warning');

Params : (all optional)

  • opt.colors : Array|String. Default colors output for all loggers. Default ['cyan'].
  • opt.tagsColors : Array|String. Default colors output for tags. Default undefined.
  • opt.timeColors : Array|String. Default colors output for time. Default undefined.
  • opt.datecolors : Array|String. Default colors output for date. Default undefined.
  • opt.fileColors : Array|String. Default colors output for filename. Default undefined.
  • opt.lineColors : Array|String. Default colors output for line number. Default undefined.
  • opt.alwaysTags : Boolean. Always print tags (even without tag() ). Default false.
  • opt.alwaysLocation : Boolean. Always print location (even without file() ). Default false.
  • opt.alwaysTime : Boolean. Always print time (even without time() ). Default false.
  • opt.alwaysDate : Boolean. Always print date (even without date() ). Default false.
  • opt.logInConsole : Boolean. Should all loggers print to console by default ? Default true.
  • opt.contextMediumSize : Int. Medium size of the context part of a log message. Used when calculating indent. Default to 45.
  • opt.spaceSize : Int. Space between context part and log part. Default to 4.

Colors must be colors.js compatible.

demo colors

Example :

var myConfigConsole = scribe.console({
    console : { //pass here Console2 options
        colors : ['rainbow', 'inverse'],
        tagsColors : ['yellow', 'underline']
    }
);

See :

###Console2.time() Tell the logger to log the time (ISO format).

###Console2.date() Tell the logger to log the date (using toDateString()).

###Console2.tag(*args), Console2.t(*args)

Params:

An infinite number of tag where tag is :

  • a string
  • or an object :
    • msg : String. The tag
    • colors : Array|String. Colors.js colors

Examples :

console.tag('My tag').log('Something');
console.tag("A tag", {msg : "A another tag", colors : ['red', 'inverse']}).log('Something else').

###Console2.file(), Console2.f() Tell the logger to log the filename and the line of the log.

###Console2.addLogger(name, colors, opt)

Params :

  • name : String. Name of the logger. Next you call the logger with console.mylogger()
  • colors : Array|String. Optional. Colors.js colors.
  • opt : Optional. Options for this logger only. See Console2 options.
    • tagsColors : Array|String. Default colors output for tags. Default undefined.
    • timeColors : Array|String. Default colors output for time. Default undefined.
    • datecolors : Array|String. Default colors output for date. Default undefined.
    • fileColors : Array|String. Default colors output for filename. Default undefined.
    • lineColors : Array|String. Default colors output for line number. Default undefined.
    • alwaysTags : Boolean. Always print tags (even without tag() ). Default false.
    • alwaysLocation : Boolean. Always print location (even without file() ). Default false.
    • alwaysTime : Boolean. Always print time (even without time() ). Default false.
    • alwaysDate : Boolean. Always print date (even without date() ). Default false.
    • logInConsole : Boolean. Should all loggers print to console by default ? Default true.

Example :

console.addLogger('fun', ['rainbow', 'inverse'], {
    timeColors : ['gray', 'underline']
})

console.fun('something');

See Console2.buildArgs() to know what you can pass to a logger

###Console2.buildArgs(log)

Do not use this unless you want to change how args you pass to a logger are printed. See code.

Params :

  • log : A log object constructed by the logger. See code.
    • args. Logger's arguments
    • ...

Return : String. The args part of the message.

  • If all args ar string of number, will use util.format.apply() as the original nodejs console does.
  • If object or array are present, will print the args line by line and object/arg on multilines.

See /examples/console2.js

###Console2.buildContext(log, opt)

Do not use this unless you want to change how context (tags/location/time/date/...) you pass to a logger are printed. See code.

Params :

  • log : A log object constructed by the logger. See code.
  • opt : wether to print tags/location/time/date or not

Return :

  • result : String. The context part of the log.
  • lenght : Int. The human-readable length of the result. Ie. without colors console caracters.

###Console2.[your logger](*args)

Will print *args to the console, with context if there is.
See Console2.buildArgs().

Params : anything, printf format, etc.

Return : the Console2 instance.

Example :

console.addLogger('demo');

console.tag('Simple').demo('A ', 'message');
console.tag('Printf format').demo("%s:%s", 10, "23");
console.tag('Multiple args and big context').time().file().demo(
    "A message",    //string
    123,            //number
    [1, 2],         //array
    { foo : 'bar' } //object
);

console.log("Demo").time().warning("Test").info("some info");

See /examples/console2.js

###Console2 events

Each Console2 instance emits events :

  • newLogger when a new logger is created

    /**
     * name : name of the logger
     * opt : Console2 options
     */
    console.on('newLogger', function (name, opt) {
        //welcome, new logger !
    });
    
  • new when a logger logs something

    /**
     * log : the log object.
    
    var log = {
        type       : 'loggerName',
        show       : {
            tags     : Boolean,
            location : Boolean,
            time     : Boolean,
            date     : Boolean
        },
        context    : {
            tags     : [ tags ],
            file     : Boolean,
            time     : Date.now(),
            location : { filename : 'main.js', line : 12 }
        },
        args       : arguments, //loggers arguments
        opt        : opt,        //loggers options for addLogger()
    
        contextString : '[..] ...' ,
        argsString    : 'My message',
        message       : '[..] ...       My message'
    };
    
    *
    * loggerName : the logger name
    */
    console.on('new', function (log, loggerName) {
        //Oh! `loggerName` has logged something
    });
    
  • [loggerName] when [loggerName] logs something. Fired whith new

    /**
     * log : same as above
     */
    console.on('log', function (log) {
        //someone has logged something with logger "log"
    });
    

    If loggerName is 'error', Scribe replace error with 'errorEvent' as NodeJS eventEmitter will raise an Error if there is no listeners.

See /examples/events.js

LogWriter(rootPath)

logWriter demo

LogWriter constructor. Highly configurable as all functions are public. See code.

Param :

  • rootPath: String. Optional Directory where to save logs. Default logs.

###LogWriter.initHistory() Attach and init the history property.

###LogWriter.createDir(path, callback) Create a dir if doesn't exist yet.

###LogWriter.appendFile(pathToFile, content, callback) Append content to file.

###LogWriter.writeFile(pathToFile, content, callback) Write (erase) content to file.

###LogWriter.newFileHistory(pathToFile) Save the new file path in history according to date.

###logWriter.getUser() Util. Return active system user.

###LogWriter.getPath(opt) Build the path to current logs folder.
Default return [YYYY]/[MMM]

###LogWriter.getFile(opt) Build the filename.
Default [DD_MM_YY].[loggerName].json

###LogWriter.path(opt) Build the full path to file.
Ie. RootPath + getPath() + getFile()

###LogWriter.save(log, opt) Save a log on disk

###LogWriter.saveOpt(logger) Save logger opt in root folder

###LogWriter.addLogger(logger) Call saveOpt().

###How logs are saved ?

LogWriter create an history.json file in root folder where it keeps tracks of all logs files created by date.

It also create [logger name].json in root folder for each logger where it saves the logger config.

Then LogWriter will save logs in directory according to the output of LogWriter.path().

Example

See /examples/logWriter_config.js to see how to build your custom log path and pass it to scribe.console() function.

WebPanel

An express router that served an HTML logs explorer.

Web panel demo

Example :

var scribe = require('scribe')(),
    app    = express();

app.use('\logs', scribe.webPanel());

app.listen(8080);

See :

###Dev tips :

WebPanel highly depends on LogWriter as it use history.json file to find logs.

WebPanel is RESTfull :

  • on the server side, an express router serves an API and find files on disk
  • on client side, an AngularJS app manage the routing and the data

All the client code is under /static.

ExpressLogger

express logger demo

###ExpressLogger.logger(console, filter) An utility to log each request made to an express server.
See scribe.express.logger()

#Using Scribe through your modules

When running require('scribe')() or require('scribe')({createDefaultConsole : true}) you ask Scribe to attach a fresh console on the NodeJS process variable.

As process is shared accross all modules you required (the whole process), you can use the Console2 instance in sub-modules.

Example :

//main.js
require('scribe')();
var sub = require('./sub.js'); //a sub-module
var console = process.console;

console.tag('Hello world').log("We're in the main file")

sub.something(); //Will use process.console
//sub.js
//don't require scribe, simply link `process.console`
var console = process.console;

module.exports = {
    something : function () {
        console.tag("Hello World", "Sub").log("We're in a submodule");
    }
};

Tip : even if you don't tell scribe to create a default console, you can manually attach a Console2 instance on process.

//main.js
var scribe = require('scribe')({
    createDefaultConsole : false
});
var sub = require('./sub.js'); //a sub-module

var customConsole = scribe.console({  //a new console
    //custom
});

process.customConsole = customConsole; //attach it to process

customConsole('Hello world').log("We're in the main file")

sub.something(); //Will use process.console
//sub.js
//don't require scribe
var console = process.customConsole;

module.exports = {
    something : function () {
        console.tag("Hello World", "Sub").log("We're in a submodule");
    }
};

See :

#Come back to the old console

Scribe overides nothing and doesn't break logging in dependencies. The old NodeJS console is never too far away.

require('scribe')();

var console = process.console;

console.time().log("Logging with Scribe")
global.console.log("Logging the old way")
//in a dependency
console.log("Something") //the old console

See : NodeJS global doc

#Contributors