Splunk custom command will not work unless Splunkd is started by the root user.
If 'getinfo' is the culprit; is it due to rights/perms? and if so what rights do i need to modify on which files/directories to make it work with the splunk user?
If Splunk is started as sudo root, then gmeans.py works perfectly.
If Splunk is started as splunk, then gmeans fails with getinfo error.
[gmeans]
filename = gmeans.py
supports_getinfo = true
supports_rawargs = true
outputheader = true
splunk btool --debug commands list gmeans
/opt/splunk/etc/apps/<appname>/default/commands.conf [gmeans]
/opt/splunk/etc/system/default/commands.conf changes_colorder = true
/opt/splunk/etc/system/default/commands.conf enableheader = true
/opt/splunk/etc/apps/<appname>/default/commands.conf filename = gmeans.py
/opt/splunk/etc/system/default/commands.conf generates_timeorder = false
/opt/splunk/etc/system/default/commands.conf generating = false
/opt/splunk/etc/system/default/commands.conf maxinputs = 50000
/opt/splunk/etc/system/default/commands.conf outputheader = false
/opt/splunk/etc/system/default/commands.conf passauth = false
/opt/splunk/etc/system/default/commands.conf perf_warn_limit = 0
/opt/splunk/etc/system/default/commands.conf required_fields = *
/opt/splunk/etc/system/default/commands.conf requires_preop = false
/opt/splunk/etc/system/default/commands.conf retainsevents = false
/opt/splunk/etc/system/default/commands.conf streaming = false
/opt/splunk/etc/apps/<appname>/default/commands.conf supports_getinfo = true
/opt/splunk/etc/apps/<appname>/default/commands.conf supports_rawargs = true
/opt/splunk/etc/system/default/commands.conf type = python
I installed a Brand New Splunk instance (6.2.3) installed as splunk user. I followed every piece of online documentation for creating custom streaming commands. The custom command is now in its own app. The splunklib library is located in $SPLUNK_HOME/etc/apps/(app_name)/bin/. The bin directory also holds the python script.
The attribute getinfo will not work. If I set supports_getinfo=0 the command acts like it runs, but will not return results. If I enable supports_getinfo, it returns the error. Debugging the script tells me nothing more than the error on screen.
#!/usr/bin/env python
import sys
from splunklib.searchcommands import dispatch, StreamingCommand, Configuration, Option, validators
# Geometric Mean Calculator
def geomean(nums):
numbers = []
for n in nums:
if not isinstance(n, float):
n = float(n)
numbers.append(n)
else:
numbers.append(n)
product = 1
for n in numbers:
# Prevent 0; numbers[n] should never be a 0.
if n < 0.25:
n = 0.04
product *= n
return round(product ** (1.0 / len(numbers)), 2)
@Configuration()
class gmeansCommand(StreamingCommand):
# Options
fieldname = Option(
doc=''' **Syntax:** **fieldname=***<fieldname>*
**Description:** REQUIRED: Name of the field to hold the calcluted mean for the geometric average''',
require=True, validate=validators.Fieldname())
nums = Option(
doc=''' **Syntax:** **nums=***<fieldname>*
**Description:** REQUIRED: Name of the field that contains the list if numbers to be calculated''',
require=True, validate=validators.Fieldname())
def stream(self, events):
for event in events:
nums = []
for n in event[self.nums].split():
nums.append(float(n))
event[self.fieldname] = geomean(nums)
yield record
dispatch(gmeansCommand, sys.argv, sys.stdin, sys.stdout, __name__)
The SDK that I had previously downloaded and installed was missing __init__.py
and few other root python files in the splunklib folder. Once I downloaded a NEW version of the python SDK and replaced the splunklib directory (and its recursive files/directories) I was able to restart Splunk as the splunk user and it worked.
I modified the gmeans.py
python file a bit; streamlined the code and added exception errors. This allowed the search.log to properly report that it was not finding the splunklib.searchcommands .
06-22-2015 10:27:46.297 ERROR ScriptRunner - stderr from '/opt/splunk/bin/python /opt/splunk/etc/apps/<appname>/bin/gmeans.py __GETINFO__ nums=scores field=score': ImportError: No module named splunklib.searchcommands
Once I added the missing __init__.py
to ../splunklib/ search.log
then started reporting on the missing *.py files like client, binding, data ..etc.
import sys
from splunklib.searchcommands import \
dispatch, StreamingCommand, Configuration, Option, validators
# Geometric Mean Calculator
def geomean(nums):
"""
Return the geometric average of nums
@param list nums List of nums to avg
@return float Geometric avg of nums
"""
numbers = []
for n in nums:
if not isinstance(n, float):
n = float(n)
numbers.append(n)
else:
numbers.append(n)
product = 1
for n in numbers:
if n < 0.25:
n = 0.04
product *= n
return round(product ** (1.0 / len(numbers)), 2)
@Configuration()
class gmeansCommand(StreamingCommand):
""" Computes the geometric mean of a list of numbers.
| stats list(<field with non zero numbers>) | gmeans nums=<number list> field=<name>
"""
# Options
field = Option(name='field', require=True)
nums = Option(name='nums', require=True)
show_error = Option(name='show_error', require=False, default=False, validate=validators.Boolean())
def stream(self, events):
for event in events:
try:
event[self.field] = geomean(str(event[self.nums]).split())
except Exception, e:
if not self.show_error :
raise e
yield event
dispatch(gmeansCommand, sys.argv, sys.stdin, sys.stdout, __name__)
The SDK that I had previously downloaded and installed was missing __init__.py
and few other root python files in the splunklib folder. Once I downloaded a NEW version of the python SDK and replaced the splunklib directory (and its recursive files/directories) I was able to restart Splunk as the splunk user and it worked.
I modified the gmeans.py
python file a bit; streamlined the code and added exception errors. This allowed the search.log to properly report that it was not finding the splunklib.searchcommands .
06-22-2015 10:27:46.297 ERROR ScriptRunner - stderr from '/opt/splunk/bin/python /opt/splunk/etc/apps/<appname>/bin/gmeans.py __GETINFO__ nums=scores field=score': ImportError: No module named splunklib.searchcommands
Once I added the missing __init__.py
to ../splunklib/ search.log
then started reporting on the missing *.py files like client, binding, data ..etc.
import sys
from splunklib.searchcommands import \
dispatch, StreamingCommand, Configuration, Option, validators
# Geometric Mean Calculator
def geomean(nums):
"""
Return the geometric average of nums
@param list nums List of nums to avg
@return float Geometric avg of nums
"""
numbers = []
for n in nums:
if not isinstance(n, float):
n = float(n)
numbers.append(n)
else:
numbers.append(n)
product = 1
for n in numbers:
if n < 0.25:
n = 0.04
product *= n
return round(product ** (1.0 / len(numbers)), 2)
@Configuration()
class gmeansCommand(StreamingCommand):
""" Computes the geometric mean of a list of numbers.
| stats list(<field with non zero numbers>) | gmeans nums=<number list> field=<name>
"""
# Options
field = Option(name='field', require=True)
nums = Option(name='nums', require=True)
show_error = Option(name='show_error', require=False, default=False, validate=validators.Boolean())
def stream(self, events):
for event in events:
try:
event[self.field] = geomean(str(event[self.nums]).split())
except Exception, e:
if not self.show_error :
raise e
yield event
dispatch(gmeansCommand, sys.argv, sys.stdin, sys.stdout, __name__)
Hey, I had this same problem and it turned out that following the steps exactly as laid out online didn't work. It's not that the copy of the SDK didn't have __init__.py
, it's that the instructions don't have you copy it.
When you copy splunklib/searchcommands
into your app's bin
directory per instructions (section "Custom Search Command Example") that causes the ImportError
since there's no __init__.py
copied over, that __init__.py
you need is in splunklib
. Therefore a more correct instruction instead of "create splunklib dir in bin/ and copy searchcommands recursively into new splunklib dir" would be "copy splunklib directory recursively into app's bin directory". That will eliminate the ImportError
I was seeing which I think is the same as yours.
Sorry to resurrect a zombie but yours is the only good description and troubleshooting effort I've seen and I wanted to share for posterity. I've also submitted a correction to Splunk for the documentation I linked, which is what I think we both were following.
upvoting @jhubbard74 answer and @mikemishou comment because you folks did a lot of work and told us what we need to know.