AIでサーバーの稼働状況分析レポート

サーバーのパフォーマンス情報をAIに与えて、稼働状況レポートをCronでメール報告させようとしたときの覚書。
Gemini 3 Pro Previewと対話。

環境: FreeBSD 14.3-RELEASE-p7

このサーバーは主にWordPressウェブサーバー。


1. サーバー情報の収集

収集するサーバーのシステム情報一覧


2. Cronジョブ生成

Gemini先生と対話してシェルスクリプトを生成。

必要なツールをインストール。
jqはJSONのコマンドライン処理ツール(デフォルトでインストール済みだった)。
# pkg install bash curl jq

Gemini先生へ渡した初期プロンプト

生成AIにサーバーの稼働状況の情報を与えて、分析レポートをCronで毎日報告させるバッチを考えています。
収集するサーバー情報が増えてもメンテナンスしやすいシェルスクリプトを教えてください。

環境: FreeBSD 14.3-RELEASE-p7
サーバー用途: WordPressウェブサーバー
生成AI: Gemini API(Gemini 2.5 Pro)

#### 収集するサーバー情報一覧
- systat(パフォーマンス統計情報)
- collectdで収集した情報
- Nginx VTS (Virtual Host Traffic Status)
- OPcache GUIの情報
- ファイヤーウォール(pfとfail2ban)のログ情報
- MariaDBのパフォーマンスView
- PHPのエラーログとphp-fpm-slow.log
- /var/log/maillogと/var/log/messages

生成されたスクリプト構成。

ai_report/
├── config.env              # APIキーや設定
├── ai_server_report.sh     # メイン実行スクリプト
└── collectors/             # データ収集モジュール置き場
    ├── 00_system.sh
    ├── 10_nginx.sh
    ├── 20_db.sh
    ├── 30_php.sh
    ├── 40_firewall.sh
    └── 99_logs.sh

あとは実行して修正を指示しながら完成させる。
最後に改善案をGemini先生に聞くといい感じにしてくれる。

実行結果。
# ./ai_server_report.sh

Collecting Server Data...
Running module: 00_system.sh
Running module: 05_collectd.sh
Running module: 10_nginx.sh
Running module: 20_db.sh
Running module: 30_php.sh
Running module: 40_firewall.sh
Running module: 99_logs.sh
Sending request to Gemini API...
Subject: [AI Report] Server Daily Analysis - 2025-12-31

2025年12月31日 サーバー日次レポート (server01.hoge.jp)

【概要】
注意が必要です。サーバーリソースには余裕がありますが、データベースのパフォーマンス指標の一部が悪化しており、アプリケーションレベルで複数のエラーが記録されています。

【パフォーマンス分析】
- CPU/メモリ/Load Averageの傾向
  - Load Averageは平均0.25前後、CPU使用率は平均1%未満と、サーバー全体の負荷は非常に低いレベルで安定しています。
  - メモリ、スワップ共に十分な空きがあり、リソースの枯渇は見られません。
  - ZFSのI/Oも低く、ディスクアクセスは軽微です。

- Collectdの統計に基づく特記事項
  - 終日、CPU、メモリ、ネットワークトラフィックに急激なスパイクは見られず、安定して稼働しています。

- MariaDBのスロークエリ状況
  - 本日、2件のスロークエリが記録されました。
  - 以下のパフォーマンス指標が目標値を下回っており、チューニングが必要です。
    ・InnoDBバッファプールヒット率: 84.11% (目標: 99.5%以上)
      - メモリからデータを読み出せず、ディスクからの読み込みが多発している状態です。
    ・一時テーブルのディスク作成比率: 11.41% (目標: 5%未満)
      - 複雑なソートや集計処理がメモリ内で完結せず、低速なディスクI/Oが発生しています。
    ・インデックス未使用のJOIN (SELECT_FULL_JOIN): 24件 (目標: 0件)
      - 非効率なテーブル結合が発生しており、クエリのパフォーマンス低下に繋がっています。

【セキュリティとログ分析】
- ファイアウォールや認証エラーの傾向
  - Fail2banのレートリミット監視 (nginx-limit-req) により、本日新たに17件のIPアドレスがブロックされました。累計ブロック数は844件に達しており、外部からの攻撃的なスキャン活動が継続しています。
  - ファイアウォールは正常に機能し、これらの不正アクセスを遮断しています。

- PHP/Webサーバーのエラーログからの指摘事項
  ・Nginxでは、正常応答 (2xx) に比べてクライアントエラー (4xx) の件数が多くなっています。これは、存在しないファイルへのアクセス試行など、外部からの探索的なアクセスが多いことを示唆しています。
  ・PHPエラーログに、対処が必要な2種類の問題が記録されています。
    1. PHP Warning: 午前6時のバッチ処理 (`import-hospital-public-data`) 実行時に、XMLのパースエラーが大量に発生しています。処理対象のデータに不正な文字 (` `) が含まれていることが原因です。
    2. PHP Fatal error: 複数のWordPressサイトで、コア関数 `get_locale()` が未定義であるという致命的なエラーが発生しています。WordPressの読み込み処理に問題が発生している可能性があり、サイト表示に影響が出ている恐れがあります。

【改善提案】
- MariaDBのパフォーマンスチューニング
  - InnoDBバッファプールのヒット率を改善するため、`innodb_buffer_pool_size` の設定値を見直すことを推奨します。
  - インデックスが使われていないJOINクエリ (SELECT_FULL_JOIN) の原因を特定し、適切なインデックスを追加する必要があります。スロークエリログの有効化とEXPLAINによる分析を推奨します。

- PHPアプリケーションの修正
  - `import-hospital-public-data` スクリプトについて、XMLをパースする前に不正な文字を置換・除去する処理を追加するよう、開発担当者へ修正を依頼してください。
  - `get_locale()` 関数のFatal errorについて、原因調査が必要です。対象サイトのプラグインやテーマの互換性、WordPressコアファイルの整合性を確認してください。

- ZFSスナップショットの整理
  - 起動ディスク (zroot/ROOT) に多数の古いシステムアップデート時のスナップショットが残っています。ディスク容量を圧迫するため、不要なスナップショットの削除を推奨します。


後は運用しながらアップデートしていく。

これ本当に導入して良かった。
膨大な量の情報から注意すべきものと改善提案までしてくれるので、保守運用の次世代を感じる。


▼ 関連記事