UNPKG

@kumologica/kumologica-contrib-splunk

Version:
130 lines (113 loc) 4.47 kB
module.exports = function (App) { const { KLNode } = require('@kumologica/devkit'); class SplunkError extends Error { constructor(error) { super(error); this.originalError = error; } } class SplunkConnectionError extends SplunkError { constructor(error) { super(error); this.name = 'SplunkConnectionError'; this.message = 'Error connecting to the splunk server with provided connection params.'; this.statusCode = 408; } } class SplunkInvalidTokenError extends SplunkError { constructor(error) { super(error); this.name = 'SplunkInvalidTokenError'; this.message = 'Token supplied for connecting to Splunk is invalid.'; this.statusCode = 400; } } class SplunkDataWriteError extends SplunkError { constructor(error) { super(error); this.name = 'SplunkDataWriteError'; this.message = 'Error occurred while trying to write data to Splunk.' this.statusCode = 400; } } class KumologicaSplunkNode extends KLNode { constructor(props) { super(App, props); this.nodeConfig = props; this.typeValues = null; this.splunkLogger = null; this.messageToProcess = null; this.consoleOutput = props.consoleOutput || false; } handle(msg) { this.processMsg(msg); } processMsg(msg) { this.messageToProcess = msg; // Resolve dynamic expressions let splunkHost = App.util.evaluateDynamicField(this.nodeConfig.splunkHost, this.messageToProcess, this); let splunkPort = App.util.evaluateDynamicField(this.nodeConfig.splunkPort, this.messageToProcess, this); let hecToken = App.util.evaluateDynamicField(this.nodeConfig.hecToken, this.messageToProcess, this); let logMessage = App.util.evaluateDynamicField(this.nodeConfig.splunkLogData, this.messageToProcess, this); // Instantiate splunk logger (lazyily) let splunkLogger = this.getSplunkLogger({ token: hecToken, url: `https://${splunkHost}:${splunkPort}` }); // Send message to console if required if (this.nodeConfig.consoleOutput) { let level = this.nodeConfig.level || 'info'; switch (level) { case 'info': this.info(logMessage); break; case 'debug': this.debug(logMessage); break; case 'warn': this.warn(logMessage); break; case 'error': this.error(logMessage); break; default: this.log(logMessage); } } // Send message to splunk instance let metadata = {}; if (this.nodeConfig.metaSource){ metadata.source = App.util.evaluateDynamicField(this.nodeConfig.metaSource, this.messageToProcess, this); } if (this.nodeConfig.metaSourceType){ metadata.sourcetype = App.util.evaluateDynamicField(this.nodeConfig.metaSourceType, this.messageToProcess, this); } if (this.nodeConfig.metaHost){ metadata.host = App.util.evaluateDynamicField(this.nodeConfig.metaHost, this.messageToProcess, this); } if (this.nodeConfig.metaIndex){ metadata.index = App.util.evaluateDynamicField(this.nodeConfig.metaIndex, this.messageToProcess, this); } let payload = { message: logMessage, severity: this.nodeConfig.level || 'info', metadata: metadata } splunkLogger.send(payload, (error, response, body) => { if (error) { if (error.code == 'ETIMEDOUT' || error.code == 'ENOTFOUND') { this.sendError(new SplunkConnectionError(error), this.messageToProcess); } } else if (body && body.text == 'Invalid token') { this.sendError(new SplunkInvalidTokenError(new Error()), this.messageToProcess); } else { if (response && JSON.parse(response.body).text == 'Success') { this.send(this.messageToProcess); } else { this.sendError(new SplunkDataWriteError(new Error()), this.messageToProcess); } } }); } getSplunkLogger(config) { let SplunkLogger = require("splunk-logging").Logger; return new SplunkLogger({ token: config.token, url: config.url, maxRetries: 2 }); } } App.nodes.registerType('splunk', KumologicaSplunkNode); };