This is the old, non-scalable answer for my very specific use case. Look at accepted answer for more useful, generic answer.
My solution in the comments of the original post did work, but it was extremely inefficient because gentimes is invoked so many times. Instead of massaging gentimes and map to work in an odd manner, I just wrote my own command.
Below is my python code for my new command that did what I wanted to do.
Assume the command is called tranexpand . It is invoked with fields span and fields where span is the size of the time buckets for the events parsed by the command and fields is a comma-separated list of fields that need to be maintained in the output data. An example invocation looks like tranexpand span=30m fields="field1,field2" . The command assumes the events being passed to it include fields starttime and endtime . These fields indicate the start and end time bucket for the event. For example, if a transaction/event ended at 8:15:12am and ended at 8:37:35am and the bucket size is 30 minutes, the starttime field would be the equivalent of 8:00:00am and the endtime field would be the equivalent of 8:30:00am.
import re
import splunk.Intersplunk
def getSpan(val):
if not val:
return None
match = re.findall("(\d+)([smhd])", val)
if len(match) > 0:
val = int(match[0][0])
units = match[0][1]
# don't do anything for units == 's', val doesn't need to change
if units == 'm':
val *= 60
elif units == 'h':
val *= 3600
elif units == 'd':
val *= (24 * 3600)
return val
return None
def generateNewEvents(results, settings):
try:
keywords, argvals = splunk.Intersplunk.getKeywordsAndOptions()
spanstr = argvals.get("span", None)
span = getSpan(spanstr)
fields = argvals.get("fields", None)
if not span:
return splunk.Intersplunk.generateErrorResults(
"generateNewEvents requires span=val[s|m|h|d]")
if not fields:
return splunk.Intersplunk.generateErrorResults(
"generateNewEvents requires comma separated" +
" field list wrapped in quotes: fields=\"A[,B[...]]\"")
fields = fields.split(',')
new_results = []
# for each result, add fields set to message
for r in results:
start = r.get("starttime", None)
end = r.get("lasttime", None)
if (start is not None) and (end is not None):
try:
start = int(float(start))
end = int(float(end)) + 1
for x in range(start, end, span):
new_event = {}
new_event['_time'] = str(x)
for y in fields:
new_event[y] = r.get(y, None)
new_results.append(new_event)
except:
pass
results = new_results
except Exception, e:
import traceback
stack = traceback.format_exc()
results = splunk.Intersplunk.generateErrorResults(
str(e) + ". Traceback: " + str(stack))
return results
results, dummyresults, settings = splunk.Intersplunk.getOrganizedResults()
results = generateNewEvents(results, settings)
splunk.Intersplunk.outputResults(results)
... View more