8000 adding logstash UDP appender · yanxi123-com/log4js-node@a7a0964 · GitHub
[go: up one dir, main page]

Skip to content

Commit a7a0964

Browse files
committed
adding logstash UDP appender
1 parent cacade0 commit a7a0964

File tree

4 files changed

+196
-0
lines changed

4 files changed

+196
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ Out of the box it supports the following features:
1313
* GELF appender
1414
* hook.io appender
1515
* Loggly appender
16+
* Logstash UDP appender
1617
* multiprocess appender (useful when you've got worker processes)
1718
* a logger for connect/express servers
1819
* configurable log message layout/patterns

examples/logstashUDP.js

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
var log4js = require('../lib/log4js');
2+
3+
/*
4+
Sample logstash config:
5+
udp {
6+
codec => json
7+
port => 10001
8+
queue_size => 2
9+
workers => 2
10+
type => myAppType
11+
}
12+
*/
13+
14+
log4js.configure({
15+
"appenders": [
16+
{
17+
type: "console",
18+
category: "myLogger"
19+
},
20+
{
21+
"host": "127.0.0.1",
22+
"port": 10001,
23+
"type": "logstashUDP",
24+
"logType": "myAppType", // Optional, defaults to 'category'
25+
"fields": { // Optional, will be added to the 'fields' object in logstash
26+
"field1": "value1",
27+
"field2": "value2"
28+
},
29+
"layout": {
30+
"type": "pattern",
31+
"pattern": "%m"
32+
},
33+
"category": "myLogger"
34+
}
35+
]
36+
});
37+
38+
var logger = log4js.getLogger("myLogger");
39+
logger.info("Test log message %s", "arg1", "arg2");

lib/appenders/logstashUDP.js

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
"use strict";
2+
var layouts = require('../layouts')
3+
, dgram = require('dgram')
4+
, util = require('util');
5+
6+
function logstashUDP (config, layout) {
7+
var udp = dgram.createSocket('udp4');
8+
var type = config.logType ? config.logType : config.category;
9+
layout = layout || layouts.colouredLayout;
10+
if(!config.fields) {
11+
config.fields = {};
12+
}
13+
return function(loggingEvent) {
14+
var logMessage = layout(loggingEvent);
15+
var fields = {};
16+
for(var i in config.fields) {
17+
fields[i] = config.fields[i];
18+
}
19+
fields['level'] = loggingEvent.level.levelStr;
20+
var logObject = {
21+
'@timestamp': (new Date(loggingEvent.startTime)).toISOString(),
22+
type: type,
23+
message: logMessage,
24+
fields: fields
25+
};
26+
sendLog(udp, config.host, config.port, logObject);
27+
};
28+
}
29+
30+
function sendLog(udp, host, port, logObject) {
31+
var buffer = new Buffer(JSON.stringify(logObject));
32+
udp.send(buffer, 0, buffer.length, port, host, function(err, bytes) {
33+
if(err) {
34+
console.error(
35+
"log4js.logstashUDP - %s:%p Error: %s", host, port, util.inspect(err)
36+
);
37+
}
38+
});
39+
}
40+
41+
function configure(config) {
42+
var layout;
43+
if (config.layout) {
44+
layout = layouts.layout(config.layout.type, config.layout);
45+
}
46+
return logstashUDP(config, layout);
47+
}
48+
49+
exports.appender = logstashUDP;
50+
exports.configure = configure;

test/logstashUDP-test.js

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
"use strict";
2+
var sys = require("sys");
3+
var vows = require('vows')
4+
, assert = require('assert')
5+
, log4js = require('../lib/log4js')
6+
, sandbox = require('sandboxed-module')
7+
;
8+
9+
function setupLogging(category, options) {
10+
var udpSent = {};
11+
12+
var fakeDgram = {
13+
createSocket: function (type) {
14+
return {
15+
send: function(buffer, offset, length, port, host, callback) {
16+
udpSent.date = new Date();
17+
udpSent.host = host;
18+
udpSent.port = port;
19+
udpSent.length = length;
20+
udpSent.offset = 0;
21+
udpSent.buffer = buffer;
22+
callback(undefined, length);
23+
}
24+
};
25+
}
26+
};
27+
28+
var logstashModule = sandbox.require('../lib/appenders/logstashUDP', {
29+
requires: {
30+
'dgram': fakeDgram
31+
}
32+
});
33+
log4js.clearAppenders();
34+
log4js.addAppender(logstashModule.configure(options), category);
35+
36+
return {
37+
logger: log4js.getLogger(category),
38+
results: udpSent
39+
};
40+
}
41+
42+
vows.describe('logstashUDP appender').addBatch({
43+
'when logging with logstash via UDP': {
44+
topic: function() {
45+
var setup = setupLogging('logstashUDP', {
46+
"host": "127.0.0.1",
47+
"port": 10001,
48+
"type": "logstashUDP",
49+
"logType": "myAppType",
50+
"category": "myLogger",
51+
"fields": {
52+
"field1": "value1",
53+
"field2": "value2"
54+
},
55+
"layout": {
56+
"type": "pattern",
57+
"pattern": "%m"
58+
}
59+
});
60+
setup.logger.log('trace', 'Log event #1');
61+
return setup;
62+
},
63+
'an UDP packet should be sent': function (topic) {
64+
assert.equal(topic.results.host, "127.0.0.1");
65+
assert.equal(topic.results.port, 10001);
66+
assert.equal(topic.results.offset, 0);
67+
var json = JSON.parse(topic.results.buffer.toString());
68+
assert.equal(json.type, 'myAppType');
69+
var fields = {
70+
field1: 'value1',
71+
field2: 'value2',
72+
level: 'TRACE'
73+
};
74+
assert.equal(JSON.stringify(json.fields), JSON.stringify(fields));
75+
assert.equal(json.message, 'Log event #1');
76+
// Assert timestamp, up to hours resolution.
77+
var date = new Date(json['@timestamp']);
78+
assert.equal(
79+
date.toISOString().substring(0, 14),
80+
topic.results.date.toISOString().substring(0, 14)
81+
);
82+
}
83+
},
84+
85+
'when missing some options': {
86+
topic: function() {
87+
var setup = setupLogging('myLogger', {
88+
"host": "127.0.0.1",
89+
"port": 10001,
90+
"type": "logstashUDP",
91+
"category": "myLogger",
92+
"layout": {
93+
"type": "pattern",
94+
"pattern": "%m"
95+
}
96+
});
97+
setup.logger.log('trace', 'Log event #1');
98+
return setup;
99+
},
100+
'it sets some defaults': function (topic) {
101+
var json = JSON.parse(topic.results.buffer.toString());
102+
assert.equal(json.type, 'myLogger');
103+
assert.equal(JSON.stringify(json.fields), JSON.stringify({'level': 'TRACE'}));
104+
}
105+
}
106+
}).export(module);

0 commit comments

Comments
 (0)
0