Merge pull request #683 from log4js-node/remove-logstash

chore: remove logstash udp
This commit is contained in:
Gareth Jones 2018-03-08 08:14:06 +11:00 committed by GitHub
commit 4d30f6ea2e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 1 additions and 400 deletions

View File

@ -14,7 +14,7 @@ There have been a few changes between log4js 1.x and 2.x (and 0.x too). You shou
* [SMTP appender](smtp.md)
* [GELF appender](https://github.com/log4js-node/gelf)
* [Loggly appender](https://github.com/log4js-node/loggly)
* [Logstash UDP appender](logstashUDP.md)
* [Logstash UDP appender](https://github.com/log4js-node/logstashUDP)
* logFaces ([UDP](logFaces-UDP.md) and [HTTP](logFaces-HTTP.md)) appender
* [TCP appender](tcp.md) (useful when you've got multiple servers but want to centralise logging)
* a [logger for connect/express](connect-logger.md) servers

View File

@ -1,111 +0,0 @@
'use strict';
const dgram = require('dgram');
const util = require('util');
function sendLog(udp, host, port, logObject) {
const buffer = Buffer.from(JSON.stringify(logObject));
/* eslint no-unused-vars:0 */
udp.send(buffer, 0, buffer.length, port, host, (err, bytes) => {
if (err) {
console.error('log4js.logstashUDP - %s:%p Error: %s', host, port, util.inspect(err));
}
});
}
function logstashUDP(config, layout) {
const udp = dgram.createSocket('udp4');
const type = config.logType ? config.logType : config.category;
if (!config.fields) {
config.fields = {};
}
function checkArgs(argsValue, logUnderFields) {
if ((!argsValue) || (argsValue === 'both')) {
return true;
}
if (logUnderFields && (argsValue === 'fields')) {
return true;
}
if ((!logUnderFields) && (argsValue === 'direct')) {
return true;
}
return false;
}
function log(loggingEvent) {
/*
https://gist.github.com/jordansissel/2996677
{
'message' => 'hello world',
'@version' => '1',
'@timestamp' => '2014-04-22T23:03:14.111Z',
'type' => 'stdin',
'host' => 'hello.local'
}
@timestamp is the ISO8601 high-precision timestamp for the event.
@version is the version number of this json schema
Every other field is valid and fine.
*/
const fields = {};
Object.keys(config.fields).forEach((key) => {
fields[key] = typeof config.fields[key] === 'function' ? config.fields[key](loggingEvent) : config.fields[key];
});
/* eslint no-prototype-builtins:1,no-restricted-syntax:[1, "ForInStatement"] */
if (loggingEvent.data.length > 1) {
const secondEvData = loggingEvent.data[1];
if ((secondEvData !== undefined) && (secondEvData !== null)) {
Object.keys(secondEvData).forEach((key) => {
fields[key] = secondEvData[key];
});
}
}
fields.level = loggingEvent.level.levelStr;
fields.category = loggingEvent.categoryName;
const logObject = {
'@version': '1',
'@timestamp': (new Date(loggingEvent.startTime)).toISOString(),
type: type,
message: layout(loggingEvent)
};
if (checkArgs(config.args, true)) {
logObject.fields = fields;
}
if (checkArgs(config.args, false)) {
Object.keys(fields).forEach((key) => {
logObject[key] = fields[key];
});
}
sendLog(udp, config.host, config.port, logObject);
}
log.shutdown = function (cb) {
udp.close(cb);
};
log.deprecated = '@log4js-node/logstashudp';
return log;
}
function configure(config, layouts) {
let layout = layouts.dummyLayout;
if (config.layout) {
layout = layouts.layout(config.layout.type, config.layout);
}
return logstashUDP(config, layout);
}
module.exports.configure = configure;

View File

@ -1,271 +0,0 @@
'use strict';
const test = require('tap').test;
const sandbox = require('@log4js-node/sandboxed-module');
function setupLogging(category, options) {
const udpSent = {};
const socket = { closed: false };
const fakeDgram = {
createSocket: function () {
return {
send: function (buffer, offset, length, port, host, callback) {
udpSent.date = new Date();
udpSent.host = host;
udpSent.port = port;
udpSent.length = length;
udpSent.offset = 0;
udpSent.buffer = buffer;
callback(undefined, length);
},
close: function (cb) {
socket.closed = true;
cb();
}
};
}
};
const log4js = sandbox.require('../../lib/log4js', {
requires: {
dgram: fakeDgram
}
});
options = options || {};
options.type = 'logstashUDP';
log4js.configure({
appenders: { logstash: options },
categories: { default: { appenders: ['logstash'], level: 'trace' } }
});
return {
logger: log4js.getLogger(category),
log4js: log4js,
results: udpSent,
socket: socket
};
}
test('logstashUDP appender', (batch) => {
batch.test('a UDP packet should be sent', (t) => {
const setup = setupLogging('myCategory', {
host: '127.0.0.1',
port: 10001,
type: 'logstashUDP',
logType: 'myAppType',
category: 'myLogger',
fields: {
field1: 'value1',
field2: 'value2'
},
layout: {
type: 'pattern',
pattern: '%m'
}
});
setup.logger.log('trace', 'Log event #1');
t.equal(setup.results.host, '127.0.0.1');
t.equal(setup.results.port, 10001);
t.equal(setup.results.offset, 0);
const json = JSON.parse(setup.results.buffer.toString());
t.equal(json.type, 'myAppType');
const fields = {
field1: 'value1',
field2: 'value2',
level: 'TRACE',
category: 'myCategory'
};
const keys = Object.keys(fields);
for (let i = 0, length = keys.length; i < length; i += 1) {
t.equal(json[keys[i]], fields[keys[i]]);
}
t.equal(JSON.stringify(json.fields), JSON.stringify(fields));
t.equal(json.message, 'Log event #1');
// Assert timestamp, up to hours resolution.
const date = new Date(json['@timestamp']);
t.equal(
date.toISOString().substring(0, 14),
setup.results.date.toISOString().substring(0, 14)
);
t.end();
});
batch.test('default options', (t) => {
const setup = setupLogging('myLogger', {
host: '127.0.0.1',
port: 10001,
type: 'logstashUDP',
category: 'myLogger',
layout: {
type: 'pattern',
pattern: '%m'
}
});
setup.logger.log('trace', 'Log event #1');
const json = JSON.parse(setup.results.buffer.toString());
t.equal(json.type, 'myLogger');
t.equal(
JSON.stringify(json.fields),
JSON.stringify({ level: 'TRACE', category: 'myLogger' })
);
t.end();
});
batch.test('configuration can include functions to generate field values at run-time', (t) => {
const setup = setupLogging('myCategory', {
host: '127.0.0.1',
port: 10001,
type: 'logstashUDP',
logType: 'myAppType',
category: 'myLogger',
fields: {
field1: 'value1',
field2: function () {
return 'evaluated at runtime';
}
},
layout: {
type: 'pattern',
pattern: '%m'
}
});
setup.logger.log('trace', 'Log event #1');
const json = JSON.parse(setup.results.buffer.toString());
t.equal(json.fields.field1, 'value1');
t.equal(json.fields.field2, 'evaluated at runtime');
t.end();
});
batch.test('extra fields should be added to the fields structure', (t) => {
const setup = setupLogging('myLogger', {
host: '127.0.0.1',
port: 10001,
type: 'logstashUDP',
category: 'myLogger',
layout: {
type: 'dummy'
}
});
setup.logger.log('trace', 'Log event #1', { extra1: 'value1', extra2: 'value2' });
const json = JSON.parse(setup.results.buffer.toString());
const fields = {
extra1: 'value1',
extra2: 'value2',
level: 'TRACE',
category: 'myLogger'
};
t.equal(JSON.stringify(json.fields), JSON.stringify(fields));
t.end();
});
batch.test('use direct args', (t) => {
const setup = setupLogging('myLogger', {
host: '127.0.0.1',
port: 10001,
type: 'logstashUDP',
category: 'myLogger',
args: 'direct',
layout: {
type: 'dummy'
}
});
setup.logger.log('info', 'Log event with fields', { extra1: 'value1', extra2: 'value2' });
const json = JSON.parse(setup.results.buffer.toString());
t.equal(json.extra1, 'value1');
t.equal(json.extra2, 'value2');
t.equal(json.fields, undefined);
t.end();
});
batch.test('use fields args', (t) => {
const setup = setupLogging('myLogger', {
host: '127.0.0.1',
port: 10001,
type: 'logstashUDP',
category: 'myLogger',
args: 'fields',
layout: {
type: 'dummy'
}
});
setup.logger.log('info', 'Log event with fields', { extra1: 'value1', extra2: 'value2' });
const json = JSON.parse(setup.results.buffer.toString());
t.equal(json.extra1, undefined);
t.equal(json.extra2, undefined);
t.equal(json.fields.extra1, 'value1');
t.equal(json.fields.extra2, 'value2');
t.end();
});
batch.test('Send null as argument', (t) => {
const setup = setupLogging('myLogger', {
host: '127.0.0.1',
port: 10001,
type: 'logstashUDP',
category: 'myLogger',
layout: {
type: 'dummy'
}
});
const msg = 'test message with null';
setup.logger.info(msg, null);
const json = JSON.parse(setup.results.buffer.toString());
t.equal(json.message, msg);
t.end();
});
batch.test('Send undefined as argument', (t) => {
const setup = setupLogging('myLogger', {
host: '127.0.0.1',
port: 10001,
type: 'logstashUDP',
category: 'myLogger',
layout: {
type: 'dummy'
}
});
const msg = 'test message with undefined';
setup.logger.info(msg, undefined);
const json = JSON.parse(setup.results.buffer.toString());
t.equal(json.message, msg);
t.end();
});
batch.test('shutdown should close sockets', (t) => {
const setup = setupLogging('myLogger', {
host: '127.0.0.1',
port: 10001,
type: 'logstashUDP',
category: 'myLogger',
layout: {
type: 'dummy'
}
});
setup.log4js.shutdown(() => {
t.ok(setup.socket.closed);
t.end();
});
});
batch.end();
});

17
types/log4js.d.ts vendored
View File

@ -215,22 +215,6 @@ export interface LogLevelFilterAppender {
maxLevel?: string;
}
export interface LogstashUDPAppender {
type: 'logstashUDP';
// hostname (or IP-address) of the logstash server
host: string;
// port of the logstash server
port: number;
// used for the type field in the logstash data
logType?: string;
// used for the type field of the logstash data if logType is not defined
category?: string;
// extra fields to log with each event
fields?: { [fieldname: string]: any };
// (defaults to dummyLayout) used for the message field of the logstash data
layout?: Layout;
}
export interface MailgunAppender {
type: 'mailgun';
// your mailgun API key
@ -370,7 +354,6 @@ export type Appender = CategoryFilterAppender
| LogFacesHTTPAppender
| LogFacesUDPAppender
| LogLevelFilterAppender
| LogstashUDPAppender
| MailgunAppender
| MultiFileAppender
| MultiprocessAppender