8000 Merge branch 'master' into version-2 · LikeABossProgrammer/log4js-node@8be0b8e · GitHub
[go: up one dir, main page]

Skip to content

Commit 8be0b8e

Browse files
author
Gareth Jones
committed
Merge branch 'master' into version-2
2 parents 2e03528 + e6a9cfb commit 8be0b8e

File tree

4 files changed

+260
-0
lines changed

4 files changed

+260
-0
lines changed

examples/redis-appender.js

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
//Note that redis appender needs install redis to work.
2+
3+
var log4js = require('../lib/log4js');
4+
5+
log4js.configure({
6+
"appenders": [
7+
{
8+
type: 'console',
9+
category: 'console'
10+
}, {
11+
type: 'dateFile',
12+
filename: 'logs/log.txt',
13+
pattern: 'yyyyMMdd',
14+
alwaysIncludePattern: false,
15+
category: 'dateFile'
16+
}, {
17+
type: 'redis',
18+
host: '127.0.0.1',
19+
port: 6379,
20+
pass: '',
21+
channel: 'q_log',
22+
category: 'redis',
23+
layout: {
24+
type: 'pattern',
25+
pattern: '%d{yyyy-MM-dd hh:mm:ss:SSS}#%p#%m'
26+
}
27+
}
28+
]
29+
});
30+
log = log4js.getLogger("console");
31+
logRedis = log4js.getLogger("redis");
32+
33+
function doTheLogging(x) {
34+
log.info("Logging something %d", x);
35+
logRedis.info("Logging something %d", x);
36+
}
37+
38+
for ( ; i < 500; i++) {
39+
doTheLogging(i);
40+
}

lib/appenders/redis.js

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
'use strict';
2+
3+
const layouts = require('../layouts');
4+
const redis = require('redis');
5+
const util = require('util');
6+
7+
function redisAppender(config, layout) {
8+
layout = layout || layouts.messagePassThroughLayout;
9+
const redisClient = redis.createClient(config.port, config.host, { auth_pass: config.pass });
10+
redisClient.on('error', (err) => {
11+
if (err) {
12+
console.error('log4js.redisAppender - %s:%p Error: %s', config.host, config.port, util.inspect(err));
13+
}
14+
});
15+
return function (loggingEvent) {
16+
const message = layout(loggingEvent);
17+
redisClient.publish(config.channel, message, (err) => {
18+
if (err) {
19+
console.error('log4js.redisAppender - %s:%p Error: %s', config.host, config.port, util.inspect(err));
20+
}
21+
});
22+
};
23+
}
24+
25+
function configure(config) {
26+
let layout;
27+
if (config.layout) {
28+
layout = layouts.layout(config.layout.type, config.layout);
29+
}
30+
31+
return redisAppender(config, layout);
32+
}
33+
34+
module.exports.appender = redisAppender;
35+
module.exports.configure = configure;

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959
"loggly": "^1.1.0",
6060
"mailgun-js": "^0.7.0",
6161
"nodemailer": "^2.5.0",
62+
"redis": "^2.7.1",
6263
"slack-node": "~0.2.0",
6364
"axios": "^0.15.3"
6465
},

test/tap/redisAppender-test.js

Lines changed: 184 additions & 0 deletions
< 10000 td data-grid-cell-id="diff-763ae12f787fc268d5f4278a084ad340f61535e32dca69587a6be8681926fbea-empty-21-2" data-line-anchor="diff-763ae12f787fc268d5f4278a084ad340f61535e32dca69587a6be8681926fbeaR21" data-selected="false" role="gridcell" style="background-color:var(--diffBlob-additionLine-bgColor, var(--diffBlob-addition-bgColor-line));padding-right:24px" tabindex="-1" valign="top" class="focusable-grid-cell diff-text-cell right-side-diff-cell left-side">+
this.port = port;
10000
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
'use strict';
2+
3+
const test = require('tap').test;
4+
const log4js = require('../../lib/log4js');
5+
const sandbox = require('sandboxed-module');
6+
7+
function setupLogging(category, options) {
8+
const msgs = [];
9+
10+
const redisCredentials = {
11+
type: options.type,
12+
host: options.host,
13+
port: options.port,
14+
pass: options.pass,
15+
channel: options.channel,
16+
layout: options.layout
17+
};
18+
19+
const fakeRedis = {
20+
createClient: function (port, host, optionR) {
21
22+
this.host = host;
23+
this.optionR = {};
24+
this.optionR.auth_pass = optionR.pass;
25+
26+
return {
27+
on: function (event, callback) {
28+
callback('throw redis error #1');
29+
},
30+
publish: function (channel, message, callback) {
31+
msgs.push(message);
32+
callback(null, {status: 'sent'});
33+
}
34+
};
35+
}
36+
};
37+
38+
const fakeLayouts = {
39+
layout: function (type, config) {
40+
this.type = type;
41+
this.config = config;
42+
return log4js.layouts.messagePassThroughLayout;
43+
},
44+
basicLayout: log4js.layouts.basicLayout,
45+
coloredLayout: log4js.layouts.coloredLayout,
46+
messagePassThroughLayout: log4js.layouts.messagePassThroughLayout
47+
};
48+
49+
const fakeUtil = {
50+
inspect: function (item) {
51+
return JSON.stringify(item);
52+
}
53+
};
54+
55+
const fakeConsole = {
56+
errors: [],
57+
logs: [],
58+
error: function (msg, value) {
59+
this.errors.push({ msg: msg, value: value });
60+
},
61+
log: function (msg, value) {
62+
this.logs.push({ msg: msg, value: value });
63+
}
64+
};
65+
66+
const redisModule = sandbox.require('../../lib/appenders/redis', {
67+
requires: {
68+
'redis': fakeRedis,
69+
'../layouts': fakeLayouts,
70+
'util': fakeUtil
71+
},
72+
globals: {
73+
console: fakeConsole
74+
}
75+
});
76+
77+
log4js.addAppender(redisModule.configure(options), category);
78+
79+
return {
80+
logger: log4js.getLogger(category),
81+
redis: fakeRedis,
82+
layouts: fakeLayouts,
83+
console: fakeConsole,
84+
messages: msgs,
85+
credentials: redisCredentials
86+
};
87+
}
88+
89+
function checkMessages(assert, result) {
90+
for (let i = 0; i < result.messages.length; i++) {
91+
assert.ok(new RegExp(`Log event #${i + 1}`).test(result.messages[i]));
92+
}
93+
}
94+
95+
log4js.clearAppenders();
96+
97+
test('log4js redisAppender', (batch) => {
98+
batch.test('redis setup', (t) => {
99+
const result = setupLogging('redis setup', {
100+
host: '127.0.0.1',
101+
port: 6739,
102+
pass: '123456',
103+
channel: 'log',
104+
type: 'redis',
105+
layout: {
106+
type: 'pattern',
107+
pattern: '%d{yyyy-MM-dd hh:mm:ss:SSS}#%p#%m'
108+
}
109+
});
110+
t.test('redis credentials should match', (assert) => {
111+
assert.equal(result.credentials.host, '127.0.0.1');
112+
assert.equal(result.credentials.port, 6739);
113+
assert.equal(result.credentials.pass, '123456');
114+
assert.equal(result.credentials.channel, 'log');
115+
assert.equal(result.credentials.type, 'redis');
116+
assert.equal(result.credentials.layout.type, 'pattern');
117+
assert.equal(result.credentials.layout.pattern, '%d{yyyy-MM-dd hh:mm:ss:SSS}#%p#%m');
118+
assert.end();
119+
});
120+
121+
t.end();
122+
});
123+
124+
batch.test('basic usage', (t) => {
125+
const setup< 93C6 /span> = setupLogging('basic usage', {
126+
host: '127.0.0.1',
127+
port: 6739,
128+
pass: '',
129+
channel: 'log',
130+
type: 'redis',
131+
layout: {
132+
type: 'pattern',
133+
pattern: '%d{yyyy-MM-dd hh:mm:ss:SSS}#%p#%m'
134+
}
135+
});
136+
137+
setup.logger.info('Log event #1');
138+
139+
t.equal(setup.messages.length, 1, 'should be one message only');
140+
checkMessages(t, setup);
141+
t.end();
142+
});
143+
144+
145+
batch.test('config with layout', (t) => {
146+
const result = setupLogging('config with layout', {
147+
layout: {
148+
type: 'redis'
149+
}
150+
});
151+
t.equal(result.layouts.type, 'redis', 'should configure layout');
152+
t.end();
153+
});
154+
155+
batch.test('separate notification for each event', (t) => {
156+
const setup = setupLogging('separate notification for each event', {
157+
host: '127.0.0.1',
158+
port: 6739,
159+
pass: '',
160+
channel: 'log',
161+
type: 'redis',
162+
layout: {
163+
type: 'pattern',
164+
pattern: '%d{yyyy-MM-dd hh:mm:ss:SSS}#%p#%m'
165+
}
166+
});
167+
setTimeout(() => {
168+
setup.logger.info('Log event #1');
169+
}, 0);
170+
setTimeout(() => {
171+
setup.logger.info('Log event #2');
172+
}, 500);
173+
setTimeout(() => {
174+
setup.logger.info('Log event #3');
175+
}, 1100);
176+
setTimeout(() => {
177+
t.equal(setup.messages.length, 3, 'should be three messages');
178+
checkMessages(t, setup);
179+
t.end();
180+
}, 3000);
181+
});
182+
183+
batch.end();
184+
});

0 commit comments

Comments
 (0)
0