2 var log4js = require('../log4js')
4 , END_MSG = '__LOG4JS__';
7 * Creates a server, listening on config.loggerPort, config.loggerHost.
8 * Output goes to config.actualAppender (config.appender is used to
9 * set up that appender).
11 function logServer(config) {
14 * Takes a utf-8 string, returns an object with
15 * the correct log properties.
17 function deserializeLoggingEvent(clientSocket, msg) {
20 loggingEvent = JSON.parse(msg);
21 loggingEvent.startTime = new Date(loggingEvent.startTime);
22 loggingEvent.level = log4js.levels.toLevel(loggingEvent.level.levelStr);
24 // JSON.parse failed, just log the contents probably a naughty.
26 startTime: new Date(),
27 categoryName: 'log4js',
28 level: log4js.levels.ERROR,
29 data: [ 'Unable to parse log:', msg ]
33 loggingEvent.remoteAddress = clientSocket.remoteAddress;
34 loggingEvent.remotePort = clientSocket.remotePort;
39 var actualAppender = config.actualAppender,
40 server = net.createServer(function serverCreated(clientSocket) {
41 clientSocket.setEncoding('utf8');
44 function logTheMessage(msg) {
45 if (logMessage.length > 0) {
46 actualAppender(deserializeLoggingEvent(clientSocket, msg));
50 function chunkReceived(chunk) {
52 logMessage += chunk || '';
53 if (logMessage.indexOf(END_MSG) > -1) {
54 event = logMessage.substring(0, logMessage.indexOf(END_MSG));
56 logMessage = logMessage.substring(event.length + END_MSG.length) || '';
57 //check for more, maybe it was a big chunk
62 clientSocket.on('data', chunkReceived);
63 clientSocket.on('end', chunkReceived);
66 server.listen(config.loggerPort || 5000, config.loggerHost || 'localhost');
68 return actualAppender;
71 function workerAppender(config) {
78 function createSocket() {
79 socket = net.createConnection(config.loggerPort || 5000, config.loggerHost || 'localhost');
80 socket.on('connect', function() {
84 socket.on('timeout', socket.end.bind(socket));
85 //don't bother listening for 'error', 'close' gets called after that anyway
86 socket.on('close', createSocket);
89 function emptyBuffer() {
91 while ((evt = buffer.shift())) {
96 function write(loggingEvent) {
97 // JSON.stringify(new Error('test')) returns {}, which is not really useful for us.
98 // The following allows us to serialize errors correctly.
99 // Validate that we really are in this case
100 if (loggingEvent && loggingEvent.stack && JSON.stringify(loggingEvent) === '{}') {
101 loggingEvent = {stack : loggingEvent.stack};
103 socket.write(JSON.stringify(loggingEvent), 'utf8');
104 socket.write(END_MSG, 'utf8');
107 return function log(loggingEvent) {
111 buffer.push(loggingEvent);
116 function createAppender(config) {
117 if (config.mode === 'master') {
118 return logServer(config);
120 return workerAppender(config);
124 function configure(config, options) {
126 if (config.appender && config.mode === 'master') {
127 log4js.loadAppender(config.appender.type);
128 actualAppender = log4js.appenderMakers[config.appender.type](config.appender, options);
129 config.actualAppender = actualAppender;
131 return createAppender(config);
134 exports.appender = createAppender;
135 exports.configure = configure;