システムが大きくなるにつれたログ管理:誰もが避けたいが誰もが直面する問題
最初に2〜3台のサーバーをセットアップした頃は、各マシンにSSHで直接接続してtail -f /var/log/syslogでデバッグしていた。それで十分だった — サーバーが8台、15台と増えるまでは。深夜2時に本番環境でエラーが発生し、エラーメッセージを探すために各マシンにSSHしなければならないとき、それが集中ログ管理を本当に必要とする瞬間だ。
Graylogは「十分に痛い思い」をした後に本番環境に導入したものだ。6ヶ月間の実運用を経て、本当に役立ったことだけをまとめる — 公式ドキュメントのコピーではなく。
Graylogとは何か、なぜELK Stackを使わないのか?
率直に言おう:Graylogはすべてのサーバーからログを受け取り、OpenSearchにインデックス化し、単一のUIから検索とアラート作成を可能にする。10個のターミナルタブを開いて各マシンでgrepする光景はもう終わりだ。
アーキテクチャは3つの主要コンポーネントで構成される:
- Graylog Server:ログの処理、パース、ルーティング
- MongoDB:メタデータの保存 — 設定、ユーザー、ストリーム、アラート
- OpenSearch(またはElasticsearch):全文検索エンジン — ログが実際に保存・クエリされる場所
ELK Stackはどうか?両方試した。ELKはカスタマイズ性が高いが、正しくセットアップするのに2〜3日かかる。Graylogなら半日で完了する。専任のDevOpsがいない小さなチームにとって、その差は大きい — 特にアラートとストリーム管理の面ではGraylogが明らかに優れている。
Docker ComposeでGraylogをインストールする
Docker Composeは最も手軽にGraylogを動かす方法だ。開発環境から小規模本番環境まで使っている — 1日50GB以下のログ量なら安定して動作する。
docker-compose.ymlファイルを作成する:
version: '3.8'
services:
mongodb:
image: mongo:6.0
volumes:
- mongodb_data:/data/db
restart: unless-stopped
opensearch:
image: opensearchproject/opensearch:2.11.0
environment:
- discovery.type=single-node
- DISABLE_SECURITY_PLUGIN=true
- OPENSEARCH_JAVA_OPTS=-Xms1g -Xmx1g
ulimits:
memlock:
soft: -1
hard: -1
volumes:
- opensearch_data:/usr/share/opensearch/data
restart: unless-stopped
graylog:
image: graylog/graylog:5.2
environment:
- GRAYLOG_PASSWORD_SECRET=somepasswordpepper1234567890abc
- GRAYLOG_ROOT_PASSWORD_SHA2=8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918
- GRAYLOG_HTTP_EXTERNAL_URI=http://YOUR_SERVER_IP:9000/
- GRAYLOG_ELASTICSEARCH_HOSTS=http://opensearch:9200
- GRAYLOG_MONGODB_URI=mongodb://mongodb:27017/graylog
depends_on:
- mongodb
- opensearch
ports:
- "9000:9000" # Web UI
- "12201:12201/udp" # GELF UDP入力
- "514:514/udp" # Syslog UDP入力
volumes:
- graylog_data:/usr/share/graylog/data
restart: unless-stopped
volumes:
mongodb_data:
opensearch_data:
graylog_data:
重要:上記のGRAYLOG_ROOT_PASSWORD_SHA2は「admin」という文字列のハッシュ値だ。実際にデプロイする前に必ず変更すること:
echo -n "your_strong_password" | sha256sum | cut -d' ' -f1
スタックを起動する:
docker compose up -d
# Graylogが完全に起動するまで60〜90秒待つ
docker compose logs -f graylog
Web UIはhttp://YOUR_SERVER_IP:9000で起動する。adminと先ほど作成したパスワードでログインする。
ログを受け取るInputの作成
Web UIでSystem → Inputsを開く。まずこの2つのInputを作成する:
1. Syslog UDP(ポート514)
Syslog UDPを選び、bind addressを0.0.0.0、ポートを514に設定する。このInputはrsyslogから直接ログを受け取る — 高速でシンプル、追加エージェントのインストールは不要だ。
2. GELF UDP(ポート12201)
GELF UDPを選び、ポートを12201に設定する。GELF(Graylog Extended Log Format)は構造化されたJSONフォーマットだ — カスタムフィールドをサポートしており、Dockerコンテナのログやカスタムアプリケーションのログに適している。
クライアントサーバーでrsyslogを設定する
Graylogにログを送信する各Linuxサーバーでrsyslogを設定する:
sudo nano /etc/rsyslog.d/90-graylog.conf
ファイルに次の1行を追加する:
# すべてのログをUDP経由でGraylogに送信する
*.* @GRAYLOG_SERVER_IP:514;RSYSLOG_SyslogProtocol23Format
rsyslogを再起動してすぐにテストする:
sudo systemctl restart rsyslog
# テストメッセージを送信
logger -t test "Hello from $(hostname)"
Graylog Web UI → Searchを開き、source:自分のホスト名で検索する — 「Hello from…」メッセージが表示されれば完了だ。
GELF経由でDockerコンテナのログを送信する
Dockerの場合、監視が必要なサービスのdocker-compose.ymlにログドライバーを追加する:
services:
my_app:
image: my_app:latest
logging:
driver: gelf
options:
gelf-address: "udp://GRAYLOG_SERVER_IP:12201"
tag: "my_app"
ストリームとアラートの作成
ストリームはGraylogで最も気に入っている機能だ。ルールに従ってログを専用の「チャンネル」にルーティングする — Nginx用、SSH認証用、アプリケーションエラー用にそれぞれ専用ストリームを用意する。サービスごとにデバッグする際、全体のログに埋もれることなく確認できるので非常に便利だ。
Streams → Create Streamでストリームを作成する。便利なルールの例:
- Field
sourcecontainswebserver-01— 特定のサーバーのログをフィルタリング - Field
messagematches regexERROR|CRITICAL|FATAL— すべてのエラーをキャッチ - Field
facilityequalsauth— 認証ログのみ取得(SSH、sudo)
ストリームを作成したらAlert Conditionを追加する。例:「5分間に10件以上のERRORメッセージがあれば通知を送る」。Notificationと組み合わせてSlack、メール、webhookに送信できる — 好みに応じて設定すればいい。
正直に言うと:アラート疲れは最初から直面した現実の問題だ。閾値を低く設定しすぎてアラートが連続して発火し、やがてすべて無視するようになった。何度もチューニングが必要だった:閾値を上げ、AND条件を追加し、特定のソースをホワイトリストに入れる。得た教訓:高い閾値から始め、1〜2週間観察してシステムのベースラインを把握してから徐々に下げること。本番環境には独自のトラフィックパターンがある — どこかのブログの数値をそのままコピーしてはいけない。
6ヶ月の実運用後の結論
Graylogは「ログはどこに?」という問題を本当に効果的に解決する。半年間で気づいたこと:
- インシデントのデバッグ時間が約30分から約5分に短縮 — 1つのUIでサーバーをまたいだ検索が可能になったため
- 失敗した認証ログのアラートにより、SSHブルートフォース攻撃を2回検出できた
- リテンションポリシー(30日以上経過したログを自動削除)によりディスク使用量を安定維持 — 突然のディスク枯渇を心配しなくて済む
事前に知っておくべき点:GraylogはRAMをかなり消費する。1ノードクラスターの場合、安定稼働に最低8GBが必要だった — OpenSearchだけで2〜4GBを消費する。スペックの低いサーバーの場合はGrafana Lokiを検討するといい:はるかに軽量で検索性能は少し劣るが、ほとんどのケースには十分だ。
予算があって20台以上のサーバーを管理しているなら — Graylogはまだ信頼できる選択だ。一度セットアップすれば長く使える。次に深夜2時にデバッグする時は、ずっと楽になるはずだ。
