Last time is the first step to create a command to generate only one event as Splunk's Custom Search Command without taking any arguments. Did.
This time, we'll take an argument and brush up the command to generate the number of events specified by the argument.
Last time: "Creating a Splunk custom search command-first step --- Qiita"
I have created a custom search command generatehello
of type Generating commands.
Created up to the last time HelloWorld.py
#!/usr/bin/env python
import sys
import os
import time
sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "lib"))
from splunklib.searchcommands import \
dispatch, GeneratingCommand, Configuration, Option, validators
@Configuration()
class HelloWorldCommand(GeneratingCommand):
""" %(synopsis)
##Syntax
%(syntax)
##Description
%(description)
"""
def generate(self):
return [{"_time": time.time(), "greeting": "hello, world"}]
dispatch(HelloWorldCommand, sys.argv, sys.stdin, sys.stdout, __name__)
This program has the following challenges:
This time, we will solve this. 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- It is based on python-part-ia-simple-generating-command.html) ". (Slightly changed)
Allows you to specify the number of events.
The argument is [Decorator](https://qiita.com/msi/items/acfa737842416580deaf#%E3%83%87%E3%82%B3%E3%83%AC%E3%83%BC%E3%82% BFdecorator-% E3% 81% A8% E3% 81% AF) Specify with Option.
Here, we will simply call Option as a class and specify it.
In the created class HelloWorldCommand
, call it as follows.
Option( )
from splunklib.searchcommands import Option
@Configuration()
class HelloWorldCommand(GeneratingCommand):
count = Option()
Option () also sets the use of count
as a command argument in the SPL statement, as well as simply storing the value in a variable called count
. In the SPL statement, specify | generatehello count = 3
.
Option class"Module structure - Python classes | Documentation | Splunk Developer Program"ThereisadescriptionoftheAPIin"splunklib.searchcommands—SplunkSDKforPythonAPIReference"Although it is a reference, it is a document that is difficult to decipher.
- class splunklib.searchcommands.Option(fget=None, fset=None, fdel=None, doc=None, name=None, default=None, require=None, validate=None)¶
Represents a search command option.
Required options must be specified on the search command line.
Example:
Short form (recommended). When you are satisfied with built-in or custom validation behaviors.
1 2 3 4 5 6 7 8 from splunklib.searchcommands.decorators import Option from splunklib.searchcommands.validators import Fieldnametotal = Option( doc=''' Syntax: total=<fieldname> Description: Name of the field that will hold the computed sum''', require=True, validate=Fieldname())
ʻOption ()has
class splunklib.searchcommands.Option (fget = None, fset = None, fdel = None, doc = None, name = None, default = None, require = None, validate = None)` It has become.
fget
, fset
, and fdel
are arguments that are passed inside the ʻOption ()to the Python built-in function (decorator)
property, which are referenced, assigned, and released (
del`), respectively. Specify the function for, but for now it's best to keep it in the corner of your head.
(If you're used to using Python property, you probably know it.)
doc
, name
, default
, require
, and validate
are arguments to remember.
argument | Description |
---|---|
doc | Write a description of the arguments. |
name | Specify the name of the argument. If omitted, the same name as the variable name of the assignment destination is set. |
default | Sets the default value when the argument is omitted. |
require | Sets whether the argument is required. boolean type(True/False) |
validate | Sets the argument type. |
If ** name ** is omitted, the same name as the variable name of the assignment destination will be the argument name of the search command, but conversely, by specifying ** name **, it will be different from the variable name. Argument names can be set.
** validate ** is defined in splunklib.searchcommands.validators, but SDK It seems that there is no choice but to look into .py). (Explanation omitted)
Boolean()
..... *Code()
..... *Duration()
..... *Fieldname()
File()
..... *Integer()
..... *List()
..... *Map()
..... *Match()
OptionName()
RegularExpression()
..... *Set()
..... *Is defined.
(When read with ʻimport *, only
Boolean,
Code,
Duration,
File, ʻInteger
, List
, Map
, RegularExpression
, Set
)
Referenced Blog, Let's change it a little and set require = False
to an integer value, default = 1
.
argument count settings of
count = Option(require=False, validate=validators.Integer(), default=1)
Since count
is given as an argument (default is 1), the output is repeated accordingly.
last time
return [{"_time": time.time(), "greeting": "hello, world"}]
But this time I want to return the value without waiting for all the processing, so instead of returning the list with return
, I will return the individual event with yield.
for i in range(0, self.count):
yield {"_time": time.time(), "greeting": "hello, world"}
After integrating up to this point, the program looks like this: Rename it to HelloWorld2.py
.
Arguments can be specified HelloWorld2.py
#!/usr/bin/env python
import sys
import os
import time
sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "lib"))
from splunklib.searchcommands import \
dispatch, GeneratingCommand, Configuration, Option, validators
@Configuration()
class HelloWorldCommand(GeneratingCommand):
""" %(synopsis)
##Syntax
%(syntax)
##Description
%(description)
"""
count = Option(require=False, validate=validators.Integer(), default=1)
def generate(self):
for i in range(0, self.count):
yield {"_time": time.time(), "greeting": "hello, world"}
dispatch(HelloWorldCommand, sys.argv, sys.stdin, sys.stdout, __name__)
Perform an operation test in the development environment.
HelloWorld2.py Operation check
$ python3 HelloWorld2.py __EXECUTE__ count=3 < /dev/null
_time,__mv__time,greeting,__mv_greeting
1584952340.0804844,,"hello, world",
1584952340.0816362,,"hello, world",
1584952340.0816433,,"hello, world",
Since we did the App registration in the Splunk environment last time, copy the modified HelloWorld2.py
to helloword / bin
.
Just like last time, be careful about owners, groups, and permissions.
Splunk Copy to environment
cp HelloWorld2.py /opt/splunk/etc/apps/helloworld/bin/
Since we changed the name, we also modify default / commands.conf
. The custom search command name is generatehello2
.
commands.conf
# [commands.conf]($SPLUNK_HOME/etc/system/README/commands.conf.spec)
# Configuration for Search Commands Protocol version 2
[generatehello]
filename = HelloWorld.py
chunked = true
python.version = python3
[generatehello2]
filename = HelloWorld2.py
chunked = true
python.version = python3
[Check with btool](https://qiita.com/msi/items/02d029d655e1f9285806#btool-%E3%81%AB%E3%82%88%E3%82%8B%E3%83%81%E3% After doing 82% A7% E3% 83% 83% E3% 82% AF), either debug / refresh or restart Splunk.
Try typing | generatehello count = 3
in the search.
3 events have been output.
So far, there is a greeting
in the" Related Fields "part on the left, and when I click on it, the words" hello, world "appear, but not in the event display.
This can be displayed by explicitly specifying the _raw
field.
Here, we simply put the same greeting as in _raw
and output it.
_raw Field settings
greeting_msg = "hello, world"
for i in range(0, self.count):
yield {"_time": time.time(), "greeting": greeting_msg, "_raw": greeting_msg}
The whole is as follows.
_raw I set the field HelloWorld2.py
#!/usr/bin/env python
import sys
import os
import time
sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "lib"))
from splunklib.searchcommands import \
dispatch, GeneratingCommand, Configuration, Option, validators
@Configuration()
class HelloWorldCommand(GeneratingCommand):
""" %(synopsis)
##Syntax
%(syntax)
##Description
%(description)
"""
count = Option(require=False, validate=validators.Integer(), default=1)
def generate(self):
greeting_msg = "hello, world"
for i in range(0, self.count):
yield {"_time": time.time(), "greeting": greeting_msg, "_raw": greeting_msg}
dispatch(HelloWorldCommand, sys.argv, sys.stdin, sys.stdout, __name__)
As in the first case, check the operation in the development environment → copy to the Splunk environment → check with btool → check with Splunk search.
Operation check in development environment
$ python3 HelloWorld2.py __EXECUTE__ count=3 < /dev/null
_time,__mv__time,greeting,__mv_greeting,_raw,__mv__raw
1584954369.7098827,,"hello, world",,"hello, world",
1584954369.7099497,,"hello, world",,"hello, world",
1584954369.7099597,,"hello, world",,"hello, world",
Notice that the _raw
field is increasing.
Splunk Copy to environment
cp HelloWorld2.py /opt/splunk/etc/apps/helloworld/bin/
($ SPLUNK_HOME
= / opt / splunk
)
Check the operation by searching Splunk. (" | generatehello2 count = 3
")
It is now displayed in the Events field.
Brush the Generating commands type custom search command created in the previous "Splunk custom search command creation-first step --- Qiita" It's up.
count
argument._raw
field so that" event "is displayed in the search results.If you can do this, it will be easier to proceed to Eventing commands.
Recommended Posts