サーバーを「渡り歩いて」ログを探す日々
キャリアを始めたばかりの頃、私は5台ほどのVPSでWebサイトを運用していました。エラーが発生するたびに、サーバー1にSSHで入り、tail -fを叩き、何もなければログアウトしてサーバー2へ……という作業の繰り返しに、正直うんざりしていました。5台ならまだしも、システムがスケールしてSwitchやRouterを含む20〜30ノードになると,このやり方は生産性の面で致命的です。
さらに大きなリスクはセキュリティ面です。もしハッカーが侵入して/var/log/内の痕跡を消去したり、サーバーが突然ハードウェア故障を起こしたりすれば、原因調査は不可能になります。その時、ログの一元管理(Centralized Logging)は単なる選択肢ではなく、必須要件であると痛感しました。
なぜログの「中央倉庫」が必要なのか?
最大の問題はデータの分散です。Load BalancerのエラーがWeb AppやDatabaseに波及した場面を想像してみてください。異なるタイムラインのイベントを突き合わせる際、それらが一箇所にまとまっていなければ,調査は苦行でしかありません。
また、ローカルにログを保存し続けると、ディスク容量不足を引き起こしやすくなります。あるサービスがエラーの無限ループに陥ってログを吐き出し続ければ、わずか数時間で10〜20GBを消費し、サーバー自体をハングアップさせてしまうこともあります。
Rsyslog:軽量・高速・低コストな解決策
現在、多くのログ管理ツールがありますが、それぞれ用途が異なります:
- クラウドソリューション(Datadog、Splunk): 非常に強力ですが、ログ量が多いと月末の請求額が数千ドルに達することもあります。
- ELK Stack(Elasticsearch, Logstash, Kibana): プロフェッショナルで検索も高速ですが、リソースを非常に多く消費します。基本的なELK構成を安定して動かすには、最低でも8GBのRAMが必要です。
- Rsyslog: Ubuntuに標準搭載されており、非常に軽量(RAM消費量はわずか10〜20MB程度)で、設定も簡単です。
ステップ1:Rsyslogサーバー(受信側)の設定
ログサーバーのIPアドレスを192.168.1.100と仮定します。まずは、他のマシンからのログを受け取るためにポートを開放します。
設定ファイルを以下のコマンドで開きます:
sudo nano /etc/rsyslog.conf
以下の行を探してコメントアウトを解除します。高速な転送のためにUDPを、ログの欠損を防ぐためにTCPを、両方有効にすることをお勧めします:
# UDP経由でログを受信
module(load="imudp")
input(type="imudp" port="514")
# TCP経由でログを受信
module(load="imtcp")
input(type="imtcp" port="514")
50台ものサーバーからのログがすべて1つのsyslogファイルに混ざると混乱するため、これらを分類します。GLOBAL DIRECTIVESセクションの前に、以下のテンプレートを追加してください:
$template RemoteLogs,"/var/log/remote/%HOSTNAME%/%PROGRAMNAME%.log"
*.* ?RemoteLogs
& ~
この設定により、Rsyslogはホスト名ごとのディレクトリと、アプリケーション名ごとのファイルを自動的に作成します。& ~の行は非常に重要です。これはテンプレートに記録した後、そのログの処理を停止することを指示するもので、ローカルのシステムログファイルへの二重書き込みを防ぎます。
サービスを再起動し、ファイアウォールを開放します:
sudo systemctl restart rsyslog
sudo ufw allow 514/udp
sudo ufw allow 514/tcp
ステップ2:Rsyslogクライアント(送信側)の設定
クライアント側の設定は非常にシンプルです。ログを中央サーバーに転送するように指定するだけです。
sudo nano /etc/rsyslog.conf
ファイルの末尾に以下の行を追加します(UDPの場合は@を1つ、TCPの場合は@@を2つ使用します):
*.* @@192.168.1.100:514
その後、サービスを再起動します:sudo systemctl restart rsyslog
ステップ3:結果の確認
ログサーバー側で、/var/log/remote/ディレクトリを確認してください。クライアントマシンのホスト名が付いたディレクトリがすぐに表示されるはずです。
ls /var/log/remote/
Logrotateによる容量管理
ログを一箇所に集めても、整理しなければディスクはすぐに一杯になってしまいます。約10台のサーバーから継続的にログが送られてくると、1日に数GBを消費することもあります。そこで、logrotateを使用して古いログを圧縮・削除します。
新しい設定ファイルを作成します:
sudo nano /etc/logrotate.d/remote-logs
以下の内容を記述します:
/var/log/remote/*/*.log {
daily
missingok
rotate 30
compress
notifempty
sharedscripts
postrotate
/usr/lib/rsyslog/rsyslog-rotate
endscript
}
この設定では、ログを毎日ローテーションし、直近の30世代分を保持して圧縮します。ログを圧縮することで、容量を最大90%節約できます。
運用における重要な注意点
- セキュリティ第一: Syslogはデフォルトで暗号化されません。インターネット経由でログを送信する場合は、VPN(WireGuardなど)を通すか、TLSを設定してください。絶対にポート514をパブリックインターネットに公開しないでください。
- 時刻同期: すべてのサーバーにNTPをインストールしてください。タイムゾーンや時刻がずれていると、サーバー間のエラー調査は出口のない迷路になります。
- 送信元でのフィルタリング: アプリケーションが大量の不要なログ(デバッグログなど)を出力する場合は、転送帯域を節約するためにクライアント側でフィルタリングを設定してください。
Syslogサーバーの構築は、プロフェッショナルなシステム管理者への第一歩です。バグ修正が楽になるだけでなく、将来的にアラートシステム(Alerting)を構築するための基盤にもなります。

