Skip to content

Commit 92333e2

Browse files
authoredJun 14, 2016
Merge pull request log4js-node#387 from sparklton/master
logFaces appender
2 parents eb96085 + 1a1d8e6 commit 92333e2

File tree

4 files changed

+192
-0
lines changed

4 files changed

+192
-0
lines changed
 

‎README.md

+1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ Out of the box it supports the following features:
1515
* hook.io appender
1616
* Loggly appender
1717
* Logstash UDP appender
18+
* logFaces appender
1819
* multiprocess appender (useful when you've got worker processes)
1920
* a logger for connect/express servers
2021
* configurable log message layout/patterns

‎examples/logFaces-appender.js

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
var log4js = require('../lib/log4js');
2+
3+
/*
4+
logFaces server configured with UDP receiver, using JSON format,
5+
listening on port 55201 will receive the logs from the appender below.
6+
*/
7+
8+
log4js.configure({
9+
"appenders": [
10+
{
11+
"type": "logFacesAppender", // (mandatory) appender type
12+
"application": "MY-NODEJS", // (optional) name of the application (domain)
13+
"remoteHost": "localhost", // (optional) logFaces server host or IP address
14+
"port": 55201, // (optional) logFaces UDP receiver port (must use JSON format)
15+
"layout": { // (optional) the layout to use for messages
16+
"type": "pattern",
17+
"pattern": "%m"
18+
}
19+
}
20+
]
21+
});
22+
23+
var logger = log4js.getLogger("myLogger");
24+
logger.info("Testing message %s", "arg1");

‎lib/appenders/logFacesAppender.js

+71
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/**
2+
* logFaces appender sends JSON formatted log events to logFaces server UDP receivers.
3+
* Events contain the following properties:
4+
* - application name (taken from configuration)
5+
* - host name (taken from underlying os)
6+
* - time stamp
7+
* - level
8+
* - logger name (e.g. category)
9+
* - thread name (current process id)
10+
* - message text
11+
*/
12+
13+
"use strict";
14+
var dgram = require('dgram'),
15+
layouts = require('../layouts'),
16+
os = require('os'),
17+
util = require('util');
18+
19+
try{
20+
var process = require('process');
21+
}
22+
catch(error){
23+
//this module is optional as it may not be available
24+
//in older versions of node.js, so ignore if it failes to load
25+
}
26+
27+
function logFacesAppender (config, layout) {
28+
var lfsSock = dgram.createSocket('udp4');
29+
var localhost = "";
30+
31+
if(os && os.hostname())
32+
localhost = os.hostname().toString();
33+
34+
var pid = "";
35+
if(process && process.pid)
36+
pid = process.pid;
37+
38+
return function log(loggingEvent) {
39+
var lfsEvent = {
40+
a: config.application || "", // application name
41+
h: localhost, // this host name
42+
t: loggingEvent.startTime.getTime(), // time stamp
43+
p: loggingEvent.level.levelStr, // level (priority)
44+
g: loggingEvent.categoryName, // logger name
45+
r: pid, // thread (process id)
46+
m: layout(loggingEvent) // message text
47+
};
48+
49+
var buffer = new Buffer(JSON.stringify(lfsEvent));
50+
var lfsHost = config.remoteHost || "127.0.0.1";
51+
var lfsPort = config.port || 55201;
52+
lfsSock.send(buffer, 0, buffer.length, lfsPort, lfsHost, function(err, bytes) {
53+
if(err) {
54+
console.error("log4js.logFacesAppender send to %s:%d failed, error: %s",
55+
config.host, config.port, util.inspect(err));
56+
}
57+
});
58+
};
59+
}
60+
61+
function configure(config) {
62+
var layout;
63+
if (config.layout)
64+
layout = layouts.layout(config.layout.type, config.layout);
65+
else
66+
layout = layouts.layout("pattern", {"type": "pattern", "pattern": "%m"});
67+
return logFacesAppender(config, layout);
68+
}
69+
70+
exports.appender = logFacesAppender;
71+
exports.configure = configure;

‎test/logFacesAppender-test.js

+96
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
"use strict";
2+
var vows = require('vows'),
3+
assert = require('assert'),
4+
log4js = require('../lib/log4js'),
5+
sandbox = require('sandboxed-module');
6+
7+
function setupLogging(category, options) {
8+
var udpSent = {};
9+
10+
var fakeDgram = {
11+
createSocket: function (type) {
12+
return {
13+
send: function(buffer, offset, length, port, host, callback) {
14+
udpSent.date = new Date();
15+
udpSent.host = host;
16+
udpSent.port = port;
17+
udpSent.length = length;
18+
udpSent.offset = 0;
19+
udpSent.buffer = buffer;
20+
callback(undefined, length);
21+
}
22+
};
23+
}
24+
};
25+
26+
var lfsModule = sandbox.require('../lib/appenders/logFacesAppender', {
27+
requires: {
28+
'dgram': fakeDgram
29+
}
30+
});
31+
log4js.clearAppenders();
32+
log4js.addAppender(lfsModule.configure(options), category);
33+
34+
return {
35+
logger: log4js.getLogger(category),
36+
results: udpSent
37+
};
38+
}
39+
40+
vows.describe('logFaces UDP appender').addBatch({
41+
'when logging to logFaces UDP receiver': {
42+
topic: function() {
43+
var setup = setupLogging('myCategory', {
44+
"type": "logFacesAppender",
45+
"application": "LFS-TEST",
46+
"remoteHost": "127.0.0.1",
47+
"port": 55201,
48+
"layout": {
49+
"type": "pattern",
50+
"pattern": "%m"
51+
}
52+
});
53+
54+
setup.logger.warn('Log event #1');
55+
return setup;
56+
},
57+
'an UDP packet should be sent': function (topic) {
58+
assert.equal(topic.results.host, "127.0.0.1");
59+
assert.equal(topic.results.port, 55201);
60+
assert.equal(topic.results.offset, 0);
61+
var json = JSON.parse(topic.results.buffer.toString());
62+
assert.equal(json.a, 'LFS-TEST');
63+
assert.equal(json.m, 'Log event #1');
64+
assert.equal(json.g, 'myCategory');
65+
assert.equal(json.p, 'WARN');
66+
67+
// Assert timestamp, up to hours resolution.
68+
var date = new Date(json.t);
69+
assert.equal(
70+
date.toISOString().substring(0, 14),
71+
topic.results.date.toISOString().substring(0, 14)
72+
);
73+
}
74+
},
75+
76+
'when missing options': {
77+
topic: function() {
78+
var setup = setupLogging('myLogger', {
79+
"type": "logFacesAppender",
80+
});
81+
setup.logger.error('Log event #2');
82+
return setup;
83+
},
84+
'it sets some defaults': function (topic) {
85+
assert.equal(topic.results.host, "127.0.0.1");
86+
assert.equal(topic.results.port, 55201);
87+
88+
var json = JSON.parse(topic.results.buffer.toString());
89+
assert.equal(json.a, "");
90+
assert.equal(json.m, 'Log event #2');
91+
assert.equal(json.g, 'myLogger');
92+
assert.equal(json.p, 'ERROR');
93+
}
94+
}
95+
96+
}).export(module);

0 commit comments

Comments
 (0)
Please sign in to comment.