From f478793da3ff9343be5d4311a5daa4de3acec7b9 Mon Sep 17 00:00:00 2001 From: Friedel Ziegelmayer Date: Sat, 19 Jan 2013 22:05:15 +0100 Subject: [PATCH 01/10] Misc code highlighting fixes in readme.md --- README.md | 72 +++++++++++++++++++++++++++---------------------------- 1 file changed, 36 insertions(+), 36 deletions(-) diff --git a/README.md b/README.md index e613b0d..0d2c196 100644 --- a/README.md +++ b/README.md @@ -21,10 +21,10 @@ NOTE: from log4js 0.5 onwards you'll need to explicitly enable replacement of no ```javascript { - appenders: [ - { type: "console" } - ], - replaceConsole: true + appenders: [ + { type: "console" } + ], + replaceConsole: true } ``` @@ -42,9 +42,9 @@ var logger = log4js.getLogger(); 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: - - [2010-01-17 11:43:37.987] [DEBUG] [default] - Some debug messages - +```bash +[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): ```javascript var log4js = require('log4js'); @@ -53,7 +53,7 @@ var log4js = require('log4js'); log4js.loadAppender('file'); //log4js.addAppender(log4js.appenders.console()); log4js.addAppender(log4js.appenders.file('logs/cheese.log'), 'cheese'); -```javascript + var logger = log4js.getLogger('cheese'); logger.setLevel('ERROR'); @@ -65,18 +65,18 @@ logger.error('Cheese is too ripe!'); logger.fatal('Cheese was breeding ground for listeria.'); ``` Output: - - [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. - +```bash +[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. +``` The first 5 lines of the code above could also be written as: ```javascript var log4js = require('log4js'); log4js.configure({ - appenders: [ - { type: 'console' }, - { type: 'file', filename: 'logs/cheese.log', category: 'cheese' } - ] + appenders: [ + { type: 'console' }, + { 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' }); ``` 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: - - #### my_log4js_configuration.json #### +```json +#### my_log4js_configuration.json #### +{ + "appenders": [ { - "appenders": [ - { - "type": "file", - "filename": "relative/path/to/log_file.log", - "maxLogSize": 20480, - "backups": 3, - "category": "relative-logger" - }, - { - "type": "file", - "absolute": true, - "filename": "/absolute/path/to/log_file.log", - "maxLogSize": 20480, - "backups": 10, - "category": "absolute-logger" - } - ] + "type": "file", + "filename": "relative/path/to/log_file.log", + "maxLogSize": 20480, + "backups": 3, + "category": "relative-logger" + }, + { + "type": "file", + "absolute": true, + "filename": "/absolute/path/to/log_file.log", + "maxLogSize": 20480, + "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 From 7f57d14e70c4583ba4d5a57a9e350c7a4b83f2b2 Mon Sep 17 00:00:00 2001 From: Friedel Ziegelmayer Date: Sat, 19 Jan 2013 22:12:10 +0100 Subject: [PATCH 02/10] Move examples into their own directory. --- example-connect-logger.js => examples/example-connect-logger.js | 0 example-socket.js => examples/example-socket.js | 0 example.js => examples/example.js | 0 fromreadme.js => examples/fromreadme.js | 0 log-rolling.js => examples/log-rolling.js | 0 memory-test.js => examples/memory-test.js | 0 6 files changed, 0 insertions(+), 0 deletions(-) rename example-connect-logger.js => examples/example-connect-logger.js (100%) rename example-socket.js => examples/example-socket.js (100%) rename example.js => examples/example.js (100%) rename fromreadme.js => examples/fromreadme.js (100%) rename log-rolling.js => examples/log-rolling.js (100%) rename memory-test.js => examples/memory-test.js (100%) diff --git a/example-connect-logger.js b/examples/example-connect-logger.js similarity index 100% rename from example-connect-logger.js rename to examples/example-connect-logger.js diff --git a/example-socket.js b/examples/example-socket.js similarity index 100% rename from example-socket.js rename to examples/example-socket.js diff --git a/example.js b/examples/example.js similarity index 100% rename from example.js rename to examples/example.js diff --git a/fromreadme.js b/examples/fromreadme.js similarity index 100% rename from fromreadme.js rename to examples/fromreadme.js diff --git a/log-rolling.js b/examples/log-rolling.js similarity index 100% rename from log-rolling.js rename to examples/log-rolling.js diff --git a/memory-test.js b/examples/memory-test.js similarity index 100% rename from memory-test.js rename to examples/memory-test.js From e4bf405f201a0a63865171ca0232b3a5bcc3dcf1 Mon Sep 17 00:00:00 2001 From: Jan Schmidle Date: Fri, 8 Feb 2013 14:54:18 +0100 Subject: [PATCH 03/10] add your own tokens to the patternLayout --- lib/layouts.js | 20 ++++++++++++++++---- test/layouts-test.js | 27 ++++++++++++++++++++++----- 2 files changed, 38 insertions(+), 9 deletions(-) diff --git a/lib/layouts.js b/lib/layouts.js index 320d12c..dc6c2dd 100644 --- a/lib/layouts.js +++ b/lib/layouts.js @@ -10,8 +10,9 @@ var dateFormat = require('./date_format') , "coloured": function() { return colouredLayout; } , "pattern": function (config) { var pattern = config.pattern || undefined; - return patternLayout(pattern); - } + var tokens = config.tokens || undefined; + return patternLayout(pattern, tokens); + } } , colours = { ALL: "grey" @@ -143,9 +144,9 @@ function messagePassThroughLayout (loggingEvent) { * Takes a pattern string and returns a layout function. * @author Stephan Strittmatter */ -function patternLayout (pattern) { +function patternLayout (pattern, tokens) { 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; @@ -221,6 +222,17 @@ function patternLayout (pattern) { case "%": replacement = "%"; break; + case "x": + if(tokens[specifier]) { + if(typeof(tokens[specifier]) === 'function') { + replacement = tokens[specifier](); + } else { + replacement = tokens[specifier]; + } + } else { + replacement = matchedString; + } + break; default: replacement = matchedString; break; diff --git a/test/layouts-test.js b/test/layouts-test.js index 105fd1c..52c9811 100644 --- a/test/layouts-test.js +++ b/test/layouts-test.js @@ -4,9 +4,10 @@ assert = require('assert'); //used for patternLayout tests. function test(args, pattern, value) { 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({ @@ -175,8 +176,12 @@ vows.describe('log4js layouts').addBatch({ level: { toString: function() { return "DEBUG"; } } - }, layout = require('../lib/layouts').patternLayout; - return [layout, event]; + }, layout = require('../lib/layouts').patternLayout + , tokens = { + testString: 'testStringToken', + testFunction: function() { return 'testFunctionToken'; } + }; + return [layout, event, tokens]; }, 'should default to "time logLevel loggerName - message"': function(args) { @@ -246,6 +251,18 @@ vows.describe('log4js layouts').addBatch({ }, '%[%r%] should output colored time': function(args) { 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); From bec0d058470263f957def32c07cbd35076edf0f3 Mon Sep 17 00:00:00 2001 From: Jan Schmidle Date: Fri, 8 Feb 2013 16:15:51 +0100 Subject: [PATCH 04/10] added some documentation to the function header --- lib/layouts.js | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/lib/layouts.js b/lib/layouts.js index dc6c2dd..aed65b8 100644 --- a/lib/layouts.js +++ b/lib/layouts.js @@ -140,9 +140,22 @@ function messagePassThroughLayout (loggingEvent) { * - %d date in various formats * - %% % * - %n newline + * - %x{} add dynamic tokens to your log. Tokens are specified in the tokens parameter * 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 Jan Schmidle */ function patternLayout (pattern, tokens) { var TTCC_CONVERSION_PATTERN = "%r %p %c - %m%n"; From 5c75ba9468b36af668f1af439cbd546461ed098f Mon Sep 17 00:00:00 2001 From: Jan Schmidle Date: Fri, 8 Feb 2013 16:17:24 +0100 Subject: [PATCH 05/10] fixed small issue that could occur with wrong evaluated parameters --- lib/layouts.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/layouts.js b/lib/layouts.js index aed65b8..931fc48 100644 --- a/lib/layouts.js +++ b/lib/layouts.js @@ -236,7 +236,7 @@ function patternLayout (pattern, tokens) { replacement = "%"; break; case "x": - if(tokens[specifier]) { + if(typeof(tokens[specifier]) !== 'undefined') { if(typeof(tokens[specifier]) === 'function') { replacement = tokens[specifier](); } else { From af428c5669470b00f95df04da28a000536d591b3 Mon Sep 17 00:00:00 2001 From: Jan Schmidle Date: Fri, 8 Feb 2013 16:18:27 +0100 Subject: [PATCH 06/10] added example on pattern tokens usage --- examples/patternLayout-tokens.js | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 examples/patternLayout-tokens.js diff --git a/examples/patternLayout-tokens.js b/examples/patternLayout-tokens.js new file mode 100644 index 0000000..18cd6f7 --- /dev/null +++ b/examples/patternLayout-tokens.js @@ -0,0 +1,21 @@ +var log4js = require("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"); \ No newline at end of file From a3bdac8e14024216613e6aa84bc2e91c9d15693f Mon Sep 17 00:00:00 2001 From: Jan Schmidle Date: Fri, 8 Feb 2013 16:22:29 +0100 Subject: [PATCH 07/10] updated require in example to match other examles --- examples/patternLayout-tokens.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/patternLayout-tokens.js b/examples/patternLayout-tokens.js index 18cd6f7..84b171c 100644 --- a/examples/patternLayout-tokens.js +++ b/examples/patternLayout-tokens.js @@ -1,4 +1,4 @@ -var log4js = require("log4js"); +var log4js = require('./lib/log4js'); var config = { "appenders": [ From b75e3660f4366c1a1268299d90bc0b65d58e5069 Mon Sep 17 00:00:00 2001 From: Nicolas Pelletier Date: Wed, 13 Feb 2013 09:35:02 -0500 Subject: [PATCH 08/10] Speed up file logging for high rate of logging. During an evaluation of multiple loggers, I saw a slow down when trying to quickly log more than 100,000 messages to a file: ```javascript counter = 150000; while (counter) { logger.info('Message[' + counter + ']'); counter -= 1; } ``` My detailed test can be found here: - https://gist.github.com/NicolasPelletier/4773843 The test demonstrate that writing 150,000 lines straight in a FileStream takes about 22 seconds until the file content stabilizes. When calling logger.debug() 150,000 times, the file stabilizes to its final content after 229s ( almost 4 minutes ! ). After investigation, it turns out that the problem is using an Array() to accumulate the data. Pushing the data in the Array with Array.push() is quick, but the code flushing the buffer uses Array.shift(), which forces re-indexing of all 149,999 elements remaining in the Array. This is exponentially slower as the buffer grows. The solution is to use something else than an Array to accumulate the messages. The fix was made using a package called Dequeue ( https://github.com/lleo/node-dequeue ). By replacing the Array with a Dequeue object, it brought the logging of 150,000 messages back down to 31s. Seven times faster than the previous 229s. There is a caveat that each log event is slightly longer due to the need to create an object to put in the double-ended queue inside the Dequeue object. According to a quick test, it takes about 4% more time per call to logger.debug(). --- lib/streams/BufferedWriteStream.js | 3 ++- package.json | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/streams/BufferedWriteStream.js b/lib/streams/BufferedWriteStream.js index d10c8c7..6820c82 100644 --- a/lib/streams/BufferedWriteStream.js +++ b/lib/streams/BufferedWriteStream.js @@ -1,4 +1,5 @@ var events = require('events'), + Dequeue = require('dequeue'), util = require('util'); module.exports = BufferedWriteStream; @@ -6,7 +7,7 @@ module.exports = BufferedWriteStream; function BufferedWriteStream(stream) { var that = this; this.stream = stream; - this.buffer = []; + this.buffer = new Dequeue(); this.canWrite = false; this.bytes = 0; diff --git a/package.json b/package.json index 44a12ad..a24cdc5 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,8 @@ "lib": "lib" }, "dependencies": { - "async": "0.1.15" + "async": "0.1.15", + "dequeue": "1.0.3" }, "devDependencies": { "vows": "0.6.2", From 8e53c6213e477bf9f4330ab167bfc27df4771eab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rio=20Freitas?= Date: Thu, 21 Feb 2013 00:06:59 +0900 Subject: [PATCH 09/10] fix: pass options from multiprocess appender to inner appender --- lib/appenders/multiprocess.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/appenders/multiprocess.js b/lib/appenders/multiprocess.js index 9ab7bc9..a698097 100644 --- a/lib/appenders/multiprocess.js +++ b/lib/appenders/multiprocess.js @@ -115,11 +115,11 @@ function createAppender(config) { } } -function configure(config) { +function configure(config, options) { var actualAppender; if (config.appender && config.mode === 'master') { 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; } return createAppender(config); From 5e242c9dc9bbd08577ec20c87b64c49a3c15cf28 Mon Sep 17 00:00:00 2001 From: Gareth Jones Date: Mon, 25 Feb 2013 16:33:48 +1100 Subject: [PATCH 10/10] bumped version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a24cdc5..6476613 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "log4js", - "version": "0.5.6", + "version": "0.5.7", "description": "Port of Log4js to work with node.", "keywords": [ "logging",