tcp.js 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. const debug = require('debug')('log4js:tcp');
  2. const net = require('net');
  3. function appender(config, layout) {
  4. let canWrite = false;
  5. const buffer = [];
  6. let socket;
  7. let shutdownAttempts = 3;
  8. let endMsg = '__LOG4JS__';
  9. function write(loggingEvent) {
  10. debug('Writing log event to socket');
  11. canWrite = socket.write(`${layout(loggingEvent)}${endMsg}`, 'utf8');
  12. }
  13. function emptyBuffer() {
  14. let evt;
  15. debug('emptying buffer');
  16. /* eslint no-cond-assign:0 */
  17. while ((evt = buffer.shift())) {
  18. write(evt);
  19. }
  20. }
  21. function createSocket() {
  22. debug(`appender creating socket to ${config.host || 'localhost'}:${config.port || 5000}`);
  23. endMsg = `${config.endMsg || '__LOG4JS__'}`;
  24. socket = net.createConnection(config.port || 5000, config.host || 'localhost');
  25. socket.on('connect', () => {
  26. debug('socket connected');
  27. emptyBuffer();
  28. canWrite = true;
  29. });
  30. socket.on('drain', () => {
  31. debug('drain event received, emptying buffer');
  32. canWrite = true;
  33. emptyBuffer();
  34. });
  35. socket.on('timeout', socket.end.bind(socket));
  36. // don't bother listening for 'error', 'close' gets called after that anyway
  37. socket.on('close', createSocket);
  38. }
  39. createSocket();
  40. function log(loggingEvent) {
  41. if (canWrite) {
  42. write(loggingEvent);
  43. } else {
  44. debug('buffering log event because it cannot write at the moment');
  45. buffer.push(loggingEvent);
  46. }
  47. }
  48. log.shutdown = function (cb) {
  49. debug('shutdown called');
  50. if (buffer.length && shutdownAttempts) {
  51. debug('buffer has items, waiting 100ms to empty');
  52. shutdownAttempts -= 1;
  53. setTimeout(() => {
  54. log.shutdown(cb);
  55. }, 100);
  56. } else {
  57. socket.removeAllListeners('close');
  58. socket.end(cb);
  59. }
  60. };
  61. return log;
  62. }
  63. function configure(config, layouts) {
  64. debug(`configure with config = ${config}`);
  65. let layout = function (loggingEvent) {
  66. return loggingEvent.serialise();
  67. };
  68. if (config.layout) {
  69. layout = layouts.layout(config.layout.type, config.layout);
  70. }
  71. return appender(config, layout);
  72. }
  73. module.exports.configure = configure;