Title

Easily Create Mod Inputs Using Splunk Add-on Builder 2.0 – Part IV

Description

Steps to leverage the Splunk Add-On Builder 2.0 to create custom codes and modular inputs.

Image

Template

Article

Author

Splunk

Author URL

/en_us/blog/author/admin

Tags

Category

Tips & Tricks

Published

December 07, 2016

Read Time

9 Minute Read

# encoding = utf-8

import os

import sys

import time

import datetime

IMPORTANT

Edit only the validate_input and collect_events functions.

Do not edit any other part in this file.

This file is generated only once when creating

the modular input.

def validate_input(helper, definition):

“””Implement your own validation logic to validate the input stanza configurations”””

# This example accesses the modular input variable

# query_max = definition.parameters.get(‘query_max’, None)

pass

def collect_events(helper, inputs, ew):

“””Implement your data collection logic here”””

# The following example accesses the configurations and arguments

# Get the arguments of this input

# opt_query_max = helper.get_arg(‘query_max’)

# Get options from setup page configuration

# Get the loglevel from the setup page

# loglevel = helper.get_log_level()

# Proxy setting configuration

# proxy_settings = helper.get_proxy()

# User credentials

# account = helper.get_user_credential(“username”)

# Global variable configuration

# global_api_uri_base = helper.get_global_setting(“api_uri_base”)

# global_api_version = helper.get_global_setting(“api_version”)

# Write to the log for this modular input

# helper.log_error(“log message”)

# helper.log_info(“log message”)

# helper.log_debug(“log message”)

# Set the log level for this modular input

# helper.set_log_level(‘debug’)

# helper.set_log_level(‘info’)

# helper.set_log_level(‘warning’)

# helper.set_log_level(‘error’)

# helper function to send http request

# response = helper.send_http_request(url, method, parameters=None, payload=None,

# headers=None, cookies=None, verify=True, cert=None, timeout=None, use_proxy=True)

# get the response headers

# r_headers = response.headers

# get the response body as text

# r_text = response.text

# get response body as json. If the body text is not a json string, raise a ValueError

# r_json = response.json()

# get response cookies

# r_cookies = response.cookies

# get redirect history

# historical_responses = response.history

# get response status code

# r_status = response.status_code

# check the response status, if the status is not sucessful, raise requests.HTTPError

# response.raise_for_status()

#

# checkpoint related helper functions

# save checkpoint

# helper.save_check_point(key, state)

# delete checkpoint

# helper.delete_check_point(key)

# get checkpoint

# state = helper.get_check_point(key)

#

”’

# The following example writes a random number as an event

import random

data = str(random.randint(0,100))

event = helper.new_event(source=helper.get_input_name(), index=helper.get_output_index(), sourcetype=helper.get_sourcetype(), data=data)

try:

ew.write_event(event)

except Exception as e:

raise e

”’

# encoding = utf-8import osimport sysimport timeimport datetime'''    IMPORTANT    Edit only the validate_input and collect_events functions.    Do not edit any other part in this file.    This file is generated only once when creating    the modular input.'''def validate_input(helper, definition):    """Implement your own validation logic to validate the input stanza configurations"""    # This example accesses the modular input variable    # query_max = definition.parameters.get('query_max', None)    passdef collect_events(helper, inputs, ew):  # We import json library for use in massaging data before writing the event  import json    # Return all the stanzas (per step #6)  stanzas = helper.input_stanzas    # Iterate through each defined Stanza (per step #6)  # NB: I only ident this with two spaces so I don't have to re-ident everything else  for stanza in stanzas:          # Another two-space identation keeps all the "give-me" code from step #7 in-play     # without more indenting exercises    helper.log_info('current stanza is: {}'.format(stanza))        """Implement your data collection logic here"""    # The following example accesses the args per defined input    opt_query_max = helper.get_arg('query_max')    # Test mode will yield single instance value, but once deployed,     # args are returned in dictionary so we take either one    if type(opt_query_max) == dict:        opt_query_max = int(opt_query_max[stanza])    else:        opt_query_max = int(opt_query_max)    # Fetch global variable configuration (add-on setup page vars)    # same as above regarding dictionary check    global_api_uri_base = helper.get_global_setting("api_uri_base")    if type(global_api_uri_base) == dict:        global_api_uri_base = global_api_uri_base[stanza]    global_api_version = helper.get_global_setting("api_version")    if type(global_api_version) == dict:        global_api_version = global_api_version[stanza]            # now we construct the actual URI from those global vars    api_uri = '/'.join([global_api_uri_base, 'v' + global_api_version])    helper.log_info('api uri: {}'.format(api_uri))    # set method & define url for initial API query    method = 'GET'    url = '/'.join([api_uri, 'maxitem.json?print=pretty'])    # submit query    response = helper.send_http_request(url, method, parameters=None, payload=None,                              headers=None, cookies=None, verify=True, cert=None, timeout=None, use_proxy=True)    # store total number of entries available from API    num_entries = int(response.text)    helper.log_info('number of entries available: {}'.format(num_entries))    # get checkpoint or make one up if it doesn't exist    state = helper.get_check_point('stanza' + '_max_id')    if not state:        # get some backlog if it doesn't exist by multiplying number of queries by 10        # and subtracting from total number of entries available        state = num_entries - (10 * opt_query_max)        if state < 0:            state = 0    helper.log_info('fetched checkpoint value for {}_max_id: {}'.format(stanza, state))        # Start a loop to grab up to number of queries per invocation without    # exceeding number of entries available    count = 0    while (count < opt_query_max) or (count + state > num_entries):        helper.log_info('while loop using count: {}, opt_query_max: {}, state: {}, and num_entries: {}'.format(count, opt_query_max, state, num_entries))        count += 1        # update url to examine actual record instead of getting number of entries        url = '/'.join([api_uri, 'item', str(state + count) + '.json?print=pretty'])        response = helper.send_http_request(url, method, parameters=None, payload=None,                              headers=None, cookies=None, verify=True, cert=None, timeout=None, use_proxy=True)        # store result as python dictionary        r_json = response.json()          # massage epoch to a human readable datetime and stash it in key named the same        if r_json['time']:            r_json['datetime'] = datetime.datetime.fromtimestamp(r_json['time']).strftime('%Y-%m-%d %H:%M:%S')           helper.log_info('item {} is: {}'.format(state + count, r_json))           # format python dict to json proper        data = json.dumps(r_json)        # similar to getting args for input instance, find sourcetype & index        # regardless of if we're in test mode (single value) or running as input (dict of values)        st = helper.get_sourcetype()        if type(st) == dict:            st = st[stanza]        idx = helper.get_output_index()        if type(idx) == dict:            idx = idx[stanza]              # write event to index if all goes well        # NB: source is modified to reflect input instance in addition to input type        event = helper.new_event(source=helper.get_input_name() + ':' + stanza, index=idx, sourcetype=st, data=data)        try:            ew.write_event(event)            # assuming everything went well, increment checkpoint value by 1            state += 1        except Exception as e:            raise e     # write new checkpoint value    helper.log_info('saving check point for stanza {} @ {}'.format(stanza + '_max_id', state))    helper.save_check_point('stanza' + '_max_id', state)

/en_us/blog/fragments/digital-resilience-pays-off

Style

two-column

Related Articles

Make Your App More Secure By Updating to jQuery® Version 3.5 or Newer
Tips & Tricks
1 Minute Read

Make Your App More Secure By Updating to jQuery® Version 3.5 or Newer

Splunk will be deprecating use of older versions of jQuery and migrating to v 3.5.0 or newer. Here is what you need to know to start preparing for this upcoming migration.
Quick Tip: Wildcard Sourcetypes in Props.conf
Tips & Tricks
1 Minute Read

Quick Tip: Wildcard Sourcetypes in Props.conf

Running as a Windows Service
Tips & Tricks
1 Minute Read

Running as a Windows Service