0

我正在尝试修改一个名为“splunk-logger”的 Node.js 函数。问题是当 SNS 消息进入函数时,来自防病毒 (Trend Micro DeepSecurity) 控制台的事件被组合在一起。我已经联系了他们的支持,他们说这只是发送事件的方式,他们无能为力。

示例:{消息 {Event_1} {Event_2} {Event_3}}

现在 JavaScript 函数运行良好,事件被转发到 Splunk。但是,由于它们甚至在它们到达 Lambda 函数之前就被组合在一起,因此 Splunk 将它们视为 1 个单个事件而不是 3 个。

我的想法是获取“事件”变量(因为它包含sns“消息”)并解析它以分离每个事件(可能使用正则表达式或其他东西)。然后,我可以创建另一个函数来立即发送每个事件,或者简单地调用“logger.flushAsync”函数来发送它们。

链接到 splunk-dev 解释功能:http: //dev.splunk.com/view/event-collector/SP-CAAAAE6Y#create

下面是 index.js 中的代码:

const loggerConfig = {
    url: process.env.SPLUNK_HEC_URL,
    token: process.env.SPLUNK_HEC_TOKEN,
};
const SplunkLogger = require('./lib/mysplunklogger');
const logger = new SplunkLogger(loggerConfig);
exports.handler = (event, context, callback) => {
    console.log('Received event:', JSON.stringify(event, null, 2));
// Log JSON objects to Splunk
    logger.log(event);
// Send all the events in a single batch to Splunk
    logger.flushAsync((error, response) => {
        if (error) {
            callback(error);
        } else {
            console.log(`Response from Splunk:\n${response}`);
            callback(null, event.key1); // Echo back the first key value
        }
    });
};

这是 mysplunklogger.js 文件中的代码。

'use strict';

const url = require('url');

const Logger = function Logger(config) {
    this.url = config.url;
    this.token = config.token;

    this.addMetadata = true;
    this.setSource = true;

    this.parsedUrl = url.parse(this.url);
    // eslint-disable-next-line import/no-dynamic-require
    this.requester = require(this.parsedUrl.protocol.substring(0, this.parsedUrl.protocol.length - 1));
    // Initialize request options which can be overridden & extended by consumer as needed
    this.requestOptions = {
        hostname: this.parsedUrl.hostname,
        path: this.parsedUrl.path,
        port: this.parsedUrl.port,
        method: 'POST',
        headers: {
            Authorization: `Splunk ${this.token}`,
        },
        rejectUnauthorized: false,
    };

    this.payloads = [];
};

// Simple logging API for Lambda functions
Logger.prototype.log = function log(message, context) {
    this.logWithTime(Date.now(), message, context);
};

Logger.prototype.logWithTime = function logWithTime(time, message, context) {
    const payload = {};

    if (Object.prototype.toString.call(message) === '[object Array]') {
        throw new Error('message argument must be a string or a JSON object.');
    }
    payload.event = message;

    // Add Lambda metadata
    if (typeof context !== 'undefined') {
        if (this.addMetadata) {
            // Enrich event only if it is an object
            if (message === Object(message)) {
                payload.event = JSON.parse(JSON.stringify(message)); // deep copy
                payload.event.awsRequestId = context.awsRequestId;
            }
        }
        if (this.setSource) {
            payload.source = `lambda:${context.functionName}`;
        }
    }

    payload.time = new Date(time).getTime() / 1000;

    this.logEvent(payload);
};

Logger.prototype.logEvent = function logEvent(payload) {
    this.payloads.push(JSON.stringify(payload));
};

Logger.prototype.flushAsync = function flushAsync(callback) {
    callback = callback || (() => {}); // eslint-disable-line no-param-reassign

    console.log('Sending event(s)');
    const req = this.requester.request(this.requestOptions, (res) => {
        res.setEncoding('utf8');

        console.log('Response received');
        res.on('data', (data) => {
            let error = null;
            if (res.statusCode !== 200) {
                error = new Error(`error: statusCode=${res.statusCode}\n\n${data}`);
                console.error(error);
            }
            this.payloads.length = 0;
            callback(error, data);
        });
    });

    req.on('error', (error) => {
        callback(error);
    });

    req.end(this.payloads.join(''), 'utf8');
};

module.exports = Logger;
4

2 回答 2

1
import requests
import re
import json
import os

def lambda_handler(event, context):

    data = json.dumps(event)

    EventIds = re.findall(r'{\\\".+?\\\"}', data)
    EventLength = len(EventIds)

    headers = {'Authorization': 'Splunk ' + os.environ['SPLUNK_HEC_TOKEN']}

    i = 0
    while i < EventLength:
        response = requests.post(os.environ['SPLUNK_HEC_URL'], headers=headers, json={"event":EventIds[i]}, verify=True)
    i+=1
于 2018-12-02T06:42:22.463 回答
0

数组是趋势科技服务器深度安全防护系统 10.0 或更高版本向 Amazon SNS 发送事件时使用的数据类型。但是 Splunk 希望每条消息都有一个事件。所以不要直接发送数组。

相反,使用 Splunk 记录器或 Lambda 遍历数组,将每个项目作为单独的消息发送。您可以为 Node.js 修改此示例 Lambda 脚本:

https://github.com/deep-security/amazon-sns/blob/master/lambda-save-ds-event-to-s3.js

它单独将事件发送到 S3(这是您需要的)。只需将其更改为发送到 Splunk。

披露:我为趋势科技工作。

于 2018-11-29T15:37:28.703 回答