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ディレクトリに格納されます。主要なログファイルの役割を理解しておきましょう。

主要なログファイル一覧

1
ls -la /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によるログローテーションの設定
  • 実際の障害調査における具体的なアプローチ

ログはシステムの「声」です。適切に収集・分析することで、問題の早期発見と迅速な解決が可能になります。日頃からログを確認する習慣をつけ、異常を検知できるようにしておきましょう。

参考リンク