Splunkで文字列を逆順にする。の最後あたりに
頻繁に使うなら、外部pythonスクリプトを用意した方がいいかもしれません。
と書いたこともあり、作ってみました。 本当大変だった
@uneyamauneko @msi さんの記事には本当助けられました。
コピペ元はcountmatches.py@splunk-sdk-python
#準備
pip install splunk-sdk
でいけるとInstall the Splunk Enterprise SDK for Pythonには書いてある。
でも自分の環境
% uname -v
Darwin Kernel Version 19.6.0: Tue Nov 10 00:10:30 PST 2020
% which python
/opt/anaconda3/bin/python
% python --version
Python 3.7.6
% $SPLUNK_HOME/bin/splunk --version
Splunk 8.1.1 (build 08187535c166)
でpip install splunk-sdk
すると
% pip install splunk-sdk
Requirement already satisfied: splunk-sdk in /opt/anaconda3/lib/python3.7/site-packages (1.6.14)
と入っているよと。確かに brew install splunk-sdk
した記憶あり。
ここで例の通りcommands.conf
を$SPLUNK_HOME/etc/<<MYAPPS>>/default/
に設置
なお https://docs.splunk.com/Documentation/Splunk/8.1.1/Admin/Commandsconf
の記載は間違っています。通報ずみ。
[rev]
chunked = true
filename = rev.py
##重要事項
/Applications/Splunk/lib/python3.7/site-packages
にlinkを作成する。
ln -s /Applications/Splunk/lib/python3.7/site-packages $SPLUNK_HOME/lib/python3.7/site-packages/splunklib
% pwd
/Applications/Splunk/lib/python3.7/site-packages
% ls -la
lrwxr-xr-x 1 XXXXX wheel 52 12 31 10:53 splunklib -> /opt/anaconda3/lib/python3.7/site-packages/splunklib
###理由
- 何度やっても
import splunklib
がうまくいかない -
/usr/bin/env splunk
で起動したpython
だとimport splunklib
はうまく行っている。 -
$SPLUNK_HOME/bin/splunk cmd python
のpython
だとimport splunklib
は失敗する。 - 仕方がないので、シンボリックリンクを作成したらうまくいくようになった。
#Code
#!/usr/bin/env python
import sys
from splunklib.searchcommands import dispatch, StreamingCommand, Configuration, Option, validators
@Configuration()
class reverseCommand(StreamingCommand):
""" Reverse the string.
##Syntax
.. code-block::
rev output=<field> <field>
##Description
Outputs the string of the input field in reverse order.
##Example
.. code-block::
index=_internal clientip=* | head 1 | rev output=r_clientip clientip
"""
output = Option(
doc='''
**Syntax:** **output=***<fieldname>*
**Description:** Name of the field that will hold the revesed text''',
require=True, validate=validators.Fieldname())
def stream(self, records):
self.logger.debug('revCommand: %s', self) # logs command line
for record in records:
for fieldname in self.fieldnames:
pass
record[self.output]=record[fieldname][-1::-1]
yield record
dispatch(reverseCommand, sys.argv, sys.stdin, sys.stdout, __name__)
##使い方
| rev output=<output field> <field>
#結果
index=_internal clientip=* | head 1
| rev clientip output=clientip_s
##解説という名の苦労話
- ほとんど元ネタのコピペ
- シバンは効果がない(みたい)。
最初にcommands.conf
とrev.py
を所定の場所(default
とbin
)に格納してSplunkを再起動した。
その時はこんなファイル。
#!/usr/bin/env python
import sys
from splunklib.searchcommands import dispatch, StreamingCommand, Configuration, Option, validators
@Configuration()
class reverseCommand(StreamingCommand):
""" Reverse the string.
"""
def stream(self, records):
self.logger.debug('revCommand: %s', self) # logs command line
for record in records:
yield record
dispatch(reverseCommand, sys.argv, sys.stdin, sys.stdout, __name__)
何もしないコマンド。とりあえず、これで動作を確認した。
いったんこれで |rev clientip
がエラーなく動作することを確認できた。
このあと、色々と変更しては、実行して結果をみて、修正しては実行を繰り返した。
このコマンドの主な処理は下記の通り。
def stream(self, records):
self.logger.debug('revCommand: %s', self) # logs command line
for record in records:
for fieldname in self.fieldnames:
pass
record[self.output]=record[fieldname][-1::-1]
yield record
return
で戻り値を返さないでyield
で返しているのがStreamingCommandなのかな?
いろいろ試していると、コマンドの引数であるフィールド名はfor fieldname in self.fieldnames:
で作ったfieldname
じゃないと取れないみたい。
unhashable type: 'list'
のエラーが出る。
リストを結合してみたら、無くても大丈夫だった。
def stream(self, records):
self.logger.debug('revCommand: %s', self) # logs command line
for record in records:
record[self.output]=record[''.join(self.fieldnames)][-1::-1]
yield record
参考はこちら StreamingCommand.fieldnames
単純に上書きするだけなら
record[fieldname]=record[fieldname][-1::-1]
でいいけど使い勝手が微妙だなとおもって、オプションを設定して上記に変更
#まとめ
初めて作ったこともあって、とても大変でした。
import
ができないでかなりの時間が・・・
ジョブの調査をみてみるとちょっと時間がかかっているような気がします。
取り敢えずは、単純にリターンするだけのpythonだとこれをテンプレートに作れると思います。