SplunkのOutgoing Webhookのフォーマットを変えたい（カスタムアラートアクション編）

# はじめに

SplunkのアラートアクションでWebhookが使えます。しかしフォーマットが固定なのが玉に瑕です。
Webhookの受け側でフォーマットを変換できればいいのですが、そうではない場合が多いので出し側でなんとかする必要があります。
※そもそもAdd-onがなかった場合を想定しています。Add-onがあればそちらを使ってください。

その場合に取り得る方法は以下です。
1. カスタムアラートアクションを作る
1. 何らかの中継地点を作り（API Gateway + AWS Lambdaなど）フォーマットを変換させる

メリデメはこんな感じだと思います。

| 方法 | メリット | デメリット |
| ----- | ----- | -----|
|カスタムアラートアクション | アラート設定時に宛先設定が分かりやすい。 | App開発がちょっと面倒。開発言語がPythonに限定される。 |
|Amazon API Gateway + AWS Lambda | Appなしで作れる。 | 費用がかかる。宛先管理が別途必要。 |


この記事では`1. カスタムアラートアクションを作る`を見てみたいと思います。

2はこちら。

https://qiita.com/symmr/items/0819a2947435a84b0042#aws-lambda%E4%BD%9C%E6%88%90



# どんなフォーマット？

こんなデータを送ってみます。

```text
| makeresults count=2 |eval name="カスタムイベント" |streamstats count as value | table name, value
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1218403/7732537c-5db9-c689-9b63-faee09d4ea0e.png)

神のようなWebhookテストサイトがあります。

https://webhook.site/#!/

ここに送ってみると、、、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1218403/1f36888b-5ba2-588f-7c61-15f03b536dba.png)

```text:webhook body
{
  "sid": "scheduler__admin__search__RMD511a0a555e05c82a2_at_1681782300_5",
  "search_name": "webhook test",
  "app": "search",
  "owner": "admin",
  "results_link": "http://<ホスト名>:8000/app/search/@go?sid=<sid>",
  "result": {
    "name": "カスタムイベント",
    "value": "1"
  }
}
```

※ちなみに、生成条件を`1回`にすると一行目のみ、`各結果に対して`にすると各行が個別に送信されます。

以下のフォーマットに変換することをゴールとします。
実際は送り先の仕様に合わせてください。
```text:webhook body (goal)
{
  "results_link": "http://<ホスト名>:8000/app/search/@go?sid=<sid>",
  "text": "カスタムイベント", #result.nameの値
  "value": "1" #result.valueの値
}
```


# カスタムアラートアクション

カスタムアラートアクションを作成するには以下の方法でAppを作ります。

1. オリジナルのWebhookアラートをコピー
1. Add-on Builderで作成

今回は1で進めたいと思います。
※Splunk Cloudを使っている場合は一旦自分のPCなどのSplunk Enterpriseで作成し、[この手順でApp作成](https://dev.splunk.com/enterprise/docs/releaseapps/packageapps/)、Splunk Cloudにアップロードする手順になります。

オリジナルのWebhookアラートはここにあります。
`$SPLUNK_HOME/etc/apps/alert_webhook/`

これを元に、新しいAppを作ります。
① `$SPLUNK_HOME/etc/apps/alert_webhook`を`$SPLUNK_HOME/etc/apps/custom_alert_webhook/`としてコピー。
※フォルダ名や各種パラメータ名は例です。分かりやすい名前にしてください。
② `custom_alert_webhook/bin/webhook.py`を`my_custom_webhook.py`に名前変更。
③ `my_custom_webhook.py`を開き、以下の通り変更。
```diff_python:my_custom_webhook.py
-        body = OrderedDict(
-            sid=settings.get('sid'),
-            search_name=settings.get('search_name'),
-            app=settings.get('app'),
-            owner=settings.get('owner'),
-            results_link=settings.get('results_link'),
-            result=settings.get('result')
+        result = settings.get('result')
+        body = OrderedDict(
+            results_link=settings.get('results_link'),
+            text=result.get('name'),
+            value=result.get('value')
        )
```
④ `default/alert_actions.conf`を開き、以下のように変更
```diff_conf:default/alert_actions.conf
- [webhook]
+ [my_custom_webhook]
python.version = python3
is_custom = 1
- label = webhook
+ label = My Custom Webhook
- description = General HTTP POST to a specified URL
+ description = Customized HTTP POST to a specified URL
icon_path = webhook.png
payload_format = json

param.user_agent = Splunk/$server.guid$
```
⑤ `default/app.conf`を開き、以下のように変更
```diff_conf:default/app.conf
[ui]
is_visible = 0
- label = Webhook Alert Action
+ label = My Custom Webhook Alert Action

[launcher]
- author = Splunk
+ author = <名前>
- description = Webhook Alert Action
+ description = My Custom Webhook Alert Action
- version=<元のバージョン>
+ version=1.0.0

[install]
state = enabled
is_configured = 1
```
⑥ `default/restmap.conf`を開き、以下のように変更
```diff_conf:default/restmap.conf
[validation:savedsearch]
# Require url to be set if webhook action is enabled
- action.webhook = case('action.webhook' != "1", null(), 'action.webhook.param.url' == 
+ action.my_custom_webhook = case('action.my_custom_webhook' != "1", null(), 'action.my_custom_webhook.param.url' == "action.my_custom_webhook.param.url" OR 'action.my_custom_webhook.param.url' == "", "No Webhook URL specified",  1==1, null())
- action.webhook.param.url = validate( match('action.webhook.param.url', "^https?://[^\s]+$"), "Webhook URL is invalid")
+ action.my_custom_webhook.param.url = validate( match('action.my_custom_webhook.param.url', "^https?://[^\s]+$"), "Webhook URL is invalid")
```
⑦ `default\data\ui\alerts\webhook.html`を開き、以下のように変更。
また、ファイル名を`my_custom_webhook.html`に変更。
```diff_html:default\data\ui\alerts\my_custom_webhook.html
<form class="form-horizontal form-complex">
    <div class="control-group">
-        <label class="control-label" for="webhook_url">URL</label>
+        <label class="control-label" for="my_custom_webhook_url">URL</label>

        <div class="controls">
-            <input type="text" class="input-xlarge" name="action.webhook.param.url" id="webhook_url" placeholder="https://your.server.com/foo/bar" />
+            <input type="text" class="input-xlarge" name="action.my_custom_webhook.param.url" id="my_custom_webhook_url" placeholder="https://your.server.com/foo/bar" />
        </div>
    </div>
    <div class="control-group">
        <div class="controls">
            <span class="help-block" style="display: block; position: static; width: auto; margin-left: 0;">
                Specified URL to send JSON payload via HTTP POST
                (ex., https://your.server.com/api/v1/webhook). 
                <br />
                <a href="{{SPLUNKWEB_URL_PREFIX}}/help?location=learnmore.alert.action.webhook" target="_blank"
                   title="Splunk help">Learn More <i class="icon-external"></i></a>
                
            </span>
        </div>
    </div>
</form>
```
⑧ `README\alert_actions.conf.spec`を開き、以下のように変更
```diff_conf:README\alert_actions.conf.spec
- [webhook]
+ [my_custom_webhook]

param.user_agent = <string>
* Configure value of the User-Agent header sent to the webhook receiver.
```
⑨ `README\savedsearches.conf.spec`を開き、以下のように変更
```diff_conf:README\savedsearches.conf.spec
# Webook alert action settings

- action.webhook = [0|1]
+ action.my_custom_webhook = [0|1]
* Enable webhook action

- action.webhook.param.url = <string>
+ action.my_custom_webhook.param.url = <string>
* URL to send the HTTP POST request to. Must be accessible from the Splunk server.
```
⑩ Splunkを再起動
⑪ アラートアクションを確認すると作成したカスタムアラートアクションがでてくるはずなので、こっちを使うようにする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1218403/34f2a110-6eec-92b9-2b81-4623941ea602.png)

# 結果

やったね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1218403/263365ca-0d4c-2185-0c78-dca77b7d9a32.png)