New README
621
README.md
|
@ -1,137 +1,520 @@
|
|||

|
||||
=======
|
||||
|
||||
**Lightweight NodeJS Logging**
|
||||
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.
|
||||
- Save messages into log files organized by user, date, and type
|
||||
|
||||
```javascript
|
||||
console.tag("Demo").time().file().log("%s is %s", "ScribeJS", "awesome")
|
||||
```
|
||||

|
||||
|
||||
# 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
|
||||
|
||||
Output Methods (Web | Console | File)
|
||||
=======
|
||||
Method#Web - Select Date
|
||||
---
|
||||

|
||||
Method#Web - Select Log Type
|
||||
---
|
||||

|
||||
Method#Web - View Logs
|
||||
---
|
||||

|
||||
Method#Console - Command Prompt
|
||||
---
|
||||

|
||||
Method#File - File
|
||||
---
|
||||

|
||||
Method#File - Directory Layout
|
||||
---
|
||||

|
||||
And :
|
||||
|
||||
- Logging express requests
|
||||
- Providing a rich HTML web panel to access logs from your browser and an API
|
||||
|
||||
# Installing
|
||||
|
||||
Installation
|
||||
=======
|
||||
```
|
||||
npm install git+https://github.com/bluejamesbond/Scribe.js.git
|
||||
```
|
||||
Documentation
|
||||
=======
|
||||
```js
|
||||
var scribe = require('scribe');
|
||||
|
||||
// Configuration
|
||||
// --------------
|
||||
scribe.configure(function(){
|
||||
scribe.set('app', 'MY_APP_NAME'); // NOTE Best way learn about these settings is
|
||||
scribe.set('logPath', './logs'); // Doublecheck // them out for yourself.
|
||||
scribe.set('defaultTag', 'DEFAULT_TAG');
|
||||
scribe.set('divider', ':::');
|
||||
scribe.set('identation', 5); // Identation before console messages
|
||||
|
||||
scribe.set('maxTagLength', 30); // Any tags that have a length greather than
|
||||
// 30 characters will be ignored
|
||||
|
||||
scribe.set('mainUser', 'root'); // Username of the account which is running
|
||||
// the NodeJS server
|
||||
# Examples
|
||||
|
||||
A list of examples is provided in [`/examples`](/examples).
|
||||
|
||||
# Documentation
|
||||
|
||||
ScribeJS is divided is 4 main modules :
|
||||
|
||||
- [Console2](#Console2) : an extended console object
|
||||
- [LogWriter](#LogWriter) : an utility to save logs on disk
|
||||
- [WebPanel](#WebPanel) : a rich HTML logs explorer
|
||||
- [ExpressLogger](#ExpressLogger) : an utility to logs all express request
|
||||
|
||||
It all starts by adding ScribeJS to your js file :
|
||||
|
||||
```javascript
|
||||
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](#basic-loggers).
|
||||
|
||||
Or :
|
||||
|
||||
```javascript
|
||||
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](#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](#Console2)
|
||||
- `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](#basic-loggers). Default `true`.
|
||||
- `logWriter` : *Optional.* A custom LogWriter instance to use.
|
||||
|
||||
**Return** : A Console2 instance.
|
||||
|
||||
|
||||
**Example** :
|
||||
|
||||
```javascript
|
||||
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`](/examples/basic.js)
|
||||
|
||||
###scribe.webPanel()
|
||||
|
||||
**Return** : an express router
|
||||
|
||||
**Example** : (assuming you have an `app` express server)
|
||||
|
||||
```javascript
|
||||
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** :
|
||||
|
||||
```javascript
|
||||
app.use(scribe.express.logger());
|
||||
```
|
||||
|
||||
See also : [`/examples/expressLogger_custom.js`](/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`](/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)
|
||||
|
||||

|
||||
|
||||
**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](https://github.com/Marak/colors.js) compatible.
|
||||
|
||||

|
||||
|
||||
**Example** :
|
||||
|
||||
```javascript
|
||||
var myConfigConsole = scribe.console({
|
||||
console : { //pass here Console2 options
|
||||
colors : ['rainbow', 'inverse'],
|
||||
tagsColors : ['yellow', 'underline']
|
||||
}
|
||||
);
|
||||
```
|
||||
|
||||
See :
|
||||
|
||||
- [`/examples/run_with_config.js`](/examples/run_with_config.js)
|
||||
- [`/examples/console2.js`](/examples/console2.js)
|
||||
|
||||
###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** :
|
||||
|
||||
```javascript
|
||||
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** :
|
||||
|
||||
```javascript
|
||||
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`](/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()`.
|
||||
|
||||
**Example** :
|
||||
|
||||
```javascript
|
||||
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
|
||||
);
|
||||
```
|
||||
|
||||
See [`/examples/console2.js`](/examples/console2.js)
|
||||
|
||||
|
||||
## LogWriter(rootPath)
|
||||
|
||||

|
||||
|
||||
LogWriter contructor. Highly configurables 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, for each day, LogWriter will save logs in a new directory.
|
||||
|
||||
|
||||
### Example
|
||||
|
||||
See [`/examples/logWriter_config.js`](/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 and HTML logs explorer.
|
||||
|
||||

|
||||
|
||||
**Example** :
|
||||
|
||||
```javascript
|
||||
var scribe = require('scribe')(),
|
||||
app = express();
|
||||
|
||||
app.use('\logs', scribe.webPanel());
|
||||
|
||||
app.listen(8080);
|
||||
```
|
||||
|
||||
See :
|
||||
|
||||
- [`/examples/webPanel.js`](/examples/webPanel.js)
|
||||
- [`/examples/webPanel_auth.js`](/examples/webPanel_auth.js) where the webPanel is protected by a basic HTTP authentification.
|
||||
|
||||
###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 and 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
|
||||
|
||||

|
||||
|
||||
###ExpressLogger.logger(console, filter)
|
||||
An utility to log each request made to an express server.
|
||||
See [`scribe.express.logger()`](#scribe.express.logger(console,-validate))
|
||||
|
||||
#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** :
|
||||
|
||||
```javascript
|
||||
//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();
|
||||
```
|
||||
|
||||
```javascript
|
||||
//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`.
|
||||
|
||||
```javascript
|
||||
//main.js
|
||||
var scribe = require('scribe')({
|
||||
createDefaultConsole : false
|
||||
});
|
||||
var sub = require('./sub.js'); //a sub-module
|
||||
|
||||
var customConsole = scribe.console({ //a new console
|
||||
//custom
|
||||
});
|
||||
|
||||
// Create Loggers
|
||||
// --------------
|
||||
scribe.addLogger("log", true , true, 'green'); // (name, save to file, print to console,
|
||||
scribe.addLogger('realtime', true, true, 'underline'); // tag color)
|
||||
scribe.addLogger('high', true, true, 'magenta');
|
||||
scribe.addLogger('normal', true, true, 'white');
|
||||
scribe.addLogger('low', true, true, 'grey');
|
||||
scribe.addLogger('info', true, true, 'cyan');
|
||||
process.customConsole = customConsole; //attach it to process
|
||||
|
||||
// Express.js
|
||||
// WARNING: ExpressJS must be installed for this to work
|
||||
// You also need to start an ExpressJS server in order for
|
||||
// this to work.
|
||||
// --------------
|
||||
app.use(scribe.express.logger(function(req, res){ // Express.js access log
|
||||
return true; // Filter out any Express messages
|
||||
}));
|
||||
|
||||
// Control Panel
|
||||
// WARNING: ExpressJS must be installed for this to work
|
||||
// You also need to start an ExpressJS server in order for
|
||||
// this to work.
|
||||
// --------------
|
||||
app.get('/log', scribe.express.controlPanel()); // Enable web control panel
|
||||
|
||||
// Basic logging
|
||||
// --------------
|
||||
console.log("[Tagname] Your message"); // [Tagname] Your message
|
||||
console.realtime("[Tagname] Your message"); // [Tagname] Your message
|
||||
console.high("[Tagname] Your message "); // [Tagname] Your message
|
||||
console.normal("[Tagname][]Your message"); // [Tagname] []Your message
|
||||
console.low("[Tagname]Your message"); // [Tagname] Your message
|
||||
|
||||
// Tagging function
|
||||
// ----------------
|
||||
console.t("Tagname").log("Your message"); // [Tagname] Your message
|
||||
console.t("Tagname").log("Your message"); // [Tagname] Your message
|
||||
console.t("Tagname").log("Your message"); // [Tagname] Your message
|
||||
|
||||
// Force use default tag
|
||||
// ---------------------
|
||||
console.t().log("Your message"); // [MY_APP_NAME] Your message
|
||||
|
||||
// Pass in file name
|
||||
// -----------------
|
||||
console.f(__filename).log("Your message"); // [file.js] Your message
|
||||
|
||||
// Auto tagging
|
||||
// ------------
|
||||
console.log("Your message"); // [invokedFrom.js:25] Your message
|
||||
|
||||
// Show Date
|
||||
// ---------
|
||||
console.day().log("Your message"); // [invokedFrom.js:25] Sep_8_14 Your message
|
||||
|
||||
// Show Time
|
||||
// ---------
|
||||
console.time().log("Your message"); // [invokedFrom.js:25] Sep_8_14 12:02:35 PM Your message
|
||||
|
||||
// Tag Scoping
|
||||
// -----------
|
||||
(function(console){
|
||||
|
||||
console.info("yeeha"); // [scoped-tag] yeeha
|
||||
console.log("yeeha"); // [scoped-tag] yeeha
|
||||
|
||||
})(console.t('scoped-tag'));
|
||||
customConsole('Hello world').log("We're in the main file")
|
||||
|
||||
sub.something();
|
||||
```
|
||||
Experimental
|
||||
=======
|
||||
```js
|
||||
// Simple Testing
|
||||
// --------------
|
||||
console.test("Test name").should(5).be(5); // Pretty printed test results
|
||||
|
||||
```javascript
|
||||
//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");
|
||||
}
|
||||
};
|
||||
```
|
||||
Contributors
|
||||
=======
|
||||
|
||||
See :
|
||||
|
||||
- [`/examples/run.js`](/examples/run.js)
|
||||
- [NodeJS process doc](http://nodejs.org/api/process.html)
|
||||
|
||||
|
||||
#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.
|
||||
|
||||
```javascript
|
||||
require('scribe')();
|
||||
|
||||
var console = process.console;
|
||||
|
||||
console.time().log("Logging with Scribe")
|
||||
global.console.log("Logging the old way")
|
||||
```
|
||||
bluejamesbond
|
||||
|
||||
```javascript
|
||||
//in a dependency
|
||||
console.log("Something") //the old console
|
||||
```
|
||||
|
||||
See : [NodeJS global doc](http://nodejs.org/api/globals.html)
|
||||
|
||||
#Contributors
|
||||
|
||||
- bluejamesbond
|
||||
- guillaumewuip
|
||||
|
|
BIN
__misc/colorsDemo.png
Normal file
After Width: | Height: | Size: 22 KiB |
BIN
__misc/console2Demo.png
Normal file
After Width: | Height: | Size: 52 KiB |
BIN
__misc/expressLoggerDemo.png
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
__misc/introDemo.png
Normal file
After Width: | Height: | Size: 9.4 KiB |
BIN
__misc/logWriterDemo.png
Normal file
After Width: | Height: | Size: 81 KiB |
Before Width: | Height: | Size: 38 KiB |
Before Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 40 KiB |
BIN
__misc/webPanelDemo.gif
Normal file
After Width: | Height: | Size: 2.8 MiB |