blastengineを使ったメール送信処理で、API呼び出しが失敗したときに素早く気づきたい場面があります。本記事では、Zabbix Agent 2のアクティブチェックでログファイルを監視し、エラー検知時に通知する最短構成を紹介します。
前提
環境
| 項目 | バージョン・設定例 |
|---|---|
| OS | Rocky Linux 9 / Ubuntu 22.04 など |
| Zabbix Server | 7.0 LTS |
| Zabbix Agent 2 | 7.0(監視対象ホストに導入済み) |
| 監視対象ログ | /var/log/myapp/blastengine.log |
ログ形式の前提
- 1行1イベントで出力されていること
- エラー発生時に
ERRORなどのレベル識別子が含まれること
アプリ側のログ出力(例)
blastengine APIの呼び出し失敗時に、以下の項目を含むログを出力するようにしておきます。
| 項目 | 説明 |
|---|---|
| timestamp | 発生日時(ISO 8601形式推奨) |
| level | ログレベル(ERROR / WARN など) |
| endpoint | 呼び出したAPIエンドポイント |
| status | HTTPステータスコード |
| error_code | blastengineのエラーコード |
| message | エラーメッセージ |
| request_id | リクエスト識別子(トレース用) |
JSON形式の例
{"timestamp":"2025-01-15T10:23:45+09:00","level":"ERROR","endpoint":"/api/v1/deliveries","status":401,"error_code":"UNAUTHORIZED","message":"Invalid API key","request_id":"req_abc123"}
プレーンテキスト形式の例
2025-01-15T10:23:45+09:00 ERROR blastengine endpoint=/api/v1/deliveries status=401 error_code=UNAUTHORIZED message="Invalid API key" request_id=req_abc123
Pythonでの実装例
import logging
import json
from datetime import datetime
logger = logging.getLogger("blastengine")
handler = logging.FileHandler("/var/log/myapp/blastengine.log")
handler.setFormatter(logging.Formatter("%(message)s"))
logger.addHandler(handler)
logger.setLevel(logging.INFO)
def log_blastengine_error(endpoint: str, status: int, error_code: str, message: str, request_id: str):
log_entry = {
"timestamp": datetime.now().astimezone().isoformat(),
"level": "ERROR",
"endpoint": endpoint,
"status": status,
"error_code": error_code,
"message": message,
"request_id": request_id
}
logger.error(json.dumps(log_entry, ensure_ascii=False))
Zabbix Agent 2の設定
監視対象ホストの /etc/zabbix/zabbix_agent2.conf を編集します。
必須設定
# Zabbix Serverのアドレス(アクティブチェック用)
ServerActive=zabbix.example.com
# ホスト名(Zabbixフロント側の登録名と完全一致させる)
Hostname=app-server-01
ログファイルの読み取り権限
Zabbix Agent 2は zabbix ユーザーで動作するため、ログファイルを読める必要があります。
# ログファイルの権限を確認
ls -la /var/log/myapp/blastengine.log
# 読み取り権限がない場合の対処例
# 方法1: グループ権限を付与
sudo chown :zabbix /var/log/myapp/blastengine.log
sudo chmod 640 /var/log/myapp/blastengine.log
# 方法2: ACLを使う(ログローテーション後も維持しやすい)
sudo setfacl -m u:zabbix:r /var/log/myapp/blastengine.log
sudo setfacl -d -m u:zabbix:r /var/log/myapp/
設定変更後、エージェントを再起動します。
sudo systemctl restart zabbix-agent2
Zabbixのアイテム作成(log監視)
Zabbixフロントエンドでログ監視アイテムを作成します。
手順
- 左メニューの Data collection → Hosts を開く
- ホスト一覧から対象ホストの Items リンクをクリック
- アイテム設定を入力し、右上の Create item ボタンをクリック
アイテム設定
| 項目 | 設定値 |
|---|---|
| Name | blastengine error log |
| Type | Zabbix agent (active) |
| Key | logrt[/var/log/myapp/blastengine.log,"ERROR.*blastengine|\"level\":\"ERROR\"",,,skip,\0] |
| Type of information | Log |
| Update interval | 1s |
キーの解説
logrt[file,<regexp>,<encoding>,<maxlines>,<mode>,<output>]
- logrt: ログローテーションに対応しています(ファイル名が変わっても追跡)
- file: 監視対象のログファイルパス
-
regexp: マッチさせる正規表現(
ERROR.*blastengineまたは JSON形式の"level":"ERROR") -
mode:
skipを指定すると、エージェント起動時に既存行をスキップします -
output:
\0でマッチした行全体を取得します
log[] と logrt[] の使い分け
| キー | 用途 |
|---|---|
log[] |
ファイル名が固定の場合 |
logrt[] |
ログローテーションでファイル名が変わる場合(推奨) |
トリガー作成(連続エラーで発火)
単発のエラーでアラートを出すとノイズになりやすいです。直近の一定期間でN回以上エラーが発生した場合に発火させます。
手順
- 左メニューの Data collection → Hosts を開く
- ホスト一覧から対象ホストの Triggers リンクをクリック
- トリガー設定を入力し、右上の Create trigger ボタンをクリック
トリガー設定
| 項目 | 設定値 |
|---|---|
| Name | blastengine: Multiple errors detected |
| Severity | High |
| Expression | count(/app-server-01/logrt[/var/log/myapp/blastengine.log,"ERROR.*blastengine|\"level\":\"ERROR\"",,,skip,\0],5m)>=3 |
| OK event generation | Expression |
| Recovery expression | count(/app-server-01/logrt[/var/log/myapp/blastengine.log,"ERROR.*blastengine|\"level\":\"ERROR\"",,,skip,\0],5m)<3 |
Expression の解説
count(/host/key,5m)>=3
- count(): 指定期間内のイベント数をカウントします
- 5m: 直近5分間
- >=3: 3回以上でトリガー発火
重大度の目安
| Severity | 使用例 |
|---|---|
| Warning | 単発のエラー、リトライで回復する可能性あり |
| High | 複数回のエラー、メール送信に影響 |
| Disaster | 認証エラーなど、対処しないと復旧しない |
通知(Action)設定
トリガー発火時に通知を送る設定を行います。事前にMedia type(Email / Slack等)が設定済みであることを前提とします。
手順
- 左メニューの Alerts を展開
- Trigger actions をクリック
- Action設定を入力し、右上の Create action ボタンをクリック
Action設定
| タブ | 項目 | 設定値 |
|---|---|---|
| Action | Name | Notify blastengine errors |
| Action | Conditions | Trigger name contains blastengine
|
| Operations | Operation type | Send message |
| Operations | Send to user groups | (通知先グループ) |
| Operations | Send only to | Email / Slack など |
メッセージテンプレート例
件名
[{TRIGGER.SEVERITY}] {HOST.NAME}: blastengine error detected
本文
発生時刻: {EVENT.DATE} {EVENT.TIME}
ホスト: {HOST.NAME}
トリガー: {TRIGGER.NAME}
重大度: {TRIGGER.SEVERITY}
該当ログ:
{ITEM.LASTVALUE}
対応手順:
1. blastengine管理画面でAPIキーの状態を確認
2. アプリケーションログで詳細を確認
3. 必要に応じてAPIキーの再発行
Zabbix: {$ZABBIX.URL}/tr_events.php?triggerid={TRIGGER.ID}
動作確認(わざと失敗させる)
設定が正しく動作するか、意図的にエラーを発生させて確認します。
テスト用にエラーを発生させる方法
# 方法1: 無効なAPIキーでリクエスト(401エラー)
curl -X POST https://app.engn.jp/api/v1/deliveries/transaction \
-H "Authorization: Bearer invalid_api_key" \
-H "Content-Type: application/json" \
-d '{"to":"test@example.com","subject":"test","text_part":"test"}'
# 方法2: ログファイルに直接テストデータを書き込む
echo '{"timestamp":"2025-01-15T10:00:00+09:00","level":"ERROR","endpoint":"/api/v1/deliveries","status":401,"error_code":"UNAUTHORIZED","message":"Test error","request_id":"test_001"}' >> /var/log/myapp/blastengine.log
確認手順
- 左メニューの Monitoring → Latest data→Hostsを選択→Applyボタン でアイテムに値が入っているか確認します
- 左メニューの Monitoring → Problems **→ Hostsを選択 → Applyボタン でトリガーが発火しているか確認します
- 通知(メール / Slack)が届いているか確認します
トラブルシューティング
| 症状 | 確認ポイント |
|---|---|
| Latest dataに値が来ない | Agent 2がログを読めているか(権限)、Hostnameが一致しているか |
| トリガーが発火しない | 正規表現がマッチしているか、閾値(count >= N)を満たしているか |
| 通知が届かない | Media typeの設定、Actionの条件 |
運用メモ(詰まりどころだけ)
ログローテーション対応
-
logrt[]を使っていれば、ファイル名の変更(blastengine.log.1など)に自動追従します -
圧縮タイミングに注意: ローテーション直後に圧縮(
.gz)すると、未読のログが読めなくなります。delaycompressオプションで1世代遅らせてください
# /etc/logrotate.d/myapp の例
/var/log/myapp/blastengine.log {
daily
rotate 7
missingok
notifempty
delaycompress
compress
create 640 appuser zabbix
}
権限問題
- ログローテーション後に権限がリセットされる場合があります
-
createディレクティブでzabbixグループを指定するか、setfaclのデフォルトACLを設定しておきます
アイテムが値を取得しない場合のチェックリスト
-
zabbix_agent2 -t 'logrt[...]'でローカルテスト -
/var/log/zabbix/zabbix_agent2.logでエラー確認 - SELinux/AppArmorが有効な場合、ログファイルへのアクセスが拒否されていないか確認
まとめ
本記事では、blastengine連携処理の失敗ログをZabbixで検知・通知する最短構成を紹介しました。
構成のポイント
- アプリ側で「1行1イベント」のログ出力を用意する
- Zabbix Agent 2のアクティブチェック(
logrt[])でログ監視を行う -
count()関数で「直近N分でM回以上」の条件でトリガーを発火させる - ActionでSlack/メール通知を設定する
次の改善として考えられること
- エラーコード別にトリガーを分割する(401は即時対応、429はレート制限で様子見など)
- ダッシュボードでエラー発生傾向を可視化する