mirror of
https://github.com/log4js-node/log4js-node.git
synced 2025-12-08 19:26:01 +00:00
feat: TCP appender - enabling a custom EndMsg token and a custom Layout
This commit is contained in:
parent
7f540a8bb8
commit
ceae893896
@ -7,6 +7,8 @@ The TCP appender sends log events to a master server over TCP sockets. It can be
|
||||
* `type` - `tcp`
|
||||
* `port` - `integer` (optional, defaults to `5000`) - the port to send to
|
||||
* `host` - `string` (optional, defaults to `localhost`) - the host/IP address to send to
|
||||
* `endMsg` - `string` (optional, defaults to `__LOG4JS__`) - the delimiter that marks the end of a log message
|
||||
* `layout` - `object` (optional, defaults to a serialized log event) - see [layouts](layouts.md)
|
||||
|
||||
## Example
|
||||
```javascript
|
||||
|
||||
@ -3,15 +3,16 @@
|
||||
const debug = require('debug')('log4js:tcp');
|
||||
const net = require('net');
|
||||
|
||||
function appender(config) {
|
||||
function appender(config, layout) {
|
||||
let canWrite = false;
|
||||
const buffer = [];
|
||||
let socket;
|
||||
let shutdownAttempts = 3;
|
||||
let endMsg = '__LOG4JS__';
|
||||
|
||||
function write(loggingEvent) {
|
||||
debug('Writing log event to socket');
|
||||
canWrite = socket.write(`${loggingEvent.serialise()}__LOG4JS__`, 'utf8');
|
||||
canWrite = socket.write(`${layout(loggingEvent)}${endMsg}`, 'utf8');
|
||||
}
|
||||
|
||||
function emptyBuffer() {
|
||||
@ -25,6 +26,7 @@ function appender(config) {
|
||||
|
||||
function createSocket() {
|
||||
debug(`appender creating socket to ${config.host || 'localhost'}:${config.port || 5000}`);
|
||||
endMsg = `${config.endMsg || '__LOG4JS__'}`;
|
||||
socket = net.createConnection(config.port || 5000, config.host || 'localhost');
|
||||
socket.on('connect', () => {
|
||||
debug('socket connected');
|
||||
@ -68,9 +70,15 @@ function appender(config) {
|
||||
return log;
|
||||
}
|
||||
|
||||
function configure(config) {
|
||||
function configure(config, layouts) {
|
||||
debug(`configure with config = ${config}`);
|
||||
return appender(config);
|
||||
let layout = function (loggingEvent) {
|
||||
return loggingEvent.serialise();
|
||||
};
|
||||
if (config.layout) {
|
||||
layout = layouts.layout(config.layout.type, config.layout);
|
||||
}
|
||||
return appender(config, layout);
|
||||
}
|
||||
|
||||
module.exports.configure = configure;
|
||||
|
||||
@ -3,39 +3,57 @@ const net = require("net");
|
||||
const log4js = require("../../lib/log4js");
|
||||
const LoggingEvent = require("../../lib/LoggingEvent");
|
||||
|
||||
const messages = [];
|
||||
const server = net.createServer(socket => {
|
||||
socket.setEncoding("utf8");
|
||||
socket.on("data", data => {
|
||||
data
|
||||
.split("__LOG4JS__")
|
||||
.filter(s => s.length)
|
||||
.forEach(s => {
|
||||
messages.push(LoggingEvent.deserialise(s));
|
||||
});
|
||||
let messages = [];
|
||||
let server = null;
|
||||
|
||||
function makeServer(config) {
|
||||
|
||||
server = net.createServer(socket => {
|
||||
socket.setEncoding("utf8");
|
||||
|
||||
socket.on("data", data => {
|
||||
data
|
||||
.split(config.endMsg)
|
||||
.filter(s => s.length)
|
||||
.forEach(s => {
|
||||
messages.push(config.deserialise(s));
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
server.unref();
|
||||
server.unref();
|
||||
|
||||
server.listen(() => {
|
||||
const { port } = server.address();
|
||||
log4js.configure({
|
||||
appenders: {
|
||||
tcp: { type: "tcp", port }
|
||||
},
|
||||
categories: {
|
||||
default: { appenders: ["tcp"], level: "debug" }
|
||||
return server;
|
||||
}
|
||||
|
||||
test("TCP Appender", batch => {
|
||||
|
||||
batch.test("Default Configuration", t => {
|
||||
messages = [];
|
||||
|
||||
const serverConfig = {
|
||||
endMsg: "__LOG4JS__",
|
||||
deserialise: (log) => { return LoggingEvent.deserialise(log); }
|
||||
}
|
||||
});
|
||||
server = makeServer(serverConfig);
|
||||
|
||||
const logger = log4js.getLogger();
|
||||
logger.info("This should be sent via TCP.");
|
||||
logger.info("This should also be sent via TCP and not break things.");
|
||||
log4js.shutdown(() => {
|
||||
server.close(() => {
|
||||
test("TCP Appender", batch => {
|
||||
batch.test("should send log messages as JSON over TCP", t => {
|
||||
server.listen(() => {
|
||||
const { port } = server.address();
|
||||
log4js.configure({
|
||||
appenders: {
|
||||
default: { type: "tcp", port },
|
||||
},
|
||||
categories: {
|
||||
default: { appenders: ["default"], level: "debug" },
|
||||
}
|
||||
});
|
||||
|
||||
const logger = log4js.getLogger();
|
||||
logger.info("This should be sent via TCP.");
|
||||
logger.info("This should also be sent via TCP and not break things.");
|
||||
|
||||
log4js.shutdown(() => {
|
||||
server.close(() => {
|
||||
t.equal(messages.length, 2);
|
||||
t.match(messages[0], {
|
||||
data: ["This should be sent via TCP."],
|
||||
@ -51,8 +69,109 @@ server.listen(() => {
|
||||
});
|
||||
t.end();
|
||||
});
|
||||
batch.end();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
batch.test("Custom EndMessage String", t => {
|
||||
messages = [];
|
||||
|
||||
const serverConfig = {
|
||||
endMsg: "\n",
|
||||
deserialise: (log) => { return LoggingEvent.deserialise(log); }
|
||||
}
|
||||
server = makeServer(serverConfig);
|
||||
|
||||
server.listen(() => {
|
||||
const { port } = server.address();
|
||||
log4js.configure({
|
||||
appenders: {
|
||||
customEndMsg: { type: "tcp", port, endMsg: "\n" },
|
||||
},
|
||||
categories: {
|
||||
default: { appenders: ["customEndMsg"], level: "debug" },
|
||||
}
|
||||
});
|
||||
|
||||
const logger = log4js.getLogger();
|
||||
logger.info("This should be sent via TCP using a custom EndMsg string.");
|
||||
logger.info("This should also be sent via TCP using a custom EndMsg string and not break things.");
|
||||
|
||||
log4js.shutdown(() => {
|
||||
server.close(() => {
|
||||
t.equal(messages.length, 2);
|
||||
t.match(messages[0], {
|
||||
data: ["This should be sent via TCP using a custom EndMsg string."],
|
||||
categoryName: "default",
|
||||
context: {},
|
||||
level: { levelStr: "INFO" }
|
||||
});
|
||||
t.match(messages[1], {
|
||||
data: ["This should also be sent via TCP using a custom EndMsg string and not break things."],
|
||||
categoryName: "default",
|
||||
context: {},
|
||||
level: { levelStr: "INFO" }
|
||||
});
|
||||
t.end();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
batch.test("Custom Layout", t => {
|
||||
messages = [];
|
||||
|
||||
const serverConfig = {
|
||||
endMsg: "__LOG4JS__",
|
||||
deserialise: (log) => { return JSON.parse(log); }
|
||||
}
|
||||
server = makeServer(serverConfig);
|
||||
|
||||
log4js.addLayout('json', function () {
|
||||
return function (logEvent) {
|
||||
return JSON.stringify({
|
||||
"time": logEvent.startTime,
|
||||
"message": logEvent.data[0],
|
||||
"level": logEvent.level.toString()
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
server.listen(() => {
|
||||
const { port } = server.address();
|
||||
log4js.configure({
|
||||
appenders: {
|
||||
customLayout: {
|
||||
type: "tcp", port,
|
||||
layout: { type: 'json' }
|
||||
},
|
||||
},
|
||||
categories: {
|
||||
default: { appenders: ["customLayout"], level: "debug" },
|
||||
}
|
||||
});
|
||||
|
||||
const logger = log4js.getLogger();
|
||||
logger.info("This should be sent as a customized json.");
|
||||
logger.info("This should also be sent via TCP as a customized json and not break things.");
|
||||
|
||||
log4js.shutdown(() => {
|
||||
server.close(() => {
|
||||
t.equal(messages.length, 2);
|
||||
t.match(messages[0], {
|
||||
message: "This should be sent as a customized json.",
|
||||
level: "INFO"
|
||||
});
|
||||
t.match(messages[1], {
|
||||
message: "This should also be sent via TCP as a customized json and not break things.",
|
||||
level: "INFO"
|
||||
});
|
||||
t.end();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
batch.end();
|
||||
});
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user