よく聞かれるチェック監視の設定について



この記事は [Mackerel Advent Calendar 2021](https://qiita.com/advent-calendar/2021/mackerel) の22日目の記事です。

Mackerel チーム CRE の masarasi です。普段、Mackerel のテクニカルサポート担当としてお客様からのお問い合わせ対応をしています。
今回は、よくご質問をいただくチェック監視の設定項目やちょっとした小ネタ、特にお問い合わせの多いログ監視の使い方についてご紹介します。


## チェック監視の設定項目

まずはよくご質問をいただくチェック監視の設定項目をご紹介します。実はいろいろカスタマイズできます。


### 最大試行回数の指定

```
max_check_attempts = 3
```

最大試行回数を指定します。ここで指定した回数以上 OK 以外の結果が続いた場合にアラートを発報します。たとえば上記のように 3 が設定されている場合、結果が `NG > NG > NG` と3回連続で OK 以外の場合にアラートが発報されます。


### 実行間隔の指定

```txt
check_interval = 5
```

チェック監視の実行間隔を分で指定します。デフォルト値は 1 分です。設定可能な範囲は 1 分から 60 分で、1 分未満の場合は 1 分、60 分以上を指定した場合は 60 分間隔で監視が実行されます。エージェントのバージョンが v0.67.0 以降であれば `10m` や `1h` のような表現でも記述できます。

### アラートを自動クローズしない

```txt
prevent_alert_auto_close = true
```

デフォルト値は false です。アラートはデフォルトでは結果が NG から OK になった際に自動でクローズされます。こちらを true に設定するとアラートは自動でクローズされなくなり、Web コンソールで手動でクローズする必要があります。

ログ監視などは性質上、パターンに一致するログが継続して出力されないとすぐにクローズされてしまうので、対応が終わるまでアラートを Web コンソールに表示しておきたいといった場合などに活用出来ます。 なお、`max_check_attempts` と併用した場合、`max_check_attempts` は常に 1 として扱われますのでご注意ください。


### 追加で任意のコマンドを実行させる

```txt
action = { command = "date >> /path/to/file" }
```

command の内容が実行された後にここに書いたコマンドも毎回実行されます。上記のようにすると command の実行結果が OK でも NG でも action の内容が実行されます。なお、環境変数を利用することで特定の結果の場合のみに action を実行させることも可能です。

以下は command の結果が OK の場合のみ action を実行する設定です。
`[ \"$MACKEREL_STATUS\" = \"OK\" ]` の OK を NG に変更すれば NG の場合のみ実行する設定になります。

```txt
action = { command = "bash -c '[ \"$MACKEREL_STATUS\" = \"OK\" ]' && date > /path/to/file"  }
```

`MACKEREL_STATUS` 以外にも利用できる環境変数はありますので、興味のある方は下記のヘルプをご覧ください。

https://mackerel.io/ja/docs/entry/custom-checks#action-env


### チェック監視の設定を書く際の注意点

これまでにご紹介した設定項目はチェック監視ごとに設定する必要があります。複数のチェック監視に対して一括で設定することは出来ません。
たとえば `check_interval` を設定する場合の例は以下の通りです。

::: note
OKな例
:::

```txt
[checks.plugin.sample1]
command = [xxxxx]
check_interval = 5

[checks.plugin.sample2]
command = [yyyyy]
check_interval = 5
```

::: note warn
NGな例 : この場合は checks.plugin.sample2 のみで有効になります。
:::

```txt
[checks.plugin.sample1]
command = [xxxxx]

[checks.plugin.sample2]
command = [yyyyy]

check_interval = 5
```

## チェック監視小ネタ

### チェック監視は手動実行できる

もしかするとあまり知られていないのではと思っているのですが、チェック監視（プラグイン）はエージェントに設定しなくても手動実行が可能です。たとえば check-ping であればターミナルなどで以下のように実行出来ます。

```
check-ping -H 127.0.0.1 -n 5 -w 100
```

なお、手動で実行した場合は結果が NG であってもアラートは上がらないので、安心して事前確認が出来ます。


### オリジナルの監視を実行する

command ではプラグイン以外に Linux コマンドやシェルスクリプトの実行も出来ます。とりあえずのサンプルですが、以下の設定をすると Web コンソールのホストの画面に `date` コマンドの結果が表示されます。

```txt
[plugin.checks.date]
command = ["date"]
```

ホストの詳細画面
![スクリーンショット 2021-12-16 18.33.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/651975/080b9d76-d8db-d83a-6e57-002f43ba4412.png)

また、実行したコマンドの終了ステータスに応じて以下のように扱われます。

|終了ステータス|意味|
|-|-|
|0|OK|
|1|WARNING|
|2|CRITICAL|
|0,1,2以外|UNKNOWN|

これらの仕組みを利用すれば、オリジナルのチェック監視を作成することも出来ます。たとえばシェルスクリプトで以下のように条件分岐させるなど、複雑な監視も実装出来たりします。

```bash
if [ 条件式 ]; then
	exit 2    # CRITICALアラート
else
	exit 0    # OK
fi
```

なお、command は文字列指定と配列指定どちらにも対応しており、以下はどちらも同じ内容の監視となります。

文字列指定の例

```txt
[plugin.checks.check-ping-sample]
command = "check-ping -H 127.0.0.1 -n 5 -w 100"
```

配列指定の例

```txt
[plugin.checks.check-ping-sample]
command = ["check-ping", "-H", "127.0.0.1", "-n", "5", "-w", "100"]
```

違いとしては、command の中で環境変数を展開したり、パイプでコマンドをつなげたりしたいという場合には文字列指定にする必要があります。Mackerel では配列指定を推奨しており、詳しい説明はここでは割愛しますが興味のある方はこちらの記事をご覧ください。

https://mackerel.io/ja/blog/entry/mackerel-advent-calendar2018-19


## ログ監視設定について

続いてチェック監視の中でも特にお問い合わせの多いログ監視の使い方についてご紹介です。

ログを監視するチェックプラグインはいくつかあります。

|OS|プラグイン|監視対象ログ|
|-|-|-|
|Linux / Windows|[check-log](https://github.com/mackerelio/go-check-plugins/tree/master/check-log#check-log)|任意のログファイル|
|Windows専用|[check-windows-eventlog](https://github.com/mackerelio/go-check-plugins/tree/master/check-windows-eventlog#check-windows-eventlog)|イベントログ|


プラグインによって文字列のパターン一致と除外のオプション名が少し違います。ややこしいですね。。。

|OS|パターン一致|パターン除外|
|-|-|-|
|check-log|--pattern|--exclude|
|check-windows-eventlog|--message-pattern|--message-exclude|

本記事では check-log を例にご紹介しますが、どちらも正規表現で記述する点は共通です。
以下のサンプルログを元に、検知条件の設定例をいくつかご紹介します。

```text
critical error xxxxx
xxxxx Error xxxxx
xxxxx ErrorLevel critical
```

### 検出したい文字列の指定

条件に一致する行を検出します。正規表現で記述可能で大文字と小文字は区別されます。

```txt
command = ["check-log", "--file", "/path/to/file", "--pattern", "Error"]
```

上記の場合、Error を含む行に一致します。ErrorLevel という文字列でも部分的に Error を含むので一致します。小文字の error には一致しません。

:::note
結果
xxxxx Error xxxxx
xxxxx ErrorLevel critical
:::


#### OR条件で一致させる

```txt
command = ["check-log", "--file", "/path/to/file", "--pattern", "Error|error"]
```

|（パイプ）区切りでOR条件の指定が出来ます。上記の場合、Error か error を含む行に一致します。

:::note
結果
critical error xxxxx
xxxxx Error xxxxx
xxxxx ErrorLevel critical
:::

#### AND条件で一致させる

```txt
command = ["check-log", "--file", "/path/to/file", "--pattern", "Error", "--pattern", "critical"]
```

`--pattern` を複数記述すると AND 条件になります。上記の場合、Error と critical を含む行に一致します。

:::note
結果
xxxxx ErrorLevel critical
:::

#### ^ 行頭で一致させる

```txt
command = ["check-log", "--file", "/path/to/file", "--pattern", "^critical"]
```

^ を文字列の先頭に書くと、その文字列から始まる行に一致します。上記の場合、critical で始まる行に一致します。

:::note
結果
critical error xxxxx
:::

#### $ 行末で一致させる

```txt
command = ["check-log", "--file", "/path/to/file", "--pattern", "critical$"]
```

$ を文字列の末尾に書くと、その文字列で終わる行に一致します。上記の場合、critical で終わる行に一致します。

:::note
結果
xxxxx ErrorLevel critical
:::

#### 大文字と小文字を区別しない

```txt
command = ["check-log", "--file", "/path/to/file", "--pattern", "Error", "--icase"]
```

`--icase` オプションで、大文字小文字を区別せず、Error（error）を含む行に一致します。

:::note
結果
critical error xxxxx
xxxxx Error xxxxx
xxxxx ErrorLevel critical
:::

### 特定の文字列を含む行を除外する

```txt
command = ["check-log", "--file", "/path/to/file", "--pattern", "Error", "--exclude", "critical"]
```

`--pattern` に一致した行から、`--exclude` で指定した文字列（正規表現）を含む行を除外します。上記の場合、Error を含む行のうち critical を含む行が除外されます。

:::note
結果
xxxxx Error xxxxx
:::


## [おまけ] 指定時刻にチェック監視を実行する

チェック監視は実行間隔を変更することは可能ですが、任意の時刻に実行するという機能がありません。ですが、Mackerel の CLIツール `mkr` を利用すると実現出来ます。

`mkr` は別途インストールが必要ですが、ホストの情報を取得するなどいろいろ出来たりします。録導入方法については下記のヘルプをご覧ください。

https://mackerel.io/ja/docs/entry/advanced/cli


本題ですが、下記のヘルプでも公開している通り、`mkr` コマンドのオプション `wrap` を使うと、コマンドやシェルの終了ステータスに応じてアラートを上げることが出来ます。（前半の オリジナルの監視を実行する でご紹介した終了ステータスに準拠します）

https://mackerel.io/ja/docs/entry/howto/mkr/wrap


ログ監視を例にすると、具体的には以下のようにコマンドを実行します。

```
mkr wrap check-log --file="/var/log/access.log" --pattern="Error"
```

ログファイルに Error という文字を含む行があれば、下記のようなアラートが上がります。ただし、実際にエージェントに設定をした場合と表示内容は異なります。

**mkr wrap のアラート**
![スクリーンショット 2021-12-21 0.18.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/651975/85dfce52-46f4-e546-5e75-81e517b81df7.png)
**mackerel-agent.conf に設定した場合のアラート**
![スクリーンショット 2021-12-21 0.31.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/651975/7128d795-b908-f061-4a72-3a65a1d94ce7.png)


`mkr wrap` の方法であれば cron へ登録することで指定時刻に実行可能です。表示内容に差はありますが、より監視の柔軟性が広がると思います。


## ヘルプページのご紹介

チェック監視については以下のヘルプを公開しています。これまでにご紹介した設定項目以外にも書かれているのでぜひご覧ください。

https://mackerel.io/ja/docs/entry/howto/mackerel-check-plugins

https://mackerel.io/ja/docs/entry/custom-checks



また、ログ監視については下記のヘルプを公開してます。ここでご紹介出来なかった情報なども書いてありますのでぜひご覧ください。

https://mackerel.io/ja/docs/entry/howto/check/log

なお、Mackerel 公式のチェック監視プラグインは GitHub にて公開しています。いろいろありますのでぜひご活用ください。

https://github.com/mackerelio/go-check-plugins


## さいごに

今回は特にお問い合わせの多いチェック監視、ログ監視についてご紹介しました。
今後もヘルプや FAQ をはじめとするドキュメントは充実させていきたいと思っていますのでよろしくお願いします！

2021 年の Mackerel アドベントカレンダーも残すところ 3 日となりました。明日 12/23 はまだ空きがありますのでよろしければご参加ください！