
Write a custom search command
A custom search command is an executable file that reads data in and writes data out. This could be a Python script, a C++ program, or some other executable binary file. For simplicity, the file is referred to as the executable in this documentation.
Search command executable requirements
The search command executable should be located in the appropriate directory and given a name that follows some basic rules.
- Executable location
- The search command executable must be located in the appropriate
$SPLUNK_HOME/etc/apps/<app_name>/bin/
directory. Most of the executables that ship with Splunk Enterprise are associated with the Search & Reporting app and are stored in$SPLUNK_HOME/etc/apps/search/bin
. Refer to executables in that directory for examples.
- If you use Splunk Cloud and want to create custom search commands, you must file a Support ticket. You do not have filesystem access to your Splunk Cloud deployment.
- Executable name
- The executable name should be the same as the command name that you will invoke in your Splunk search and follow the naming convention
<command_name>.py
. Search command names can consist of only alphanumeric (a-z and 0-9) characters. New commands should have unique names. The name cannot be the same name of any of the built-in or existing custom commands.
Build the command executable using the Splunk SDK for Python
With the Version 2 protocol, you can use platform-specific versions of external search executables. See Select a location for your custom search command.
For information about handling inputs, outputs, and errors with the Splunk SDK for Python, see Introduction to custom search commands on the Splunk dev portal.
After you build the search command executable, you must Add the custom command to your Splunk deployment.
Build the command executable using the Intersplunk.py file
As part of building the executable, you need to specify how to handle inputs, send output, and handle errors.
Handling inputs
With the Intersplunk.py file, the input to the executable should be formatted in pure CSV or in Intersplunk, which is a header section followed by a blank line followed by pure CSV body.
The simplest way to interpret your executable input is to use splunk.Intersplunk.readResults
, which takes three optional parameters and returns a list of dicts (which represents the list of input events). The optional parameters are input_buf
, settings
, and has_header
.
- inputbuf
- The
inputbuf
parameter where to read input from. If the parameter is None, which is the default value, the input is read fromsys.stdin
.
- settings
- The
settings
parameter is expected to be a dict where any information found in the input header is stored. The default value for this parameter is None, which means that no settings are recorded
- has_header
- The
has_header
parameter specifics whether or not input header is used. The default value for this parameter is True.
To indicate if your executable expects a header, use the enableheader
attribute. The default value for the enableheader
attribute is True, which means that the input will contain the header section and you are using the Intersplunk format.
If your executable does not expect a header section in the input, enableheader
is False, you can directly use the Python CSV module to read the input. For example:
import csv
r = csv.reader(sys.stdin)
for l in r:
...
The advantage of using the Python CSV is that you can break at any time in the for loop, and only lines in the input that you had iterated to at that point are read into memory. This leads to much better performance in some use cases.
Sending output
You can also use the Intersplunk.py file to construct your output of the executable. splunk.Intersplunk.generateErrorResults
takes a string and writes the correct error output to sys.stdout
. splunk.Intersplunk.outputResults
takes a list of dict objects and writes the appropriate CSV output to sys.stdout
.
To output data, add:
splunk.Intersplunk.outputResults(results)
The output of your executable is expected to be pure CSV. For an error condition, simply return a CSV with a single "ERROR" column and a single row (besides the header row) with the contents of the message.
Handling errors
The arguments that are passed to your executable (in sys.argv) are the same arguments that are used to invoke your custom command in the search language, unless your executable has the attribute supports_getinfo = true
. The supports_getinfo
attribute indicates that the first argument to your executable is either __GETINFO__ or __EXECUTE__
. This allows you to call the executable with the command arguments at parse time to check for syntax errors before any execution of the search. Errors at this time will short circuit any real execution of the search query. If called with __GETINFO__
, this also allows you to dynamically specify the properties of your executable (such as streaming or not) depending on your arguments.
If your executable has the attribute supports_getinfo
set to 'true', you should first make a call like:
(isgetinfo, sys.argv) = splunk.Intersplunk.isGetInfo(sys.argv)
This call will strip the first argument from sys.argv and check if you are in GETINFO mode or EXECUTE mode. If you are in GETINFO mode, your executable should use splunk.Intersplunk.outputInfo()
to return the properties of your executable or splunk.Intersplunk.parseError()
if the arguments are invalid.
The definition of outputInfo()
and its arguments is as follows:
def outputInfo(streaming, generating, retevs, reqsop, preop, timeorder=False)
You can also set these attributes in the commands.conf file. See How to edit a configuration file.
See also
- To decide where to implement your command, see Select a location for your custom search command.
- To learn about the supported protocols and SDKs, see About writing custom search commands.
- To learn about security best practices with custom search commands, see Security responsibilities with custom commands.
- For information about the custom search command parameters, see commands.conf.
PREVIOUS About writing custom search commands |
NEXT Select a location for your custom search command |
This documentation applies to the following versions of Splunk® Enterprise: 6.4.0, 6.4.1, 6.4.2, 6.4.3, 6.4.4, 6.4.5, 6.4.6, 6.4.7, 6.4.8, 6.4.9, 6.4.10, 6.4.11, 6.5.0, 6.5.1, 6.5.1612 (Splunk Cloud only), 6.5.2, 6.5.3, 6.5.4, 6.5.5, 6.5.6, 6.5.7, 6.5.8, 6.5.9, 6.5.10, 6.6.0, 6.6.1, 6.6.2, 6.6.3, 6.6.4, 6.6.5, 6.6.6, 6.6.7, 6.6.8, 6.6.9, 6.6.10, 6.6.11, 6.6.12, 7.0.0, 7.0.1, 7.0.2, 7.0.3, 7.0.4, 7.0.5, 7.0.6, 7.0.7, 7.0.8, 7.0.9, 7.0.10, 7.0.11, 7.0.13, 7.1.0, 7.1.1, 7.1.2, 7.1.3, 7.1.4, 7.1.5, 7.1.6, 7.1.7, 7.1.8, 7.1.9, 7.1.10, 7.2.0, 7.2.1, 7.2.2, 7.2.3, 7.2.4, 7.2.5, 7.2.6, 7.2.7, 7.2.8, 7.2.9, 7.3.0, 7.3.1, 7.3.2, 8.0.0, 7.3.3, 8.0.1
Comments
1) First and second sentences are a little weird. A Python script is not a kind of "binary file". The author seems to think they are.
2) Typo - "handing" s/b handling, and I think it's missing an "of"
"Note: For information about the handing inputs, outputs, and errors"
3) "Build the command executable using the Intersplunk.py SDK"
What... are you talking about? =)
I am pretty sure that there is no such thing as the "intersplunk.py SDK".
Intersplunk.py ships with splunk, but it's just a python file.
Or I'm just behind on things and there's an SDK with docs and tools and examples and (hey that would be great). but if so that means there's some URL you should link to here.
4) At a general level, it's weird to make such a specific mention that it can be any executable, but then *only* talk about Python scripts. eg: Can platform differences be handled at all? Are there any working examples of non-python executables (ideally with source code)?
Pablord
Thank you for your question. The documentation feedback is really for letting us know that this is something not clear in the documentation or for a suggestion. For specific questions on how to use Splunk, please post your question on Splunk Answers. https://answers.splunk.com/
I see other examples in the web.
rest /services/authentication/current-context/context
But it is not applicable to my case, because rest shoud be the first command in the search.
thank!
hi, I need help
I need to recover the logged user in splunk. To then compare the logged-in user with a field of an index.
Example:
Index = "example" getuserlogged = "value_of_field_on_index" | other command | other command.
Where getuserlogged is a function that retrieves the user logged in splunk.
is it possible to do? Thank in advance
Sideview
Thank you, I have updated the text to reflect your comments.