Create a Lambda function using the splunk-logging blueprint (Node.js)

This topic describes how to use the AWS Lambda blueprint "splunk-logging" from the AWS Lambda Management Console to create a Node.js Lambda function for sending data to Splunk Enterprise via HTTP Event Collector (HEC).

Note: Be careful when sending data from AWS to an on-premises Splunk Enterprise instance. Sending large amounts of data could result in excessive egress costs and unacceptable latency.

This topic contains the following sections:

Creating a Lambda function using the blueprint

This section guides you through the creation of a new AWS Lambda Node.js function using the HEC blueprint. The basic steps are as follows:

Note: As of this writing, there are five AWS Lambda blueprints that send data to HEC. This topic describes the first one, but the rest comprise similar workflows. Following are direct links to each of the blueprints. They require you to log into the AWS Management Console:

Configure HTTP Event Collector

Do the following in Splunk Enterprise (or self-service Splunk Cloud) before creating a new HEC Lambda function using a blueprint:

  • Enable HTTP Event Collector in Splunk Enterprise (or self-service Splunk Cloud):
    • For Splunk Enterprise or self-service Splunk Cloud, first go to Settings > Data inputs > HTTP Event Collector, and then click Global Settings. Click the Enable button, and then click Save. For more information, see "Enable HTTP Event Collector" in the Getting Data In manual.
    • For managed Splunk Cloud, submit a support ticket to have the feature enabled.
  • Create at least one input token. You'll need this token later in this procedure.
    • For Splunk Enterprise or self-service Splunk Cloud, go to Settings > Data inputs > HTTP Event Collector and click the New Token button. Proceed through the Add Data workflow until you've successfully created a token. For more information, see Create an Event Collector token in the Getting Data In manual.
    • For managed Splunk Cloud, submit a support ticket to create or manage a token.
Note: To avoid excess egress costs and latency, run your Lambda function in the same AWS Region as your Splunk Cloud instance. For more information about AWS regions and regional endpoints, see Regions and Endpoints in AWS General Reference.

Select and configure the blueprint

Next, you'll select the splunk-logging AWS Lambda blueprint.

  1. Log onto the AWS Management Console, and under Compute, click Lambda.

  2. Click Create a Lambda function.

  3. On the Select blueprint page, type splunk into the Filter field, and then choose the splunk-logging blueprint.

    Screen shot of the Select blueprint page.

  4. On the Configure triggers page, you can add a trigger to invoke your function, such as AWS S3 or API Gateway. Listed on this page are the various supported event sources for Lambda. Click Next for now, as you can configure the specific event source after you have configured the function itself in following step.

    Screen shot of the Configure triggers page.

  5. On the Configure function page, name your function. Optionally, change the description to fit what you'll be doing with the function.

    Screen shot of the Configure function page.

  6. In the Runtime pop-up menu, leave Node.js 4.3 as the choice.

  7. Under Lambda function code, leave Code entry type set to Edit code inline. Scroll downward, and then set the following environment variables to configure your Lambda function:

    • SPLUNK_HEC_URL: Enter the URL for your HTTP Event Collector endpoint. For example, <splunk_host>/services/collector. Replace <splunk_host> with the full hostname and HEC port, changing the protocol (HTTP or HTTPS) if necessary. Be sure to include the port you've assigned to HEC (8088 by default), and not the Splunk Web port (8000).
    • SPLUNK_HEC_TOKEN: Paste the HEC token that you created above.

Edit the code

After you choose the Edit code inline option, the editor appears above the Environment variables section with some pre-filled code. This code is a blueprint that sends some sample events to HEC in Splunk Enterprise or Splunk Cloud. You can edit this blueprint to add your own logic.

If you examine the code in more detail, you'll see the following basic functionality.

  1. We initially define a loggerConfig variable, which takes in the values of the environment variables SPLUNK_HEC_URL and SPLUNK_HEC_TOKEN to set the corresponding attributes url and token. While you can optionally hardcode these values directly inline, using the environment variables is highly recommended to avoid storing any sensitive settings as part of the function code itself.

  2. We define a logger object (Logger) to assemble (using the log(), logWithTime() or logEvent() functions) and send (using the flushAsync() function) the events.

  3. Next, we instantiate the logger (logger), which is immediately available upon function loading to log any event or message both during initial function load time or per function invocation inside the event handler explained below.

    const logger = new SplunkLogger(loggerConfig);
  4. Finally, we have our event handler, which uses logger. Every time the handler is invoked, logger is used to log . The handler function is passed three parameters: event, which contains the actual event data, context, which contains contextual information such as the AWS request ID, and callback which is used to return results back to the caller indicating success or failure. The context parameter corresponds to Lambda context object. The callback parameter corresponds to Lambda callback method. You can update the content of the handler to log event data however you want.

  5. exports.handler = (event, context, callback) => {
        // Log strings
        logger.log(`value1 = ${event.key1}`, context);
        logger.log(`value2 = ${event.key2}`, context);
        logger.log(`value3 = ${event.key3}`, context);
    
        // Log JSON objects
        logger.log(event);
    
        // Log JSON objects with optional 'context' argument to add Lambda metadata e.g. awsRequestId, functionName
        logger.log(event, context);
    
        // Specify the timestamp explicitly, useful for forwarding events with embedded
        // timestamps like from AWS IoT, AWS Kinesis, AWS CloudWatch Logs
        // Change "Date.now()" below to event timestamp if specified in event payload
        logger.logWithTime(Date.now(), event, context);
    
        // 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
            }
        });
    };
    
    Note: For more information about the Lambda function programming model in Node.js, see Programming Model (Node.js) in the AWS Lambda Developer Guide.

    You have the option to log either strings or entire JSON objects (key/value pairs). In both cases, you use the log() function.

    In addition to the log() function, we've also defined an optional function, logWithTime(), to log each event with an explicit timestamp. Otherwise, with log(), events are logged with current time of execution by Lambda. The logWithTime() function is useful when forwarding events with embedded timestamps like from AWS Kinesis, AWS CloudWatch Logs and AWS IoT.

    Both log() and logWithTime() accept an additional optional context argument, which is expected to be the same context object passed to the event handler function. Only when passing down the context object, then Lambda metadata such as awsRequestId will be added to the event payload, and the event source will be set to lambda:<functionName> automatically. For example:

    logger.log(event, context);
    logger.logWithTime(event.timestamp, event, context); // assuming time is embedded in event payload as event.timestamp
    

    For more control over setting all metadata such as host, source, sourcetype, and index on a per-event basis, another lower level function, logEvent(), is available instead of the above high-level convenience functions. For example:

    logger.logEvent({
      time: 1479885847,
      event: event,
      host: "myhost",
      source: "mysource",
      sourcetype: "mysourcetype",
      index: "myindex",
    });
    

    For complete list of request parameters you can send as part of the HEC event payload, see the services/collector endpoint reference documentation.

    The logger doesn't actually send data until the flushAsync() function is called. Therefore, logger is simply packaging and batching the event data as it repeatedly calls the log() (or logWithTime() or logEvent()) function. Calling flushAsync() sends the batched event data. The flushAsync() function expects a function argument as a callback with arguments error and response. An error argument will hold any request error; if the request is successful, error will be null and response will hold a Splunk response payload.

    The callback method that was passed into the handler function is used to indicate success or failure to the Lambda function caller. In the blueprint, upon failure of flushAsync(), callback(error) is called to indicate failure with error information returned to the caller. Upon successful flushAsync(), callback(null, result) is called to indicate success, with its result being the key1 value of the test event. You can change the result value to any other information useful for the caller.

Save the Lambda function

  1. Under Lambda function handler and role, leave the Handler field set to index.handler.

  2. From the Role pop-up menu, choose lambda_basic_execution under Use existing role.

  3. Leave the Advanced settings section as is, and then click Next.

  4. On the Review page, review your settings. If you have to make any changes, click the Edit button. When you're done, click Create function.

    Screen shot of an AWS Lambda function successful creation page.

Test the Lambda function

To test your new Lambda function, click the Test button.

  1. You'll need to use sample event data for this function. Choose the "Hello World" sample event template from the Actions -> Configure test event popup menu. You can change any of the values you want to in the edit window. Then click Submit. If the execution succeeded, you'll see a screen like the following:

    Screen shot showing successful test event transmission.

  2. Now, log into Splunk Enterprise or Splunk Cloud and search for the data using the index or sourcetype you specified when creating the new token. For example, if you created a new token with default settings just for this walkthrough, search for index=main and sourcetype=httpevent. If you haven't changed the blueprint code, you'll see six events indexed corresponding to each of the log calls in the handler function:

    Screen shot of Splunk Enterprise or Splunk Cloud search app showing search results matching the events that were transmitted by AWS Lambda.

Each event has been logged.

Next steps

The HEC blueprint code represents a working template for getting data from your AWS services to Splunk Enterprise or Splunk Cloud using HTTP Event Collector.