
サーバ監視から1次調査、レポート作成してくれるAIツールつくってみた
明けましておめでとうございます。MSP事業部運用チーム新人エンジニアのHAです。
入社し3ヶ月ほど経過した私の視点からAIを組み込んだツール作成、検証を最近トライしましたので、
シェアいたします。
MSPアシストとは
私たちネットアシストが提供している看板サービス「MSPアシスト」は、
24/365体制でお客様のサーバを監視保守から運用までお任せいただけるサービスとなっており、
Cloudベンダーやミドルウェア構成、スペックを問わないことはもちろんのこと、 お客様の運用目的にアジャストした対応、提案が強みとなっております。
具体的には、いわゆる監視オペレータ的な手順書対応に限らず、ミドルウェアのパラーメータ調整からWaf等のセキュリティ製品導入まで幅の広い知識を個々のエンジニアが
日々学びながら高めることでお客様目線のより良いサービスを提供しております。
本記事のテーマ(アラート対応×AI)
このブログでは、MSPアシストのサービス中でも、アラート対応と呼ばれる、
お客様のサーバを監視しているサーバが異常を検知した際の対応を
一部AIを活用した自動化を行えないか、私個人視点で検討したものになります。
アラート対応の一般的な流れ
まずアラート対応は、大きく下記のようなプロセスとなります。
1.監視サーバがお客様サーバの異常を検知
2.お客様サーバへ接続し、閲覧系コマンドを利用し、直接的な原因を特定
3.お客様にアラート検知及びサーバ内状況をご報告
4.根本的な原因、改善のための対策提案
5.対策しクローズ
もちろんケースバイケースで上記のようなプロセスをとらないことも多いですが、
おおまかには以上の流れをとります。
ネットアシストの強みが発揮されるポイント
そして、技術力や経験が求められ、ネットアシストが強みとしているのは4以降のプロセスとなります。
したがってエンジニアリソースをなるべく4以降に集中することが品質向上につながると考え、
1から3の部分を下記の構成で自動化できないか検証してみました。
構成概要
Zabbix(監視サーバ)
↓ Webhook
AWS Lambda
↓
SSM Run Command
↓
EC2(閲覧コマンド 実行)
↓
Amazon Bedrock(AI要約)
↓
障害レポート生成
構成上の注意点
!!!ご注意!!!
念の為ですが、上記の構成は、現在のネットアシスト内の実際の構成とは異なるもので、
あくまでも検証目的の趣味的なものと捉えてください。
使用したLambdaコード(ディスク容量アラート対応)
この構成での構築をすべて手順にすると冗長になりすぎるので、
サーバ構築やzabbixのWebhook設定はいい感じでやっていただきまして、
コアとなるLambdaのJSコード(ディスク容量アラート対応)が下記となります。
検証結果だけご興味ある方は飛ばしてください。
import {
SSMClient,
SendCommandCommand,
GetCommandInvocationCommand
} from "@aws-sdk/client-ssm";
import {
BedrockRuntimeClient,
InvokeModelCommand
} from "@aws-sdk/client-bedrock-runtime";
/* =====================
環境設定(ダミー)
===================== */
// 実環境では環境変数や
// Zabbixホスト名 → EC2タグ解決などを想定
const REGION = "<AWS_REGION>";
const INSTANCE_ID = "<TARGET_EC2_INSTANCE_ID>";
const ssm = new SSMClient({ region: REGION });
const bedrock = new BedrockRuntimeClient({ region: REGION });
export const handler = async (event) => {
console.log("RAW EVENT:", JSON.stringify(event, null, 2));
/* =====================
0. Zabbix Webhook 受信
===================== */
// Zabbixのトリガーアクションから
// Webhookで送信された内容をパース
const zabbixEvent = JSON.parse(event.body);
/*
zabbixEvent 例:
{
host: "<TARGET_HOST>",
trigger: "Linux: FS [/]: Space is low",
severity: "Warning",
status: "PROBLEM",
item_value: "89.5 %",
time: "2025-xx-xx xx:xx:xx"
}
*/
console.log("ZABBIX EVENT:", zabbixEvent);
/* =====================
1. SSM RunCommand
===================== */
const commands = [
"echo '### FILESYSTEM USAGE ###'",
"df -h /",
"echo '### TOP DIRECTORIES UNDER / ###'",
"du -xh / --max-depth=2 | sort -h | tail -15",
"echo '### TOP DIRECTORIES UNDER /var ###'",
"du -xh /var --max-depth=2 | sort -h | tail -15",
"echo '### LARGE FILES (>100MB) UNDER /var ###'",
"find /var -type f -size +100M -exec ls -lh {} \\; 2>/dev/null | sort -k5 -h | tail -10",
"echo '### RECENTLY UPDATED LARGE FILES ###'",
"find /var -type f -size +100M -mmin -1440 -exec ls -lh {} \\; 2>/dev/null | sort -k6,7"
];
const sendResult = await ssm.send(
new SendCommandCommand({
InstanceIds: [INSTANCE_ID],
DocumentName: "AWS-RunShellScript",
Parameters: { commands }
})
);
const commandId = sendResult.Command.CommandId;
console.log("SSM CommandId:", commandId);
// 実行完了を最低限待機
await new Promise(r => setTimeout(r, 5000));
const invocation = await ssm.send(
new GetCommandInvocationCommand({
CommandId: commandId,
InstanceId: INSTANCE_ID
})
);
const ssmOutput = invocation.StandardOutputContent;
console.log("=== SSM OUTPUT ===\n", ssmOutput);
/* =====================
2. Bedrock(Claude 3 Haiku)
===================== */
// 取得した調査結果を
// そのまま「報告文」に変換
const prompt = `
あなたは熟練したインフラエンジニアです。
以下はディスク逼迫アラートとサーバ調査結果です。
【Zabbix Alert】
- Host: ${zabbixEvent.host}
- Trigger: ${zabbixEvent.trigger}
- Severity: ${zabbixEvent.severity}
- Status: ${zabbixEvent.status}
- Item value: ${zabbixEvent.item_value}
- Time: ${zabbixEvent.time}
【SSM 調査結果】
${ssmOutput}
以下を日本語で簡潔にまとめてください。
1. 障害の概要
2. 想定される原因
3. 影響範囲
4. 即時対応案
5. 恒久対応案
`;
const bedrockResponse = await bedrock.send(
new InvokeModelCommand({
modelId: "anthropic.claude-3-haiku-20240307-v1:0",
contentType: "application/json",
accept: "application/json",
body: JSON.stringify({
anthropic_version: "bedrock-2023-05-31",
max_tokens: 600,
messages: [
{
role: "user",
content: prompt
}
]
})
})
);
const decoded = JSON.parse(
Buffer.from(bedrockResponse.body).toString("utf-8")
);
const report = decoded.content?.[0]?.text ?? "No output";
console.log("=== AI REPORT ===\n", report);
/* =====================
3. レスポンス返却
===================== */
// 実運用では:
// ・Slack通知
// ・チケット起票
// ・メール本文生成
// などに拡張可能
return {
statusCode: 200,
body: JSON.stringify({
status: "ok",
report
})
};
};
では検証結果をご報告します!
検証シナリオ(ログローテート失敗)
シナリオとしては、あるあるですが「ログローテート失敗」をやってみます。
※ログローテート失敗とは、本来は自動で圧縮・削除されるはずのログファイルが、
何らかの理由で処理されず、延々と溜まり続けてしまう状態のことです。
検証結果
①空きディスク容量のアラート状況をつくる
保守対象サーバでダミーファイル設置
fallocate -l 5G /var/log/httpd/access_log
設置後、まずはZabbixがアラート検知しました。
そしてそのアラートをwebhookでLambdaに飛ばします。
続いて、LambdaがSSM経由でコマンドをたたき、
先程のアラート内容+コマンドからの出力をBedrock(AI)に投げます。
②出力されたAIレポート
1. 障害の概要:
アプリケーションサーバ "app-server-01" のファイルシステム "/" の使用率が 83.37% と高く、
ディスク容量が不足しているという警告が発生しています。
2. 想定される原因:
ログファイルの肥大化が主な原因と考えられます。
"/var/log/httpd/access_log" ファイルが 5.0 GB と非常に大きくなっています。
最近更新された大きなファイルも見られることから、
ログファイルが急激に増大している可能性があります。
3. 影響範囲:
ファイルシステムの使用率が高いため、サーバ上の他のアプリケーションやサービスの動作に支障をきたす可能性があります。
4. 即時対応案:
1. ログファイルの整理を行う
- "/var/log/httpd/access_log" ファイルをアーカイブするか削除する
- その他の大きなログファイルも確認し、必要に応じて対処する
2. ファイルシステムの使用率を監視し、再びしきい値を超えないよう注意する
5. 恒久対応案:
1. ログファイルの自動削除/アーカイブ設定を行う
- logrotate などを使ってログファイルの自動管理を設定する
2. ファイルシステムのサイズ拡張を検討する
- ディスク容量の増設や別ディスクの追加など、ファイルシステムの容量を拡張する
③アラート検知からレポート出力までに要した時間
7:02:28 監視サーバが対象サーバでのディスク空容量10%以下アラート検知
7:02:39 AIレポート出力
→11秒で出力
考察
出力結果が妥当であることもさることながら、
アラート検知からレポート出力がほぼ同時という結果になりました!
もちろんこれは、原因特定が複雑なアラートであったり、
そもそもサーバリソース逼迫でコマンドが打てない等のケースでは対応が難しいですが、
そこは、人間にエスカレーションするフローにすれば解決するようにも思えます。
今回のブログでは、あまりに長くなるので割愛しましたが、このレポートを架電スクリプトにして、
お客様へAIがお電話する検証や直近半年のアラートを基にAIがレポート作成を行うなどおもしろそうなものを趣味的にトライしております。
まとめ
サーバのサービス停止のような一次対応をAIで実施することについては、
想定外のケースもありうるので慎重な検討が求められますが、
今回行ったような閲覧系コマンド×レポート出力については、実務利用可能な水準にきていることを、
今回のトライで学びました。





