Merge branch 'master' into util.format

This commit is contained in:
Gareth Jones 2013-02-25 16:43:03 +11:00
commit f272e3fd0a
13 changed files with 116 additions and 51 deletions

View File

@ -21,10 +21,10 @@ NOTE: from log4js 0.5 onwards you'll need to explicitly enable replacement of no
```javascript ```javascript
{ {
appenders: [ appenders: [
{ type: "console" } { type: "console" }
], ],
replaceConsole: true replaceConsole: true
} }
``` ```
@ -42,9 +42,9 @@ var logger = log4js.getLogger();
logger.debug("Some debug messages"); logger.debug("Some debug messages");
``` ```
By default, log4js outputs to stdout with the coloured layout (thanks to [masylum](http://github.com/masylum)), so for the above you would see: By default, log4js outputs to stdout with the coloured layout (thanks to [masylum](http://github.com/masylum)), so for the above you would see:
```bash
[2010-01-17 11:43:37.987] [DEBUG] [default] - Some debug messages [2010-01-17 11:43:37.987] [DEBUG] [default] - Some debug messages
```
See example.js for a full example, but here's a snippet (also in fromreadme.js): See example.js for a full example, but here's a snippet (also in fromreadme.js):
```javascript ```javascript
var log4js = require('log4js'); var log4js = require('log4js');
@ -53,7 +53,7 @@ var log4js = require('log4js');
log4js.loadAppender('file'); log4js.loadAppender('file');
//log4js.addAppender(log4js.appenders.console()); //log4js.addAppender(log4js.appenders.console());
log4js.addAppender(log4js.appenders.file('logs/cheese.log'), 'cheese'); log4js.addAppender(log4js.appenders.file('logs/cheese.log'), 'cheese');
```javascript
var logger = log4js.getLogger('cheese'); var logger = log4js.getLogger('cheese');
logger.setLevel('ERROR'); logger.setLevel('ERROR');
@ -65,18 +65,18 @@ logger.error('Cheese is too ripe!');
logger.fatal('Cheese was breeding ground for listeria.'); logger.fatal('Cheese was breeding ground for listeria.');
``` ```
Output: Output:
```bash
[2010-01-17 11:43:37.987] [ERROR] cheese - Cheese is too ripe! [2010-01-17 11:43:37.987] [ERROR] cheese - Cheese is too ripe!
[2010-01-17 11:43:37.990] [FATAL] cheese - Cheese was breeding ground for listeria. [2010-01-17 11:43:37.990] [FATAL] cheese - Cheese was breeding ground for listeria.
```
The first 5 lines of the code above could also be written as: The first 5 lines of the code above could also be written as:
```javascript ```javascript
var log4js = require('log4js'); var log4js = require('log4js');
log4js.configure({ log4js.configure({
appenders: [ appenders: [
{ type: 'console' }, { type: 'console' },
{ type: 'file', filename: 'logs/cheese.log', category: 'cheese' } { type: 'file', filename: 'logs/cheese.log', category: 'cheese' }
] ]
}); });
``` ```
@ -106,28 +106,28 @@ For FileAppender you can also pass the path to the log directory as an option wh
log4js.configure('my_log4js_configuration.json', { cwd: '/absolute/path/to/log/dir' }); log4js.configure('my_log4js_configuration.json', { cwd: '/absolute/path/to/log/dir' });
``` ```
If you have already defined an absolute path for one of the FileAppenders in the configuration file, you could add a "absolute": true to the particular FileAppender to override the cwd option passed. Here is an example configuration file: If you have already defined an absolute path for one of the FileAppenders in the configuration file, you could add a "absolute": true to the particular FileAppender to override the cwd option passed. Here is an example configuration file:
```json
#### my_log4js_configuration.json #### #### my_log4js_configuration.json ####
{
"appenders": [
{ {
"appenders": [ "type": "file",
{ "filename": "relative/path/to/log_file.log",
"type": "file", "maxLogSize": 20480,
"filename": "relative/path/to/log_file.log", "backups": 3,
"maxLogSize": 20480, "category": "relative-logger"
"backups": 3, },
"category": "relative-logger" {
}, "type": "file",
{ "absolute": true,
"type": "file", "filename": "/absolute/path/to/log_file.log",
"absolute": true, "maxLogSize": 20480,
"filename": "/absolute/path/to/log_file.log", "backups": 10,
"maxLogSize": 20480, "category": "absolute-logger"
"backups": 10,
"category": "absolute-logger"
}
]
} }
]
}
```
Documentation for most of the core appenders can be found on the [wiki](log4js-node/wiki/Appenders), otherwise take a look at the tests and the examples. Documentation for most of the core appenders can be found on the [wiki](log4js-node/wiki/Appenders), otherwise take a look at the tests and the examples.
## Documentation ## Documentation

View File

@ -0,0 +1,21 @@
var log4js = require('./lib/log4js');
var config = {
"appenders": [
{
"type": "console",
"layout": {
"type": "pattern",
"pattern": "%[%r (%x{pid}) %p %c -%] %m%n",
"tokens": {
"pid" : function() { return process.pid; }
}
}
}
]
};
log4js.configure(config, {});
var logger = log4js.getLogger("app");
logger.info("Test log message");

View File

@ -115,11 +115,11 @@ function createAppender(config) {
} }
} }
function configure(config) { function configure(config, options) {
var actualAppender; var actualAppender;
if (config.appender && config.mode === 'master') { if (config.appender && config.mode === 'master') {
log4js.loadAppender(config.appender.type); log4js.loadAppender(config.appender.type);
actualAppender = log4js.appenderMakers[config.appender.type](config.appender); actualAppender = log4js.appenderMakers[config.appender.type](config.appender, options);
config.actualAppender = actualAppender; config.actualAppender = actualAppender;
} }
return createAppender(config); return createAppender(config);

View File

@ -10,8 +10,9 @@ var dateFormat = require('./date_format')
, "coloured": function() { return colouredLayout; } , "coloured": function() { return colouredLayout; }
, "pattern": function (config) { , "pattern": function (config) {
var pattern = config.pattern || undefined; var pattern = config.pattern || undefined;
return patternLayout(pattern); var tokens = config.tokens || undefined;
} return patternLayout(pattern, tokens);
}
} }
, colours = { , colours = {
ALL: "grey" ALL: "grey"
@ -121,13 +122,26 @@ function messagePassThroughLayout (loggingEvent) {
* - %d date in various formats * - %d date in various formats
* - %% % * - %% %
* - %n newline * - %n newline
* - %x{<tokenname>} add dynamic tokens to your log. Tokens are specified in the tokens parameter
* You can use %[ and %] to define a colored block. * You can use %[ and %] to define a colored block.
* Takes a pattern string and returns a layout function. *
* Tokens are specified as simple key:value objects.
* The key represents the token name whereas the value can be a string or function
* which is called to extract the value to put in the log message. If token is not
* found, it doesn't replace the field.
*
* A sample token would be: { "pid" : function() { return process.pid; } }
*
* Takes a pattern string, array of tokens and returns a layout function.
* @param {String} Log format pattern String
* @param {object} map object of different tokens
* @return {Function}
* @author Stephan Strittmatter * @author Stephan Strittmatter
* @author Jan Schmidle
*/ */
function patternLayout (pattern) { function patternLayout (pattern, tokens) {
var TTCC_CONVERSION_PATTERN = "%r %p %c - %m%n"; var TTCC_CONVERSION_PATTERN = "%r %p %c - %m%n";
var regex = /%(-?[0-9]+)?(\.?[0-9]+)?([\[\]cdmnpr%])(\{([^\}]+)\})?|([^%]+)/; var regex = /%(-?[0-9]+)?(\.?[0-9]+)?([\[\]cdmnprx%])(\{([^\}]+)\})?|([^%]+)/;
pattern = pattern || TTCC_CONVERSION_PATTERN; pattern = pattern || TTCC_CONVERSION_PATTERN;
@ -203,6 +217,17 @@ function patternLayout (pattern) {
case "%": case "%":
replacement = "%"; replacement = "%";
break; break;
case "x":
if(typeof(tokens[specifier]) !== 'undefined') {
if(typeof(tokens[specifier]) === 'function') {
replacement = tokens[specifier]();
} else {
replacement = tokens[specifier];
}
} else {
replacement = matchedString;
}
break;
default: default:
replacement = matchedString; replacement = matchedString;
break; break;

View File

@ -1,4 +1,5 @@
var events = require('events'), var events = require('events'),
Dequeue = require('dequeue'),
util = require('util'); util = require('util');
module.exports = BufferedWriteStream; module.exports = BufferedWriteStream;
@ -6,7 +7,7 @@ module.exports = BufferedWriteStream;
function BufferedWriteStream(stream) { function BufferedWriteStream(stream) {
var that = this; var that = this;
this.stream = stream; this.stream = stream;
this.buffer = []; this.buffer = new Dequeue();
this.canWrite = false; this.canWrite = false;
this.bytes = 0; this.bytes = 0;

View File

@ -1,6 +1,6 @@
{ {
"name": "log4js", "name": "log4js",
"version": "0.5.6", "version": "0.5.7",
"description": "Port of Log4js to work with node.", "description": "Port of Log4js to work with node.",
"keywords": [ "keywords": [
"logging", "logging",
@ -26,7 +26,8 @@
"lib": "lib" "lib": "lib"
}, },
"dependencies": { "dependencies": {
"async": "0.1.15" "async": "0.1.15",
"dequeue": "1.0.3"
}, },
"devDependencies": { "devDependencies": {
"vows": "0.6.2", "vows": "0.6.2",

View File

@ -4,9 +4,10 @@ assert = require('assert');
//used for patternLayout tests. //used for patternLayout tests.
function test(args, pattern, value) { function test(args, pattern, value) {
var layout = args[0] var layout = args[0]
, event = args[1]; , event = args[1]
, tokens = args[2];
assert.equal(layout(pattern)(event), value); assert.equal(layout(pattern, tokens)(event), value);
} }
vows.describe('log4js layouts').addBatch({ vows.describe('log4js layouts').addBatch({
@ -174,8 +175,12 @@ vows.describe('log4js layouts').addBatch({
level: { level: {
toString: function() { return "DEBUG"; } toString: function() { return "DEBUG"; }
} }
}, layout = require('../lib/layouts').patternLayout; }, layout = require('../lib/layouts').patternLayout
return [layout, event]; , tokens = {
testString: 'testStringToken',
testFunction: function() { return 'testFunctionToken'; }
};
return [layout, event, tokens];
}, },
'should default to "time logLevel loggerName - message"': function(args) { 'should default to "time logLevel loggerName - message"': function(args) {
@ -245,6 +250,18 @@ vows.describe('log4js layouts').addBatch({
}, },
'%[%r%] should output colored time': function(args) { '%[%r%] should output colored time': function(args) {
test(args, '%[%r%]', '\033[36m14:18:30\033[39m'); test(args, '%[%r%]', '\033[36m14:18:30\033[39m');
} },
'%x{testString} should output the string stored in tokens': function(args) {
test(args, '%x{testString}', 'testStringToken');
},
'%x{testFunction} should output the result of the function stored in tokens': function(args) {
test(args, '%x{testFunction}', 'testFunctionToken');
},
'%x{doesNotExist} should output the string stored in tokens': function(args) {
test(args, '%x{doesNotExist}', '%x{doesNotExist}');
},
'%x should output the string stored in tokens': function(args) {
test(args, '%x', '%x');
},
} }
}).export(module); }).export(module);