mirror of
https://github.com/log4js-node/log4js-node.git
synced 2025-12-08 19:26:01 +00:00
Merge pull request #683 from log4js-node/remove-logstash
chore: remove logstash udp
This commit is contained in:
commit
4d30f6ea2e
@ -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
|
||||
|
||||
@ -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;
|
||||
@ -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
17
types/log4js.d.ts
vendored
@ -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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user