| 'use strict'; |
| |
| const debug = require('debug')('log4js:tcp'); |
| const net = require('net'); |
| |
| function appender(config) { |
| let canWrite = false; |
| const buffer = []; |
| let socket; |
| let shutdownAttempts = 3; |
| |
| function write(loggingEvent) { |
| debug('Writing log event to socket'); |
| canWrite = socket.write(`${loggingEvent.serialise()}__LOG4JS__`, 'utf8'); |
| } |
| |
| function emptyBuffer() { |
| let evt; |
| debug('emptying buffer'); |
| /* eslint no-cond-assign:0 */ |
| while ((evt = buffer.shift())) { |
| write(evt); |
| } |
| } |
| |
| function createSocket() { |
| debug(`appender creating socket to ${config.host || 'localhost'}:${config.port || 5000}`); |
| socket = net.createConnection(config.port || 5000, config.host || 'localhost'); |
| socket.on('connect', () => { |
| debug('socket connected'); |
| emptyBuffer(); |
| canWrite = true; |
| }); |
| socket.on('drain', () => { |
| debug('drain event received, emptying buffer'); |
| canWrite = true; |
| emptyBuffer(); |
| }); |
| socket.on('timeout', socket.end.bind(socket)); |
| // don't bother listening for 'error', 'close' gets called after that anyway |
| socket.on('close', createSocket); |
| } |
| |
| createSocket(); |
| |
| function log(loggingEvent) { |
| if (canWrite) { |
| write(loggingEvent); |
| } else { |
| debug('buffering log event because it cannot write at the moment'); |
| buffer.push(loggingEvent); |
| } |
| } |
| |
| log.shutdown = function (cb) { |
| debug('shutdown called'); |
| if (buffer.length && shutdownAttempts) { |
| debug('buffer has items, waiting 100ms to empty'); |
| shutdownAttempts -= 1; |
| setTimeout(() => { |
| log.shutdown(cb); |
| }, 100); |
| } else { |
| socket.removeAllListeners('close'); |
| socket.end(cb); |
| } |
| }; |
| return log; |
| } |
| |
| function configure(config) { |
| debug(`configure with config = ${config}`); |
| return appender(config); |
| } |
| |
| module.exports.configure = configure; |