Use the Splunk SDK to create a Custom Search Command.
It is said that there is a document, but it is difficult to understand, so I will summarize the reference destination and procedure.
As a first step, create a custom search command generatehello
[^ 2] that outputs" hello, world "[^ 1].
[^ 1]: In lowercase, in honor of Kernighan & Ritchie. [^ 2]: It's a so-called Native command that uses the Splunk SDK framework instead of calling a script using run. For how to create a script using the run command as a custom search command, "How to create a custom search command (Splunk) --Qiita" will be helpful. I will.
: point_up_tone3: It's a bit old, but the content is still valid Splunk official blog "[Building custom search commands in Python part I – A simple Generating commands](https://www.splunk.com/en_us/blog/tips] -and-tricks / building-custom-search-commands-in-python-part-ia-simple-generating-command.html) It is based on "[^ 3]. However, this article takes a bottom-up approach.
[^ 3]: In the blog of April 2014, it is "Part I", but it seems that the blog of "Part II" has been deleted or not posted.
Outputs "hello, world" in the SPL statement | generatehello count = 3
and the number of events specified in the count argument (3 events in this example).
For now, let's create a simple custom search command that takes no arguments.
Development guide"Develop apps | Documentation | Splunk Developer Program"However, it is often confusing to read this, so I will organize the terms.
the term | easy explanation |
---|---|
App(s) | Display part(UI)、Add-on, entire application, including custom search commands App in singular, but Apps(Ups)Is often called in the plural. $SPLUNKHOME/etc/apps/ It is arranged in directory units below. |
Add-on(s) | Display part(UI)Part or whole of the app without |
Custom Search Command | Your own program called as an SPL command. Generally configured as part of the App. |
In this article, it is described as SPLUNKHOME = / opt / splunk
[^ 5].
[^ 5]: As an aside, some files seem to be hardcoded as SPLANKHOME = / opt / splunk_home. Since the installation destination of the distributed package is / opt / splunk, you may trip over a little bit.
Download the Splunk SDK, unpack it, and set up your development directory.
reference: Create custom search commands | Documentation | Splunk Developer Program See also: Downloads | Splunk Developer Program See also: GitHub --splunk / splunk-sdk-python: Splunk Software Development Kit for Python See also: Releases · splunk / splunk-sdk-python · GitHub
The document also describes how to install with pip [^ 4], but this time I will not use the Python virtual environment and will not install pip. Download and use the .zip or .tar.gz file.
[^ 4]: cd $ SPLUNKHOME / etc / apps / yourapp / bin; pip install -t. Splunk-sdk and other methods are written, but the official method described in the official document is used in another directory. Develop and test in, and deploy to Splunk.
: point_up_tone3: From "Releases · splunk / splunk-sdk-python · GitHub" to the latest (currently 1.6.12) .zip Download and unzip the file or .tar.gz file.
Splunk SDK Download and unpack
$ wget https://github.com/splunk/splunk-sdk-python/archive/1.6.12.tar.gz
...
2020-03-17 01:50:38 (3.12 MB/s) - ‘1.6.12.tar.gz’ saved [3876452]
$ ls
1.6.12.tar.gz
$ tar xvfz 1.6.12.tar.gz
splunk-sdk-python-1.6.12/
splunk-sdk-python-1.6.12/.gitattributes
...
splunk-sdk-python-1.6.12/utils/cmdopts.py
$
(There is setup.py in the extracted directory, but I will not use it this time.)
HelloWorld-work /
,
cp -rp splunk-sdk-python-1.6.12/examples/searchcommands_template HelloWorld-work
HelloWorld-work / lib /
directory
mkdir HelloWorld-work/lib
splunklib
directory under it.
cp -rp splunk-sdk-python-1.6.12/splunklib/ HelloWorld-work/lib/
HelloWorld-work Setup
$ cp -rp splunk-sdk-python-1.6.12/examples/searchcommands_template HelloWorld-work
$ mkdir HelloWorld-work/lib
$ cp -rp splunk-sdk-python-1.6.12/splunklib/ HelloWorld-work/lib/
$
You now have a directory structure like the one below.
HelloWork-work Directory tree structure
HelloWorld-work/
|-- bin
| |-- filter.py ................ Eventing commands (See below)Template.
| |-- generate.py .............. Generating commands (See below)Template.
| |This time, we will use this file.
| |-- report.py ................ Reporting commands (See below)Template.
| `-- stream.py ................ Streaming commands (See below)Template.
|-- default ......................The directory that stores the provider's default configuration files.
| |-- app.conf .................Fix it when you set up Splunk.
| |-- commands-scpv1.conf ......Delete this file.
| |-- commands-scpv2.conf ......Commands this file when configuring Splunk.Replace with conf.
| |Eventually it will be deleted.
| |-- commands.conf ............When setting up Splunk
| |Command this file-scpv2.Replace with conf and fix.
| |-- data
| | `-- ui
| | `-- nav
| | `-- default.xml .. [Setting]-[User interface]-[Navigation menu]-[default]
| |It is the App display configuration displayed in.
| `-- logging.conf .............This time, delete this file.
|-- lib ..........................The library directory referenced as PYTHONPATH.
| |This location is not fixed, but it is recommended in the official documentation.
| |If you added a package that is not included in splunklib in your Python virtual environment
| | site-packages/You need to put the library below.
| `-- splunklib ................Same as splunklib in SDK. Call it with import splunklib.
| |-- __init__.py
: :
: :
| `-- six.pyc
`-- metadata
`-- default.meta .............reference/Write permission is specified.
12 directories, 79 files
This directory structure mimics the structure of the $ SPLUNKHOME / etc / apps / yourapplication / directory. You can register as an App by deleting unnecessary files and copying them to $ SPLUNKHOME / etc / apps / as they are.
: point_up_tone3: There are default /
and local /
in the config file directory, the default /
directory is the provider's default setting, and the user is the local /
directory (otherwise the directory) It is a rule to set only the changes (by creating).
This time, the developer = the provider, so modify the configuration file in the default /
directory directly.
Before we start creating custom search commands, let's talk about the types.
reference: Create custom search commands | Documentation | Splunk Developer Program reference: Python classes | Documentation | Splunk Developer Program
: point_up_tone3: There are four types of custom search commands.
The core of the search commands module contains four classes:
- EventingCommand: Defines a search command that applies a transformation to search results as they travel through the events pipeline. Examples of eventing commands include sort, dedup, and cluster.
- GeneratingCommand: Defines a search command that generates event records based on command arguments. Examples of generating commands include search (at the beginning of the pipeline), inputcsv, input lookup, and metadata.
- ReportingCommand: Defines a search command that processes search results and generates a reporting data structure. Examples of reporting commands include stats, top, and timechart.
- StreamingCommand: Defines a search command that applies a transformation to search results as they travel through the processing pipeline. Examples of streaming commands include search, eval, and where.
The simple explanation is as follows.
type | easy explanation | Execution location | Command example |
---|---|---|---|
Eventing commands | Command that receives input, processes it, and outputs it | Search Head only | sort, dedup, cluster |
Generating commands | InputNot received, Command to output | Search Head only | (Written at the beginning)search, inputcsv, input lookup, metadata |
Reporting commands | Command to receive input and process it into report format | Search Head only | stats, top, timechart |
Streaming commands | Commands to process and output in a distributed environment | Indexer can be used in parallel | search, eval, where |
It may be difficult to distinguish between Eventing commands and Streaming commands, with the difference that Eventing commands can only be executed in Search Head, while Streaming commands can also be executed in Indexer [^ 7]. (See also "Types of commands" for more information)
[^ 7]: There is also a command called "Stateful Streaming commands" that can only be executed by Search Head ... What's wrong ...
As a first step, we will create ** Generating commands ** without any input.
reference: Templates - Create custom search commands | Documentation | Splunk Developer Program
Templates are available for each of the four types. Browse the Generating comannds template.
Generating commands template --generate.py
It's located in ʻexamples / searchcommands_template / bin / generate.pyin the Splunk SDK directory, but under
bin /` in the working directory you set up.
generate.py
1 #!/usr/bin/env python
2
3 import sys
4 import os
5
6 sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "lib"))
7 from splunklib.searchcommands import \
8 dispatch, GeneratingCommand, Configuration, Option, validators
9
10 @Configuration()
11 class %(command.title())Command(GeneratingCommand):
12 """ %(synopsis)
13
14 ##Syntax
15
16 %(syntax)
17
18 ##Description
19
20 %(description)
21
22 """
23 def generate(self):
24 # Put your event code here
25 pass
26
27 dispatch(%(command.title())Command, sys.argv, sys.stdin, sys.stdout, __name__)
generate.py
is located (..../HellWorld-work/bin/../lib
= ..../HelloWorld-work/lib
) Is added to sys.path.
Call the splunklib
module under this lib.
What you can see from this is that Splunk doesn't automatically set lib /
to PYTHONPATH.
If you want to add your own library, you need to set sys.path, but if you use this template, you can load it by putting it in the lib directory.% (command.title ())
part to a suitable name.
(Since it appears on the 27th line, replace it with the same character string)
The GeneratingCommand class is specified as the base class.% ()
part with an appropriate one if possible, but this time it will be omitted.generate
should be used as is.
The generate ()
function must be an iterator (see below).% (command.title ())
part with the same string that appears on line 11.Copy the template generate.py
to HelloWorld.py
and modify the command name etc.
Set % (command.title ())
on lines 11 and 27 to HelloWorld
.
You can use an editor, but it may be easier to fix it with sed.
sed Fix using
$ sed -e 's/%(command.title())/HelloWorld/' generate.py > HelloWorld.py
$ diff generate.py HelloWorld.py
11c11
< class %(command.title())Command(GeneratingCommand):
---
> class HelloWorldCommand(GeneratingCommand):
27c27
< dispatch(%(command.title())Command, sys.argv, sys.stdin, sys.stdout, __name__)
---
> dispatch(HelloWorldCommand, sys.argv, sys.stdin, sys.stdout, __name__)
$
Modify the field called greeting to return only one "hello, world".
The type to return is a dictionary type. At this time, Splunk often uses the time as a key, so set the time in the _time
field.
Also, as I wrote above, generate () must be of type iterate. : point_up_tone3: There are two ways to do this.
First, it returns only one entry, so let's try it with return. Insert ʻimport time ()` on line 5 to add the time, and modify the parts on lines 24 and 25 as follows:
1 #!/usr/bin/env python
2
3 import sys
4 import os
5 import time # _New import to set time
6
7 sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "lib"))
8 from splunklib.searchcommands import \
9 dispatch, GeneratingCommand, Configuration, Option, validators
10
11 @Configuration()
12 class HelloWorldCommand(GeneratingCommand):
13 """ %(synopsis)
14
15 ##Syntax
16
17 %(syntax)
18
19 ##Description
20
21 %(description)
22
23 """
24 def generate(self):
25 return [{"_time": time.time(), "greeting": "hello, world"}] #Note that it is a list
26
27
28 dispatch(HelloWorldCommand, sys.argv, sys.stdin, sys.stdout, __name__)
The 25th line puts the time in the _time
field, puts" hello, world "in the greeting
field, and returns as a list.
You can check the operation with python3 HelloWorld.py __EXCECUTE__ </ dev / null
, but if you execute it as it is, an error will occur.
Error occurred
$ python3 --version
Python 3.6.9
$ python3 HelloWorld.py __EXECUTE__ < /dev/null
Traceback (most recent call last):
File "HelloWorld.py", line 8, in <module>
from splunklib.searchcommands import \
File "../lib/splunklib/searchcommands/__init__.py", line 145, in <module>
from .environment import *
File "../lib/splunklib/searchcommands/environment.py", line 120, in <module>
splunklib_logger, logging_configuration = configure_logging('splunklib')
File "../lib/splunklib/searchcommands/environment.py", line 103, in configure_logging
fileConfig(filename, {'SPLUNK_HOME': splunk_home})
File "/usr/lib/python3.6/logging/config.py", line 84, in fileConfig
handlers = _install_handlers(cp, formatters)
File "/usr/lib/python3.6/logging/config.py", line 131, in _install_handlers
hlist = cp["handlers"]["keys"]
File "/usr/lib/python3.6/configparser.py", line 959, in __getitem__
raise KeyError(key)
KeyError: 'handlers'
$
This is an error when reading the .conf file.
I go to read the files under the default /
directory, but since I haven't set anything at the moment, the template characters are still there.
In this article, we will delete unnecessary files once, assuming that we will make the necessary settings.
The target this time is logging.conf. (Troubleshooting keywords are ʻin configure_loggingand
KeyError:'handlers'` in the above error.)
Delete logging.conf in the default /
directory. (If you want to restore it, copy it from the SDK directory again.)
logging.conf Delete
$ rm ../default/logging.conf
$ ls ../default/
app.conf commands-scpv1.conf commands-scpv2.conf commands.conf data
$
Run the test in the development environment.
python3 HelloWorld.py __EXECUTE__ < /dev/null
It can be executed with the command sequence.
: point_up_tone3: __EXECUTE__
is two underscores (_
) before and after ʻEXECUTE`.
Even if it is a Generating command, it will wait for standard input [^ 6], so specify / dev / null as input.
[^ 6]: When run on Splunk, Splunk populates meta information for processing by the Splunk library.
Test run
$ python3 --version
Python 3.6.9
$ python3 HelloWorld.py __EXECUTE__ < /dev/null
_time,__mv__time,greeting,__mv_greeting
1584528442.0660899,,"hello, world",
$
You've added unknown fields, __mv__time
and __mv_greeting
, which the Splunk library adds automatically. Here, make sure that the intended _time
and greeting
are output.
Install (register) it in Splunk and run it.
Modify ʻapp.confand
commands.conf in the
default / `directory.
See also: app.conf --Splunk Documentation
The template ʻapp.conf` looks like this:
app.conf
1 # Splunk app configuration file
2
3 [ui]
4 label = %(app_label)<= Correct this to the name of the App.
5 is_visible = 1
6
7 [launcher]
8 description = %(app_description)
9 author = %(app_author)
10 version = %(app_version)
11
12 [package]
13 id = %(app_id)
14
15 [install]
16 is_configured = 0
You can install the custom search command alone, but it will be set in the system directory, so set the name to label
to register it as a new app.
Here, it is "Hello World". Other parts need to be modified, but they do not affect the operation of the custom search command, so leave them as they are.
*** app.conf.orig 2020-03-18 20:00:07.303785404 +0900
--- app.conf 2020-03-18 20:00:18.943809800 +0900
***************
*** 1,7 ****
# Splunk app configuration file
[ui]
! label = %(app_label)
is_visible = 1
[launcher]
--- 1,7 ----
# Splunk app configuration file
[ui]
! label = Hello World
is_visible = 1
[launcher]
After modification app.conf
# Splunk app configuration file
[ui]
label = Hello World
is_visible = 1
[launcher]
description = %(app_description)
author = %(app_author)
version = %(app_version)
[package]
id = %(app_id)
[install]
is_configured = 0
commands.conf
See also: commands.conf --Splunk Documentation
It is commands.conf
that sets the custom search command.
Under the default /
directory, there are three files, commands.conf
, commands-scpv1.conf
, and commands-scpv2.conf
. Two templates are available because there are v1 and v2 versions of the protocol that the custom search command interacts with Splunk. The template, commands.conf
, has the contents of v1.
Strictly speaking, it is necessary to examine which protocol to use, but I think that it will be v2 in the future, so copy commands-scpv2.conf
to commands.conf
and modify it.
commands-scpv2.conf copy of
$ cp commands-scpv2.conf commands.conf
$
commands.conf (v2) template
1 # [commands.conf]($SPLUNK_HOME/etc/system/README/commands.conf.spec)
2 # Configuration for Search Commands Protocol version 2
3
4 [%(command.lower()]
5 filename = %(command.lower()).py
6 chunked = true
If the command name called from SPL and the file name excluding .py
are the same, it is not necessary to set filename
, but this time the command name to be called is generatehello
and the file name is HelloWorld.py
. So, set it.
Also, as I wrote at the beginning, Python3 is used, so make this setting. : point_up_tone3: When using Python3
python.version = python3
To set.
After rewriting commands.conf
1 # [commands.conf]($SPLUNK_HOME/etc/system/README/commands.conf.spec)
2 # Configuration for Search Commands Protocol version 2
3
4 [generatehello]
5 filename = HelloWorld.py
6 chunked = true
7 python.version = python3
I wrote the App name in ʻapp.conf, so it doesn't matter what directory you install, as long as the directory name doesn't conflict with other Splunk Apps. Here, let's call it
helloworld`. Delete unnecessary configuration files before installation (copy).
: point_up_tone3: The installation directory is under $ SPLUNKHOME / etc / apps /
. Copy the entire HelloWorld-work /
directory. At this time, pay attention to the owner and permissions of the file. Be especially careful if you're running Splunk as non-root.
$ rm HelloWorld-work/default/commands-scpv[12].conf; sudo sh -c "cp -rp HelloWorld-work /opt/splunk/etc/apps/helloworld; chown -R splunk:splunk /opt/splunk/etc/apps/helloworld"
$ ls -ld /opt/splunk/etc/apps/helloworld/{*,}
drwxr-xr-x 6 splunk splunk 4096 Mar 18 07:52 /opt/splunk/etc/apps/helloworld/
drwxr-xr-x 2 splunk splunk 4096 Mar 18 09:33 /opt/splunk/etc/apps/helloworld/bin
drwxr-xr-x 3 splunk splunk 4096 Mar 18 11:43 /opt/splunk/etc/apps/helloworld/default
drwxr-xr-x 3 splunk splunk 4096 Mar 18 07:52 /opt/splunk/etc/apps/helloworld/lib
drwxr-xr-x 2 splunk splunk 4096 Feb 13 23:30 /opt/splunk/etc/apps/helloworld/metadata
$
See also: Use btool to troubleshoot configurations --Splunk Documentation
Use btool to check that the configuration file is correct.
$SPLUNKHOME/bin/splunk btool check
If there is no problem, nothing will be displayed, but if there is something wrong, the following display will appear. (Example of accidentally changing python.version
to ython.version
)
Display when there is a problem with the configuration file
$ sudo su splunk -c "/opt/splunk/bin/splunk btool check"
Invalid key in stanza [generatehello] in /opt/splunk/etc/apps/helloworld/default/commands.conf, line 7: ython.version (value: python3).
$
With the --debug
option, you will get a lot of messages even for config files that are okay.
The settings are loaded at http (s): // _ yourURL_ / debug / refresh, so restarting is basically unnecessary, but if it does not load, restart Splunk.
Finally, run it on Splunk. Select Hello World
from the App and enter the command in the search window.
|generatehello
It worked.
| generatehello
The greeting does not appear as an "event" because the generated data does not contain a _raw
field.
If you click on the greeting
part of the menu on the left, you will see that" hello, world "is output.
If you want to output it explicitly, specify the field with table
etc. and it will be displayed.
If you think something is strange, look at the job log.
The above example is an example of raising an exception for testing.
Up to here for this time. If you can take the first step, it will be easier to take the next step.
| generatehello count = 3
, this time I created a command with no arguments to display only one event.Next time, I will brush up the commands to finish them. ⇒ I wrote the following "Splunk custom search command creation part 2-Qiita".
Click here for an example of the Splunk SDK program → [splunk-sdk-python / generatehello.py at master · splunk / splunk-sdk-python · GitHub](https://github.com/splunk/splunk-sdk-python/blob /master/examples/searchcommands_app/package/bin/generatehello.py)
[Updated on 05/04/2020] Sample code has been released on GitHub → Splunk-CustomSearchCommand-FirstStep at step1
Recommended Posts