Skip to content

Commit 85db94d

Browse files
committed
Fix up searchcommands and add example searches and results
1 parent 220e143 commit 85db94d

File tree

8 files changed

+73
-167
lines changed

8 files changed

+73
-167
lines changed

examples/searchcommands_app/README.md

Lines changed: 63 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ This app provides several examples of custom search commands that illustrate eac
77
:---------------- |:-----------|:-------------------------------------------------------------------------------------------
88
countmatches | Streaming | Counts the number of non-overlapping matches to a regular expression in a set of fields.
99
generatetext | Generating | Generates a specified number of events containing a specified text string.
10-
pypygeneratetext | Generating | Runs generatetext with the string 'PyPy'.
1110
simulate | Generating | Generates a sequence of events drawn from a csv file using repeated random sampling with replacement.
1211
generatehello | Generating | Generates a specified number of events containing the text string 'hello'.
1312
sum | Reporting | Adds all of the numbers in a set of fields.
@@ -19,12 +18,10 @@ The app is tested on Splunk 5 and 6. Here is its manifest:
1918
├── bin
2019
│   ├── countmatches.py .......... CountMatchesCommand implementation
2120
│ ├── generatetext.py .......... GenerateTextCommand implementation
22-
│ ├── pypygeneratetext.py ...... Runs generatetext.py with PyPy
2321
│ ├── simulate.py .............. SimulateCommand implementation
2422
│ └── sum.py ................... SumCommand implementation
2523
├── lib
26-
| └── splunklib
27-
│ └── searchcommands ....... splunklib.searchcommands module
24+
| └── splunklib ................ splunklib module
2825
├── default
2926
│ ├── data
3027
│ │   └── ui
@@ -35,41 +32,83 @@ The app is tested on Splunk 5 and 6. Here is its manifest:
3532
│ ├── logging.conf ............. Python logging[3] configuration in ConfigParser[4] format
3633
│ └── searchbnf.conf ........... Search assistant configuration [5]
3734
└── metadata
38-
└── local.meta ............... Permits the search assistant to use searchbnf.conf[6]
35+
└── default.meta ............. Permits the search assistant to use searchbnf.conf[6]
3936
```
4037
**References**
41-
[1] [app.conf](http://docs.splunk.com/Documentation/Splunk/latest/Admin/Appconf app.conf)
42-
[2] [commands.conf](http://docs.splunk.com/Documentation/Splunk/latest/Admin/Commandsconf)
43-
[3] [Python Logging HOWTO](http://docs.python.org/2/howto/logging.html)
44-
[4] [ConfigParser—Configuration file parser](http://docs.python.org/2/library/configparser.html)
45-
[5] [searchbnf.conf](http://docs.splunk.com/Documentation/Splunk/latest/admin/Searchbnfconf)
46-
[6] [Set permissions in the file system](http://docs.splunk.com/Documentation/Splunk/latest/AdvancedDev/SetPermissions#Set_permissions_in_the_filesystem)
38+
[1] [app.conf](https://docs.splunk.com/Documentation/Splunk/latest/Admin/Appconf app.conf)
39+
[2] [commands.conf](https://docs.splunk.com/Documentation/Splunk/latest/Admin/Commandsconf)
40+
[3] [Python Logging HOWTO](https://docs.python.org/2/howto/logging.html)
41+
[4] [ConfigParser—Configuration file parser](https://docs.python.org/2/library/configparser.html)
42+
[5] [searchbnf.conf](https://docs.splunk.com/Documentation/Splunk/latest/admin/Searchbnfconf)
43+
[6] [Set permissions in the file system](https://docs.splunk.com/Documentation/Splunk/latest/AdvancedDev/SetPermissions#Set_permissions_in_the_filesystem)
4744

4845
## Installation
4946

50-
+ Link the app to $SPLUNK_HOME/etc/apps/searchcommands_app by running this command:
47+
+ Bring up Dockerized Splunk with the app installed from the root of this repository via:
5148

5249
```
53-
./setup.py link --scp-version {1|2}
50+
SPLUNK_VERSION=latest docker compose up -d
5451
```
5552

56-
+ Or build a tarball to install on any Splunk instance by running this command:
53+
+ When the `splunk` service is healthy (`health: starting` -> `healthy`) login and run test searches within the app via http://localhost:8000/en-US/app/searchcommands_app/search
5754

58-
```
59-
./setup.py build --scp-version {1|2}
60-
```
55+
### Example searches
6156

62-
The tarball is build as build/searchcommands_app-1.5.0-private.tar.gz.
63-
64-
+ Then (re)start Splunk so that the app is recognized.
57+
#### countmatches
58+
```
59+
| inputlookup tweets | countmatches fieldname=word_count pattern="\\w+" text
60+
```
61+
Results:
62+
text | word_count
63+
:----|:---|
64+
excellent review my friend loved it yours always guppyman @GGreeny62... http://t.co/fcvq7NDHxl | 14
65+
Tú novia te ama mucho | 5
66+
... |
6567

66-
## Dashboards and Searches
68+
#### filter
69+
```
70+
| generatetext text="Hello world! How the heck are you?" count=6 \
71+
| filter predicate="(int(_serial) & 1) == 0" update="_raw = _raw.replace('world', 'Splunk')"
72+
```
73+
Results:
74+
Event |
75+
:-----|
76+
2. Hello Splunk! How the heck are you? |
77+
4. Hello Splunk! How the heck are you? |
78+
6. Hello Splunk! How the heck are you? |
6779

68-
+ TODO: Add saved search(es) for each example.
80+
#### generatetext
81+
```
82+
| generatetext count=3 text="Hello there"
83+
```
84+
Results:
85+
Event |
86+
:-----|
87+
1. Hello there |
88+
2. Hello there |
89+
3. Hello there |
6990

70-
### Searches
91+
#### simulate
92+
```
93+
| simulate csv="/opt/splunk/etc/apps/searchcommands_app/data/population.csv" rate=10 interval=00:00:01 duration=00:00:02 seed=9
94+
```
95+
Results:
96+
Event |
97+
:-----|
98+
text = Margarita (8) |
99+
text = RT @Habibies: When you were born, you cried and the world rejoiced. Live your life so that when you die, the world will cry and you will re... |
100+
text = @dudaribeiro_13 q engraçado em. |
71101

72-
+ TODO: Describe saved searches.
102+
#### sum
103+
```
104+
| inputlookup tweets
105+
| countmatches fieldname=word_count pattern="\\w+" text
106+
| sum total=word_counts word_count
107+
```
108+
Results:
109+
word_counts |
110+
:-----|
111+
4497.0 |
73112

74113
## License
75114

examples/searchcommands_app/package/bin/filter.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ class FilterCommand(EventingCommand):
4949
5050
.. code-block::
5151
| generatetext text="Hello world! How the heck are you?" count=6
52-
| filter predicate="(long(_serial) & 1) == 0" update="_raw = _raw.replace('world', 'Splunk')"
52+
| filter predicate="(int(_serial) & 1) == 0" update="_raw = _raw.replace('world', 'Splunk')"
5353
5454
"""
5555
predicate = Option(doc='''

examples/searchcommands_app/package/bin/pypygeneratetext.py

Lines changed: 0 additions & 78 deletions
This file was deleted.

examples/searchcommands_app/package/bin/simulate.py

Lines changed: 7 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,7 @@ class SimulateCommand(GeneratingCommand):
4747
##Example
4848
4949
.. code-block::
50-
| simulate csv=population.csv rate=50 interval=00:00:01
51-
duration=00:00:05 | countmatches fieldname=word_count
52-
pattern="\\w+" text | stats mean(word_count) stdev(word_count)
50+
| simulate csv="/opt/splunk/etc/apps/searchcommands_app/data/population.csv" rate=10 interval=00:00:01 duration=00:00:02 seed=1
5351
5452
This example generates events drawn from repeated random sampling of events from :code:`tweets.csv`. Events are
5553
drawn at an average rate of 50 per second for a duration of 5 seconds. Events are piped to the example
@@ -85,28 +83,20 @@ class SimulateCommand(GeneratingCommand):
8583
**Description:** Value for initializing the random number generator ''')
8684

8785
def generate(self):
88-
89-
if not self.records:
90-
if self.seed is not None:
91-
random.seed(self.seed)
92-
self.records = [record for record in csv.DictReader(self.csv_file)]
93-
self.lambda_value = 1.0 / (self.rate / float(self.interval))
86+
if self.seed is not None:
87+
random.seed(self.seed)
88+
records = [record for record in csv.DictReader(self.csv_file)]
89+
lambda_value = 1.0 / (self.rate / float(self.interval))
9490

9591
duration = self.duration
96-
9792
while duration > 0:
98-
count = int(round(random.expovariate(self.lambda_value)))
93+
count = int(round(random.expovariate(lambda_value)))
9994
start_time = time.clock()
100-
for record in random.sample(self.records, count):
95+
for record in random.sample(records, count):
10196
yield record
10297
interval = time.clock() - start_time
10398
if interval < self.interval:
10499
time.sleep(self.interval - interval)
105100
duration -= max(interval, self.interval)
106101

107-
def __init__(self):
108-
super(SimulateCommand, self).__init__()
109-
self.lambda_value = None
110-
self.records = None
111-
112102
dispatch(SimulateCommand, sys.argv, sys.stdin, sys.stdout, __name__)

examples/searchcommands_app/package/default/commands.conf

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,6 @@ filename = generatetext.py
1616
chunked = true
1717
python.version = python3
1818

19-
[pypygeneratetext]
20-
filename = pypygeneratetext.py
21-
chunked = true
22-
python.version = python3
23-
2419
[simulate]
2520
filename = simulate.py
2621
chunked = true

examples/searchcommands_app/package/default/searchbnf.conf

Lines changed: 2 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ comment1 = \
3535
of the records produced by the generatetext command.
3636
example1 = \
3737
| generatetext text="Hello world! How the heck are you?" count=6 \
38-
| filter predicate="(long(_serial) & 1) == 0" update="_raw = _raw.replace('world', 'Splunk')"
38+
| filter predicate="(int(_serial) & 1) == 0" update="_raw = _raw.replace('world', 'Splunk')"
3939
category = events
4040
appears-in = 1.5
4141
maintainer = dnoble
@@ -58,23 +58,6 @@ maintainer = dnoble
5858
usage = public
5959
tags = searchcommands_app
6060

61-
[pypygeneratetext-command]
62-
syntax = PYPYGENERATETEXT COUNT=<event_count> TEXT=<string>
63-
alias =
64-
shortdesc = Generates a sequence of occurrences of a text string on the streams pipeline under control of PyPy.
65-
description = \
66-
This command generates COUNT occurrences of a TEXT string under control of PyPy. Each occurrence is prefixed \
67-
by its _SERIAL number and stored in the _RAW field of each record. This command assumes that PyPy is on Splunkd's \
68-
PATH.
69-
comment1 = \
70-
This example generates 10 occurrences of the string "Hello world!".
71-
example1 = | pypygeneratetext count=10 text="Hello world!"
72-
category = external generating
73-
appears-in = 1.5
74-
maintainer = dnoble
75-
usage = public
76-
tags = searchcommands_app
77-
7861
[simulate-command]
7962
syntax = SIMULATE CSV=<path> RATE=<expected_event_count> INTERVAL=<sampling_period> DURATION=<execution_period> \
8063
[SEED=<string>]?
@@ -90,9 +73,7 @@ comment1 = \
9073
countmatches command which adds a word_count field containing the number of words in the text field of each event. \
9174
The mean and standard deviation of the word_count are then computed by the builtin stats command.
9275
example1 = \
93-
| simulate csv=population.csv rate=50 interval=00:00:01 duration=00:00:05 \
94-
| countmatches fieldname=word_count pattern="\\w+" text \
95-
| stats mean(word_count) stdev(word_count)
76+
| simulate csv="/opt/splunk/etc/apps/searchcommands_app/data/population.csv" rate=10 interval=00:00:01 duration=00:00:02 seed=1
9677
category = generating
9778
appears-in = 1.2
9879
maintainer = dnoble

examples/searchcommands_app/setup.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -468,7 +468,6 @@ def run(self):
468468
os.path.join('package', 'bin', 'filter.py'),
469469
os.path.join('package', 'bin', 'generatehello.py'),
470470
os.path.join('package', 'bin', 'generatetext.py'),
471-
os.path.join('package', 'bin', 'pypygeneratetext.py'),
472471
os.path.join('package', 'bin', 'simulate.py'),
473472
os.path.join('package', 'bin', 'sum.py')
474473
]

tests/searchcommands/test_searchcommands_app.py

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -199,26 +199,6 @@ def test_generatehello_as_unit(self):
199199

200200
return
201201

202-
@skipUnless(pypy(), 'Skipping TestSearchCommandsApp.test_pypygeneratetext_as_unit because pypy is not on PATH.')
203-
def test_pypygeneratetext_as_unit(self):
204-
205-
expected, output, errors, exit_status = self._run_command('pypygeneratetext', action='getinfo', protocol=1)
206-
self.assertEqual(0, exit_status, msg=six.text_type(errors))
207-
self.assertEqual('', errors, msg=six.text_type(errors))
208-
self._compare_csv_files_time_sensitive(expected, output)
209-
210-
expected, output, errors, exit_status = self._run_command('pypygeneratetext', action='execute', protocol=1)
211-
self.assertEqual(0, exit_status, msg=six.text_type(errors))
212-
self.assertEqual('', errors, msg=six.text_type(errors))
213-
self._compare_csv_files_time_insensitive(expected, output)
214-
215-
expected, output, errors, exit_status = self._run_command('pypygeneratetext')
216-
self.assertEqual(0, exit_status, msg=six.text_type(errors))
217-
self.assertEqual('', errors, msg=six.text_type(errors))
218-
self._compare_chunks(expected, output, time_sensitive=False)
219-
220-
return
221-
222202
def test_sum_as_unit(self):
223203

224204
expected, output, errors, exit_status = self._run_command('sum', action='getinfo', phase='reduce', protocol=1)

0 commit comments

Comments
 (0)