ラベル webhook の投稿を表示しています。 すべての投稿を表示
ラベル webhook の投稿を表示しています。 すべての投稿を表示

2021年10月13日水曜日

Alertmanager でアラート時にシェルスクリプトを実行する方法

Alertmanager でアラート時にシェルスクリプトを実行する方法

概要

AlertManager はアラートの情報を Slack やメールで通知します
アラート発生時に特定のコマンドを実行したい場合があります
その場合は webhook と組み合わせてコマンドを実行しましょう

Promethues や AlertManager の基本的な設定は前回の記事を確認してください

環境

  • Ubuntu 18.04
  • docker 20.10.7
  • Prometheus 2.30.3
  • Alertmanager 0.23.0
  • Node export 1.2.2
  • webhook 2.5.0

webhook の準備

インストールはこちらを参照してください
webhook を受け取った際に実行するシェルと AlertManager から webhook を受け取りペイロードを変数に格納する設定を準備します

  • vim /tmp/alertmanager_test.sh
#!/bin/bash
echo $STATUS > result_alertmanager_test_shell.log
echo $ANNOTATIONS >> result_alertmanager_test_shell.log
  • chmod +x /tmp/alertmanager_test.sh

AlertManager から送信されるペイロード情報はこちらを参考にしてください

  • vim /tmp/alertmanager_hooks.json
[
  {
    "id": "alertmanager_test",
    "execute-command": "/tmp/alertmanager_test.sh",
    "command-working-directory": "/tmp",
    "include-command-output-in-response": true,
    "pass-environment-to-command":
    [
      {
        "envname": "STATUS",
        "source": "payload",
        "name": "status"
      },
      {
        "envname": "ANNOTATIONS",
        "source": "payload",
        "name": "alerts.0.annotations.summary"
      }
    ]
  }
]

今回はアラート情報の status と annotations.summary を取得してシェルスクリプト側で使うような設定を記載しています

スクリプトと設定ファイルが準備できたら webhook を起動しましょう

  • webhook -hooks /tmp/alertmanager_hooks.json -verbose

alertmanager.yml

アラート発生時に webhook を投げるように alertmanager.yml に記載します
同時に Slack にも通知したい場合など複数のレシバーを定義する場合には routes で発生したアラートに応じてどのレシバーを使用するのかを定義する必要があります

continue: true にすることで次のレシバーも評価してくれます

  • vim alertmanager.yml
route:
  receiver: 'slack'
  routes:
    - receiver: 'slack'
      group_wait: 10s
      match_re:
        job: node1
      continue: true
    - receiver: 'webhook'
      group_wait: 10s
      match_re:
        job: node1
      continue: true

receivers:
  - name: 'slack'
    slack_configs:
      - api_url: 'https://hooks.slack.com/services/xxx/xxx/xxx'
        channel: '#private'
        text: "{{ .CommonAnnotations.summary }}"
        send_resolved: true
  - name: 'webhook'
    webhook_configs:
      - url: 'http://192.168.100.10:9000/hooks/alertmanager_test'

webhook_configs に起動した webhook の URL 情報などを記載します

動作確認

  • stress-ng -c 2 -l 100

などで CPU の使用率を上げてみましょう アラートが上がった際に webhook のログを確認して以下のようなログが出ていれば正常に webhook が投げられ届いていることになります

[webhook] 2021/10/08 13:32:10 executing /tmp/alertmanager_test.sh (/tmp/alertmanager_test.sh) with arguments ["/tmp/alertmanager_test.sh"] and environment [STATUS=firing ANNOTATIONS=Node1 cpu usage over 40%] using /tmp as cwd

ちなみに webhook_configs はデフォルトだと resolved 時にもリクエストして来ます

  • cat result_alertmanager_test_shell.log
resolved
Node1 cpu usage over 40%

コマンドを複数回実行されても問題ないようにするか send_resolved: false を設定してアラート発生時のみ webhook が投げられるようにしましょう

最後に

AlertManager でシェルスクリプトを実行する方法を紹介しました

webhook のプロセスを一つ管理する必要があるので面倒な感じもしますが AlertManager 自体にシェルをキックするような機能は現状ないのでこの方法がベストプラクティスになるかなと思います

Jenkins などがあればそこに webhook を投げてジョブを実行する感じでもいいのかもしれません

参考サイト

2021年10月12日火曜日

adnanh webhook を使ってコマンドを実行する方法

adnanh webhook を使ってコマンドを実行する方法

概要

過去にshell2http というツールを使って HTTP からコマンドを発行する方法を紹介しました

今回紹介する adnanh/webhook は更に柔軟にコマンドを発行することができます
インストールから簡単な使い方を紹介します

環境

  • Ubuntu 18.04
  • webhook 2.5.0

インストール

今回は Ubuntu なので apt を使います

  • apt-get -y install webhook

go で書かれているので go get したり自分でビルドしても OK です
apt でインストールすると自動で sysetmd 配下に登録してくれます

実行するシェルの作成

今回は簡単なシェルを作成します
現在の日付をファイルに出力するだけのスクリプトになります

#!/bin/bash
date > /tmp/result_test_shell.log

hooks.json の作成

hooks.json は webhook で使用する設定ファイルです
実行するスクリプト名や各種オプションを設定します
YAML 形式でも記載できます

  • cd /tmp
  • vim hooks.json
[
  {
    "id": "test-webhook",
    "execute-command": "/tmp/test.sh",
    "command-working-directory": "/tmp"
  }
]

複数の定義を記載することができます
id の部分は webhook でリクエストする際の URI のパス名になります

webhook の起動

では起動します
成功すると :9000 ポートで起動します

  • webhook -hooks /tmp/hooks.json -verbose

-verbose を付与するとログが表示されます
systemd がすでに起動している可能性もあるのでその場合は systemd 側を停止してから起動しましょう

  • systemctl stop webhook
  • systemctl disable webhook

動作確認

あとは curl で動作してみましょう
パラメータがない場合は GET でも POST でも OK です

  • curl localhost:9000/hooks/test-webhook
  • cat /tmp/result_test_shell.log

実行後にちゃんとファイルが生成されて日付が記載されていることを確認しましょう

パラメータを付与してスクリプトを実行する方法

webhook 時に application/json で渡したデータをスクリプト内で使用することもできます

#!/bin/bash
echo $MSG > result_test2_shell.log

MSG という変数に webhook で渡ってきたデータを格納してみます

パラメータのマッピングを定義する

webhook から送信された JSON 情報を変数に格納するマッピング情報を新たに定義します
使用するオプションは pass-environment-to-command になります

  • vim hooks2.json
[
  {
    "id": "test-webhook2",
    "execute-command": "/tmp/test2.sh",
    "command-working-directory": "/tmp",
    "include-command-output-in-response": true,
    "pass-environment-to-command":
    [
      {
        "envname": "MSG",
        "source": "payload",
        "name": "message"
      }
    ]
  }
]

source の payload は送られて来た JSON をパースすることを明示しています
JSON を使う場合は必須なのでそのまま記載します

そして JSON の message として送られてきたデータを変数 MSG に格納します
name がパース対象のフィールド名で envname が格納する変数名になります

動作確認

  • webhook -hooks /tmp/hooks2.json -verbose

ではデータを送信してみます
今度は POST で application/json のデータを送信するようにリクエストを変更します

  • curl -XPOST -H 'Content-type: application/json' -d '{"message":"HELLO"}' localhost:9000/hooks/test-webhook2

これでファイルを確認すると「HELLO」と記載されているのが確認できると思います

最後に

webhook を送信するサービスはいろいろとありますがそれを受け取る場合に自分で作成する必要がありました

adnanh/webhook を使えばどんなサービスの webhook でも受けられるように汎用的に作られているので便利です

他にも XML を受け取ったりファイル、マルチパートデータを受け取ったりできるので基本な HTTP リクエストには対応しているかなと思います

参考サイト