UNPKG

log4js

Version:
121 lines (100 loc) 3.29 kB
/* eslint no-prototype-builtins:1,no-restricted-syntax:[1, "ForInStatement"] */ 'use strict'; const debug = require('debug')('log4js:loggly'); const loggly = require('loggly'); const os = require('os'); function isAnyObject(value) { return value !== null && (typeof value === 'object' || typeof value === 'function'); } function numKeys(obj) { return Object.keys(obj).length; } /** * @param msgListArgs * @returns Object{ deTaggedMsg: [...], additionalTags: [...] } */ function processTags(msgListArgs) { const msgList = (msgListArgs.length === 1 ? [msgListArgs[0]] : msgListArgs); return msgList.reduce((accumulate, element) => { if (isAnyObject(element) && Array.isArray(element.tags) && numKeys(element) === 1) { accumulate.additionalTags = accumulate.additionalTags.concat(element.tags); } else { accumulate.deTaggedData.push(element); } return accumulate; }, { deTaggedData: [], additionalTags: [] }); } /** * Loggly Appender. Sends logging events to Loggly using node-loggly, optionally adding tags. * * This appender will scan the msg from the logging event, and pull out any argument of the * shape `{ tags: [] }` so that it's possible to add tags in a normal logging call. * * For example: * * logger.info({ tags: ['my-tag-1', 'my-tag-2'] }, 'Some message', someObj, ...) * * And then this appender will remove the tags param and append it to the config.tags. * * @param config object with loggly configuration data * { * token: 'your-really-long-input-token', * subdomain: 'your-subdomain', * tags: ['loggly-tag1', 'loggly-tag2', .., 'loggly-tagn'] * } * @param layout a function that takes a logevent and returns a string (defaults to objectLayout). */ function logglyAppender(config, layout) { const client = loggly.createClient(config); let openRequests = 0; let shutdownCB; debug('creating appender.'); function app(loggingEvent) { const result = processTags(loggingEvent.data); const deTaggedData = result.deTaggedData; const additionalTags = result.additionalTags; // Replace the data property with the deTaggedData loggingEvent.data = deTaggedData; const msg = layout(loggingEvent); openRequests += 1; debug('sending log event to loggly'); client.log( { msg: msg, level: loggingEvent.level.levelStr, category: loggingEvent.categoryName, hostname: os.hostname().toString(), }, additionalTags, (error) => { if (error) { console.error('log4js.logglyAppender - error occurred: ', error); } debug('log event received by loggly.'); openRequests -= 1; if (shutdownCB && openRequests === 0) { shutdownCB(); shutdownCB = undefined; } } ); } app.shutdown = function (cb) { debug('shutdown called'); if (openRequests === 0) { cb(); } else { shutdownCB = cb; } }; return app; } function configure(config, layouts) { let layout = layouts.messagePassThroughLayout; if (config.layout) { layout = layouts.layout(config.layout.type, config.layout); } debug('configuring new appender'); return logglyAppender(config, layout); } module.exports.configure = configure;