Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
mvsum for splunk
# put this in $SPLUNK_HOME/etc/apps/search/local/commands.conf
[mvsum]
filename = mvsum.py
streaming = true
retainsevents = true
supports_multivalues = true
supports_getinfo = true
# save this as $SPLUNK_HOME/etc/apps/search/bin/mvsum.py
# make sure to chmod it to be executable
# Sums multi-valued fields within a single result.
# Usage:
# | mvsum response_time as total_response_time
# where "response_time" is a multi-valued numeric field.
import splunk.Intersplunk as si
import sys
import exceptions
def num(s):
try:
return int(s)
except exceptions.ValueError:
return float(s)
isgetinfo, sys.argv = si.isGetInfo(sys.argv)
keywords, options = si.getKeywordsAndOptions()
if len(keywords) != 3 or keywords[1] != "as":
si.parseError("Invalid syntax. Syntax is: mvsum input-field as output-field")
if isgetinfo:
# outputInfo automatically calls sys.exit()
si.outputInfo(True, False, True, False, None, False)
try:
input_field = keywords[0]
output_field = keywords[2]
results, dummyresults, settings = si.getOrganizedResults()
for result in results:
if input_field in result:
field_value = result[input_field]
if field_value:
if isinstance(field_value, list):
nums = [num(x) for x in field_value]
result[output_field] = str(sum(nums))
else:
result[output_field] = int(field_value)
except:
import traceback
stack = traceback.format_exc()
results = si.generateErrorResults("Error : Traceback: " + str(stack))
si.outputResults(results)

Hey Jordan, wanted to let you know I took your code and updated it to support Splunk 6.x. Thanks for the inspiration. Here are the update files that have been working fine in 6.x across all platforms.

#commands.conf
[mvsum]
filename       = mvsum.py
type           = python
run_in_preview = false
enableheader   = true
streaming      = true
generating     = false
retainsevents  = true
supports_multivalues = true
supports_getinfo     = true
supports_rawargs     = false
#searchbnf.conf
[mvsum-command]
syntax      = mvsum <input-field> as <output-field>
shortdesc   = Sums up the numeric values in a multi-value field
description = Calculates the sum of numeric multi-value field <input-field> \
              and puts the result in the field <output-field>
usage       = public
example1    = | transaction Resource mvlist="Activity" ... | mvsum Activity as TotalActivity
comment1    = Calculates the total of the metric field 'Activity' for each transaction event\
              and stores the results in the output field TotalActivity
related     = mvjoin mvcombine eval
#mvsum.py

# Sums multi-valued field values and store in a single value output field.
# Usage:
#   | mvsum input-field as output-field
#   where "input-field" is a multi-valued field of numbers and "output-field" is the resulting field name.

import re
import splunk.Intersplunk
import sys
import exceptions

# Helper function used to parse values in the <input-field> field
def getNum(value):
    if value == '' or value is None or value is "NULL":
        value = None
    else:
        try:
            value = float(value)
            if value.is_integer():
                value = int(value)
        except ValueError:
            pass
    return value


# Main logic of mvsum function
def generateResult(results, settings):
    try:

        # get input parameters
        (isgetinfo, sys.argv) = splunk.Intersplunk.isGetInfo(sys.argv)
        if isgetinfo:
            # outputInfo automatically calls sys.exit()
            splunk.Intersplunk.outputInfo(True, False, True, False, None, False)

        # check input arguments for validity (mvsum <input-field> as <output-field>)
        if len(sys.argv) < 4 or sys.argv[2] != "as":
            return splunk.Intersplunk.generateErrorResults(
                "Invalid syntax.  Syntax is: mvsum input-field as output-field")

        # store input arguments
        inputstr = sys.argv[1]
        outputstr = sys.argv[3]

        # assert input-field is specified
        if not inputstr:
            return splunk.Intersplunk.generateErrorResults(
                "mvsum requires an input field to sum up")

        # assert output-field is specified
        if not outputstr:
            return splunk.Intersplunk.generateErrorResults(
                "mvsum requires an output field to store the")

        # loop through results and calculate the new output-field
        # by summing up numeric values in the multi-value input-field
        for result in results:
            if inputstr in result:
                field_value = result[inputstr]
                if field_value:
                    if isinstance(field_value, list):
                        nums = [getNum(x) for x in field_value]
                        try:
                            result[outputstr] = round(sum(nums),3)
                        except:
                            return splunk.Intersplunk.generateErrorResults(
                                "non-numeric data passed in input field")
                    else:
                        result[outputstr] = field_value

    # catch exceptions
    except Exception, e:
        import traceback
        stack = traceback.format_exc()
        results = splunk.Intersplunk.generateErrorResults(
            str(e) + ". Traceback: " + str(stack))

    return results

# Entry point of the code
results, dummyresults, settings = splunk.Intersplunk.getOrganizedResults()
results = generateResult(results, settings)
splunk.Intersplunk.outputResults(results)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment