Linuxシステムで発生する問題を解決するためには、ログの読み方と活用法を理解することが不可欠です。サービスが起動しない、応答が遅い、原因不明のエラーが発生するといった状況において、ログは問題解決の糸口を与えてくれます。
この記事では、Linuxログ管理の基盤となる/var/logディレクトリの構造、systemd-journaldとjournalctlによる高度なログ分析、従来のrsyslogの設定方法、ログローテーションの仕組み、そして実際の障害調査アプローチまでを体系的に解説します。
前提条件と動作確認環境#
本記事の内容は以下の環境で動作確認しています。
| 項目 |
内容 |
| OS |
Ubuntu 24.04 LTS / AlmaLinux 9 |
| systemd |
255 |
| rsyslog |
8.2302以上 |
| シェル |
bash 5.2 |
基本的なLinuxコマンドライン操作ができることを前提としています。
Linuxログシステムの全体像#
現代のLinuxディストリビューションでは、2つのログシステムが共存しています。
graph TB
subgraph アプリケーション
A1[Webサーバー]
A2[データベース]
A3[カスタムアプリ]
end
subgraph カーネル
K[カーネルメッセージ]
end
subgraph ログシステム
J[systemd-journald<br/>バイナリログ]
R[rsyslog<br/>テキストログ]
end
subgraph 出力先
JF[/run/log/journal<br/>/var/log/journal]
VL[/var/log/]
end
A1 --> J
A2 --> J
A3 --> J
K --> J
J --> JF
J --> R
R --> VL
| ログシステム |
特徴 |
出力形式 |
| systemd-journald |
systemd統合のログ管理、構造化データ、高速検索 |
バイナリ |
| rsyslog |
従来型のsyslog、リモート転送対応、柔軟なフィルタリング |
テキスト |
多くのディストリビューションでは、journaldがログを収集し、rsyslogに転送して従来形式のテキストファイルとして保存する構成が採用されています。
/var/logディレクトリの構造#
Linuxシステムのログは、主に/var/logディレクトリに格納されます。主要なログファイルの役割を理解しておきましょう。
主要なログファイル一覧#
| ファイル/ディレクトリ |
内容 |
/var/log/syslog |
システム全般のログ(Debian/Ubuntu系) |
/var/log/messages |
システム全般のログ(RHEL/CentOS系) |
/var/log/auth.log |
認証関連のログ(Debian/Ubuntu系) |
/var/log/secure |
認証関連のログ(RHEL/CentOS系) |
/var/log/kern.log |
カーネルメッセージ |
/var/log/dmesg |
起動時のカーネルメッセージ |
/var/log/boot.log |
起動プロセスのログ |
/var/log/cron |
cronジョブの実行ログ |
/var/log/mail.log |
メール関連のログ |
/var/log/nginx/ |
Nginxのアクセス/エラーログ |
/var/log/apache2/ |
Apacheのアクセス/エラーログ |
/var/log/mysql/ |
MySQLのログ |
/var/log/journal/ |
journaldのバイナリログ |
ディストリビューション別の違い#
Debian/Ubuntu系とRHEL/AlmaLinux系では、ログファイル名が異なる場合があります。
| 用途 |
Debian/Ubuntu |
RHEL/AlmaLinux |
| システム全般 |
/var/log/syslog |
/var/log/messages |
| 認証ログ |
/var/log/auth.log |
/var/log/secure |
| cronログ |
/var/log/syslog |
/var/log/cron |
ログファイルの基本的な閲覧#
1
2
3
4
5
6
7
8
9
10
11
|
# リアルタイムでログを監視
sudo tail -f /var/log/syslog
# 最新100行を表示
sudo tail -n 100 /var/log/auth.log
# 特定キーワードでフィルタリング
sudo grep "error" /var/log/syslog
# 特定の時刻以降のログを表示
sudo awk '$0 >= "Jan 8 10:00:00"' /var/log/syslog
|
journalctlによる高度なログ分析#
systemd-journaldは、systemd環境におけるログ管理の中心です。journalctlコマンドを使用することで、強力なフィルタリングと検索が可能になります。
journaldの設定#
journaldの設定ファイルは/etc/systemd/journald.confにあります。
1
|
sudo cat /etc/systemd/journald.conf
|
主要な設定項目:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
[Journal]
# ログの永続化設定(persistent: /var/log/journal に保存)
Storage=persistent
# 最大ディスク使用量
SystemMaxUse=500M
# 単一ファイルの最大サイズ
SystemMaxFileSize=50M
# ログ保持期間
MaxRetentionSec=1month
# 圧縮を有効化
Compress=yes
# リモート転送先のrsyslogに転送
ForwardToSyslog=yes
|
設定変更後はサービスを再起動します。
1
|
sudo systemctl restart systemd-journald
|
高度なフィルタリングオプション#
journalctlは多様なフィルタリングオプションを提供しています。
複合条件でのフィルタリング#
1
2
3
4
5
6
7
8
9
10
11
|
# 特定サービスのエラーログを時間指定で抽出
journalctl -u nginx -p err --since "2026-01-08 00:00:00" --until "2026-01-08 23:59:59"
# 特定ユーザーのセッションログ
journalctl _UID=1000 --since today
# 特定の実行ファイルに関するログ
journalctl _EXE=/usr/sbin/sshd
# 特定PIDのログ
journalctl _PID=1234
|
フィールド一覧の確認#
1
2
3
4
5
|
# 使用可能なフィールドを確認
journalctl -F _SYSTEMD_UNIT
# 特定フィールドの値一覧
journalctl -F SYSLOG_IDENTIFIER
|
ブート情報の活用#
1
2
3
4
5
6
7
8
9
10
11
12
13
|
# 過去のブート一覧を表示
journalctl --list-boots
# 出力例:
# -2 abc123 Wed 2026-01-06 10:00:00 JST—Wed 2026-01-06 18:00:00 JST
# -1 def456 Thu 2026-01-07 09:00:00 JST—Thu 2026-01-07 22:00:00 JST
# 0 ghi789 Fri 2026-01-08 08:00:00 JST—Fri 2026-01-08 19:00:00 JST
# 2回前の起動時のログを確認
journalctl -b -2
# 特定のブートIDを指定
journalctl -b abc123
|
カーネルメッセージの確認#
1
2
3
4
5
6
7
8
|
# カーネルメッセージのみ表示
journalctl -k
# 今回起動時のカーネルメッセージ
journalctl -k -b
# ハードウェアエラーの確認
journalctl -k -p err
|
出力形式のカスタマイズ#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
# JSON形式(プログラムでの処理用)
journalctl -u sshd -o json
# 整形されたJSON
journalctl -u sshd -o json-pretty
# 詳細表示(全フィールド表示)
journalctl -u sshd -o verbose
# 短い形式(タイムスタンプのみ)
journalctl -u sshd -o short-iso
# cat形式(メッセージのみ)
journalctl -u sshd -o cat
|
ログの永続化設定#
デフォルトでは、journaldのログは再起動で消える場合があります。永続化するには以下の設定を行います。
1
2
3
4
5
6
7
8
9
10
11
|
# ログ保存ディレクトリを作成
sudo mkdir -p /var/log/journal
# 所有権とパーミッションを設定
sudo systemd-tmpfiles --create --prefix /var/log/journal
# journaldを再起動
sudo systemctl restart systemd-journald
# 永続化されているか確認
journalctl --disk-usage
|
ログのメンテナンス#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
# 現在のディスク使用量を確認
journalctl --disk-usage
# 古いログを削除(サイズ指定)
sudo journalctl --vacuum-size=200M
# 古いログを削除(期間指定)
sudo journalctl --vacuum-time=2weeks
# ログファイル数で制限
sudo journalctl --vacuum-files=5
# 整合性チェック
journalctl --verify
|
rsyslogの設定と活用#
rsyslogは、従来のsyslogプロトコルを拡張した高機能なログデーモンです。テキスト形式でのログ保存、リモートサーバーへの転送、高度なフィルタリングが可能です。
rsyslogの基本設定#
rsyslogの設定ファイルは/etc/rsyslog.confです。
1
|
sudo cat /etc/rsyslog.conf
|
基本的な設定構造:
# モジュールの読み込み
module(load="imuxsock") # ローカルsyslogソケット
module(load="imklog") # カーネルログ
module(load="imjournal") # journaldからの入力
# グローバル設定
global(workDirectory="/var/lib/rsyslog")
# ルール設定
# ファシリティ.プライオリティ 出力先
*.info;mail.none;authpriv.none;cron.none /var/log/messages
authpriv.* /var/log/secure
mail.* -/var/log/maillog
cron.* /var/log/cron
*.emerg :omusrmsg:*
ファシリティとプライオリティ#
rsyslogでは、ログをファシリティ(発生源)とプライオリティ(重要度)で分類します。
ファシリティ一覧#
| ファシリティ |
説明 |
| kern |
カーネルメッセージ |
| user |
ユーザープロセス |
| mail |
メールシステム |
| daemon |
デーモン |
| auth |
認証システム |
| syslog |
syslog自身 |
| lpr |
プリンタ |
| cron |
cronデーモン |
| local0-7 |
カスタム用途 |
プライオリティ一覧#
| プライオリティ |
数値 |
説明 |
| emerg |
0 |
システム使用不能 |
| alert |
1 |
即時対応が必要 |
| crit |
2 |
致命的な状態 |
| err |
3 |
エラー |
| warning |
4 |
警告 |
| notice |
5 |
通常だが重要な状態 |
| info |
6 |
情報 |
| debug |
7 |
デバッグ |
カスタムログ設定の追加#
/etc/rsyslog.d/ディレクトリに設定ファイルを追加することで、カスタム設定を行えます。
アプリケーション専用ログの設定#
1
|
sudo vim /etc/rsyslog.d/50-myapp.conf
|
# local0ファシリティをmyappログに出力
local0.* /var/log/myapp/app.log
# 特定プログラム名でフィルタリング
:programname, isequal, "myapp" /var/log/myapp/app.log
& stop
# メッセージ内容でフィルタリング
:msg, contains, "ERROR" /var/log/errors.log
リモートサーバーへのログ転送#
1
|
sudo vim /etc/rsyslog.d/60-remote.conf
|
# UDP転送(軽量だが信頼性低)
*.* @192.168.1.100:514
# TCP転送(信頼性高)
*.* @@192.168.1.100:514
# 特定ファシリティのみ転送
auth.* @@192.168.1.100:514
# TLS暗号化転送(推奨)
# 証明書設定が必要
$DefaultNetstreamDriverCAFile /etc/ssl/certs/ca.pem
$ActionSendStreamDriver gtls
$ActionSendStreamDriverMode 1
$ActionSendStreamDriverAuthMode anon
*.* @@(o)192.168.1.100:6514
設定変更後は再起動が必要です。
1
2
3
4
5
|
# 設定ファイルの構文チェック
sudo rsyslogd -N1
# rsyslogを再起動
sudo systemctl restart rsyslog
|
テンプレートによるログ形式のカスタマイズ#
rsyslogでは、テンプレートを使用してログの出力形式をカスタマイズできます。
# カスタムテンプレートの定義
template(name="CustomFormat" type="string"
string="%timestamp:::date-rfc3339% %hostname% %syslogtag%%msg%\n")
# テンプレートを適用
*.* /var/log/custom.log;CustomFormat
# JSON形式テンプレート
template(name="JsonFormat" type="list") {
constant(value="{")
constant(value="\"timestamp\":\"")
property(name="timestamp" dateFormat="rfc3339")
constant(value="\",\"host\":\"")
property(name="hostname")
constant(value="\",\"program\":\"")
property(name="programname")
constant(value="\",\"message\":\"")
property(name="msg" format="json")
constant(value="\"}\n")
}
*.* /var/log/json.log;JsonFormat
logrotateによるログローテーション#
ログファイルは放置すると肥大化し、ディスク容量を圧迫します。logrotateを使用して、定期的なローテーション(世代管理)を行います。
logrotateの基本設定#
グローバル設定は/etc/logrotate.confに記述します。
1
|
sudo cat /etc/logrotate.conf
|
# 週単位でローテーション
weekly
# 4世代保持
rotate 4
# ローテーション後に新しいログファイルを作成
create
# 日付をファイル名に付加
dateext
# 圧縮を有効化
compress
# アプリケーション個別設定を読み込み
include /etc/logrotate.d
アプリケーション個別設定#
/etc/logrotate.d/ディレクトリに個別設定を配置します。
1
|
sudo vim /etc/logrotate.d/myapp
|
/var/log/myapp/*.log {
# 日単位でローテーション
daily
# 30世代保持
rotate 30
# ファイルが存在しなくてもエラーにしない
missingok
# 空ファイルはローテーションしない
notifempty
# 古いログを圧縮
compress
# 直近のローテーションは圧縮しない
delaycompress
# 新しいログファイルのパーミッション設定
create 0640 www-data adm
# ローテーション後にスクリプトを実行
postrotate
/usr/bin/systemctl reload myapp > /dev/null 2>&1 || true
endscript
# 複数ファイルでもスクリプトは1回だけ実行
sharedscripts
}
主要なlogrotateディレクティブ#
| ディレクティブ |
説明 |
| daily/weekly/monthly |
ローテーション頻度 |
| rotate N |
保持する世代数 |
| compress |
古いログをgzip圧縮 |
| delaycompress |
1世代前は圧縮しない |
| missingok |
ファイルがなくてもエラーにしない |
| notifempty |
空ファイルはローテーションしない |
| create mode owner group |
新ファイルの作成設定 |
| copytruncate |
ファイルをコピーして元を切り詰め(アプリ再起動不要) |
| size N |
サイズベースでローテーション |
| maxsize N |
時間とサイズの両方で判定 |
| dateext |
日付をファイル名に付加 |
| olddir /path |
古いログの保存先 |
| postrotate/endscript |
ローテーション後の処理 |
| prerotate/endscript |
ローテーション前の処理 |
サイズベースのローテーション#
時間ではなくファイルサイズでローテーションすることも可能です。
/var/log/myapp/app.log {
# 100MB超えたらローテーション
size 100M
# または時間とサイズの複合条件
# maxsize 100M
# daily
rotate 10
compress
missingok
notifempty
}
logrotateの手動実行とデバッグ#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
# デバッグモード(実際には実行しない)
sudo logrotate -d /etc/logrotate.conf
# 強制実行
sudo logrotate -f /etc/logrotate.conf
# 特定設定のみテスト
sudo logrotate -d /etc/logrotate.d/myapp
# 詳細出力
sudo logrotate -v /etc/logrotate.conf
# ステータスファイルの確認
sudo cat /var/lib/logrotate/status
|
障害調査の実践的アプローチ#
ログを活用した効果的なトラブルシューティングの手順を解説します。
トラブルシューティングのフローチャート#
graph TD
A[問題発生] --> B{症状の確認}
B --> C[エラーメッセージの特定]
C --> D[関連ログの収集]
D --> E{ログ分析}
E -->|原因特定| F[対策の実施]
E -->|原因不明| G[追加情報の収集]
G --> D
F --> H[動作確認]
H -->|解決| I[文書化]
H -->|未解決| Bケース1: サービス起動失敗の調査#
Webサーバーが起動しない場合の調査手順を示します。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
# 1. サービスの状態確認
sudo systemctl status nginx
# 出力例(エラーの場合):
# ● nginx.service - A high performance web server
# Active: failed (Result: exit-code) since ...
# Main PID: 1234 (code=exited, status=1/FAILURE)
# 2. 詳細なエラーログを確認
journalctl -u nginx -n 50 --no-pager
# 3. 設定ファイルの構文エラーをチェック
sudo nginx -t
# 4. 関連するエラーを時系列で追跡
journalctl -u nginx --since "10 minutes ago" -p err
# 5. 依存サービスの確認
systemctl list-dependencies nginx
# 6. ポートの競合確認
sudo ss -tlnp | grep :80
|
ケース2: SSH接続失敗の調査#
SSH接続が拒否される場合の調査手順です。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
# 1. 認証ログの確認(Ubuntu/Debian)
sudo tail -n 100 /var/log/auth.log | grep sshd
# RHEL/AlmaLinux系
sudo tail -n 100 /var/log/secure | grep sshd
# 2. journalctlでの確認
journalctl -u sshd --since "1 hour ago"
# 3. 特定IPからの接続試行を追跡
sudo grep "192.168.1.100" /var/log/auth.log
# 4. 失敗した認証のみを抽出
journalctl -u sshd | grep -i "failed\|invalid\|refused"
# 5. sshdの設定確認
sudo sshd -t
# 6. ファイアウォールの確認
sudo iptables -L -n | grep 22
sudo ufw status
|
ケース3: ディスク容量不足の調査#
システムの応答が遅い、ログが書き込めないなどの症状が出た場合の調査です。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
# 1. ディスク使用量の確認
df -h
# 2. 大きなファイルの特定
sudo du -sh /var/log/* | sort -hr | head -20
# 3. 最近更新されたログファイル
sudo find /var/log -type f -mmin -60 -exec ls -lh {} \;
# 4. 肥大化しているログの特定
sudo find /var/log -type f -size +100M
# 5. journalログの使用量確認
journalctl --disk-usage
# 6. 古いログの削除(一時対処)
sudo journalctl --vacuum-size=100M
sudo logrotate -f /etc/logrotate.conf
|
ケース4: システムクラッシュの事後調査#
システムが予期せず再起動した場合の調査方法です。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
# 1. 前回起動時のログを確認
journalctl -b -1
# 2. カーネルパニックやOOM Killerの確認
journalctl -b -1 -k | grep -i "panic\|oom\|killed"
# 3. シャットダウン/再起動の履歴
last reboot | head -10
# 4. 前回終了時のログ
journalctl -b -1 | tail -100
# 5. ハードウェアエラーの確認
journalctl -b -1 -p err | grep -i "hardware\|memory\|disk\|cpu"
# 6. dmesgの確認(カーネルリングバッファ)
sudo dmesg | grep -i "error\|fail\|warn"
|
ケース5: アプリケーションエラーの調査#
特定のアプリケーションで問題が発生した場合の調査です。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
# 1. アプリケーション固有のログ確認
sudo tail -f /var/log/myapp/app.log
# 2. エラーレベルでフィルタリング
sudo grep -i "error\|exception\|critical" /var/log/myapp/app.log
# 3. 特定時間帯のログ抽出
sudo awk '/Jan 8 14:00:/,/Jan 8 15:00:/' /var/log/myapp/app.log
# 4. エラー発生頻度の分析
sudo grep "ERROR" /var/log/myapp/app.log | cut -d' ' -f1-3 | uniq -c | sort -rn
# 5. 関連プロセスの確認
ps aux | grep myapp
# 6. リソース使用状況の確認
top -p $(pgrep myapp)
|
ログ分析のワンライナー集#
実務でよく使用するログ分析コマンドをまとめます。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
# SSHログイン失敗のIPアドレス別集計
sudo grep "Failed password" /var/log/auth.log | \
awk '{print $(NF-3)}' | sort | uniq -c | sort -rn | head -20
# HTTPステータスコード別集計(Nginxアクセスログ)
sudo awk '{print $9}' /var/log/nginx/access.log | sort | uniq -c | sort -rn
# 時間帯別アクセス数
sudo awk '{print $4}' /var/log/nginx/access.log | cut -d: -f2 | sort | uniq -c
# 最もアクセスの多いURL
sudo awk '{print $7}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20
# 直近1時間のエラーログ抽出
journalctl --since "1 hour ago" -p err --no-pager
# 特定エラーの初出時刻を特定
journalctl | grep -m 1 "特定のエラーメッセージ"
|
ログ監視の自動化#
問題を早期発見するために、ログ監視を自動化することが重要です。
シンプルなログ監視スクリプト#
1
2
3
4
5
6
7
8
9
10
11
12
13
|
#!/bin/bash
# /usr/local/bin/log-alert.sh
LOG_FILE="/var/log/syslog"
ALERT_PATTERNS="error|critical|failed|panic"
MAIL_TO="admin@example.com"
# 直近5分間のログをチェック
ERRORS=$(journalctl --since "5 minutes ago" -p err --no-pager 2>/dev/null)
if [ -n "$ERRORS" ]; then
echo "$ERRORS" | mail -s "[ALERT] System Errors Detected" "$MAIL_TO"
fi
|
systemd timerによる定期監視#
1
2
|
# /etc/systemd/system/log-alert.service
sudo vim /etc/systemd/system/log-alert.service
|
1
2
3
4
5
6
|
[Unit]
Description=Log Alert Service
[Service]
Type=oneshot
ExecStart=/usr/local/bin/log-alert.sh
|
1
2
|
# /etc/systemd/system/log-alert.timer
sudo vim /etc/systemd/system/log-alert.timer
|
1
2
3
4
5
6
7
8
9
|
[Unit]
Description=Run Log Alert every 5 minutes
[Timer]
OnBootSec=5min
OnUnitActiveSec=5min
[Install]
WantedBy=timers.target
|
1
2
3
|
# タイマーを有効化
sudo systemctl daemon-reload
sudo systemctl enable --now log-alert.timer
|
まとめ#
この記事では、Linuxログ管理とトラブルシューティングについて以下の内容を解説しました。
/var/logディレクトリの構造と主要ログファイルの役割
- journalctlによる高度なフィルタリングと分析手法
- rsyslogの設定とカスタムログの作成
- logrotateによるログローテーションの設定
- 実際の障害調査における具体的なアプローチ
ログはシステムの「声」です。適切に収集・分析することで、問題の早期発見と迅速な解決が可能になります。日頃からログを確認する習慣をつけ、異常を検知できるようにしておきましょう。
参考リンク#