All files / log4js-logstash-tcp index.js

85.1% Statements 40/47
57.14% Branches 24/42
100% Functions 9/9
85.1% Lines 40/47

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123    1x   1x   1x 1x 1x             3x       3x   3x         3x 3x                     3x 3x                                 3x 3x 9x     3x 2x 1x   2x 2x               3x 2x 2x 2x 2x         3x 3x   3x                 3x 3x 17x     3x     3x 3x     3x       3x 3x     3x     3x     1x  
'use strict';
 
const TcpConnectionPool = require("./classes/TcpConnectionPool").TcpConnectionPool;
 
const tcpConnectionPool = new TcpConnectionPool();
 
let apm = false;
try {
    apm = require('elastic-apm-node');
} catch(e) {
    // ignore APM if it's not loaded
}
 
 
function sendLog(host, port, logObject) {
    tcpConnectionPool.send(host, port, logObject);
}
 
function logstashTCP(config, layout) {
    const type = config.logType ? config.logType : config.category;
 
    Iif (!config.fields) {
        config.fields = {};
    }
 
    function checkArgs(argsValue, logUnderFields) {
        Eif ((!argsValue) || (argsValue === 'both')) {
            return true;
        }
 
        if (logUnderFields && (argsValue === 'fields')) {
            return true;
        }
 
        return (!logUnderFields) && (argsValue === 'direct');
    }
 
    function log(loggingEvent) {
        let currentAPMTransaction = false
        Iif(apm && apm.currentTransaction) {
            currentAPMTransaction = apm.currentTransaction
        }
 
        /*
         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];
        });
        // adding context to log messages as separate fields added by logger.addContext(key, value)
        if(loggingEvent.context) {
            if(loggingEvent.data.length === 1 || !loggingEvent.data[1]) {
                loggingEvent.data[1] = {}
            }
            Eif(typeof loggingEvent.data[1] === 'object') {
                loggingEvent.data[1] = {
                    ...loggingEvent.context,
                    ...loggingEvent.data[1]
                }
            }
        }
 
        /* eslint no-prototype-builtins:1,no-restricted-syntax:[1, "ForInStatement"] */
        if (loggingEvent.data.length > 1) {
            const secondEvData = loggingEvent.data[1];
            Eif ((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(),
            // this allows to show logs generated by logging events together with APM events
            ...(currentAPMTransaction.ids || {}),
            type: type,
            message: layout(loggingEvent)//.data[0]
        };
 
        Eif (checkArgs(config.args, false)) {
            Object.keys(fields).forEach((key) => {
                logObject[key] = fields[key];
            });
        }
        sendLog(config.host, config.port, logObject);
    }
 
    log.shutdown = function (cb) {
        tcpConnectionPool.close(cb);
    };
 
    return log;
}
 
function configure(config, layouts) {
    let layout = layouts.dummyLayout;
    Iif (config.layout) {
        layout = layouts.layout(config.layout.type, config.layout);
    }
    Iif(!layout) {
        throw new Error('wrong and/or unknown layout chosen in log4js configuration', config.layout);
    }
    return logstashTCP(config, layout);
}
 
module.exports.configure = configure;