手順

Linux のログ:journalctl、/var/log、rsyslog、logrotate

更新日: · Skillaria.Top

最近の Linux ディストリビューションでは、journald がログを集め、journalctl で読みます。journalctl -u nginx は1つのサービスのログを表示し、-f はリアルタイムの流れを表示し、--since と -p で時刻と重要度を絞り込めます。テキストのログは /var/log に保存され、rsyslog が書き込むか、アプリケーションが直接書きます。logrotate は古いファイルを圧縮・削除し、ディスクが満杯になるのを防ぎます。

サービスが夜中に停止したとき、原因は多くの場合ログに残っています。問題はどこを見るかです。Ubuntu、Debian、RHEL、Fedora、Arch などの最近のディストリビューションでは、journald がイベントを集め、journalctl で読みます。同時に多くのプログラムが /var/log に通常のテキストファイルを書き、そのサイズは logrotate が管理します。ここでは、journalctl と Linux のログの実践的な使い方、ほかのログの場所、ローテーション中に重要な情報を失わない方法を説明します。

Linux のログの保存場所

ログの保存先は3つあります。全体像として覚えておくと便利です。

  • journald:systemd のバイナリ形式のジャーナル。すべてのサービスの stdout と stderr、カーネルのメッセージ、syslog を受け取ります。/var/log/journal/(永続)または /run/log/journal/(再起動まで)に保存されます。
  • /var/log:テキストファイル。rsyslog(例:/var/log/syslog、/var/log/auth.log)またはアプリケーション自身(nginx、PostgreSQL、MySQL など)が書きます。
  • カーネルのリングバッファ:ドライバーとハードウェアのメッセージ。dmesg や journalctl -k で表示します。
ファイル内容
/var/log/syslog(Debian/Ubuntu)システム全体のログ
/var/log/messages(RHEL/Fedora)Red Hat 系での同じ役割
/var/log/auth.log または /var/log/secureログイン、sudo、SSH
/var/log/kern.logカーネルのメッセージ
/var/log/dpkg.log、/var/log/apt/パッケージのインストール
/var/log/nginx/Web サーバーの access.log と error.log
/var/log/wtmp、/var/log/btmpログインのバイナリ記録。last と lastb で読む

/var/log の多くのファイルは root またはグループ adm だけが読めるので、読み取りコマンドは sudo 付きで実行することがよくあります。

journalctl の基本コマンド

引数なしの journalctl は、最も古いエントリから順に、ページャー less でジャーナル全体を表示します。通常はそこまで必要ありません。たいてい表示範囲を絞ります。

journalctl              # ジャーナル全体。古いものから新しいものへ
journalctl -e           # 末尾を表示した状態で開く
journalctl -n 50        # 最後の 50 行
journalctl -r           # 逆順。新しいものが上
journalctl --no-pager   # less を使わない。スクリプトや grep に便利

ページャーの中では、less の操作が使えます。/ は検索、G は末尾、q は終了です。長い行は画面の幅で切られ、左右の矢印キーで横にスクロールできます。

サービス単位のログ:journalctl -u

最もよくある用途は、1つの systemd ユニットが書いた内容を見ることです。ファイルを探してgrepする必要はありません。

$ sudo journalctl -u nginx -n 20
Oct 14 03:12:41 web1 systemd[1]: Starting nginx.service - A high performance web server...
Oct 14 03:12:41 web1 nginx[1834]: nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
Oct 14 03:12:41 web1 systemd[1]: nginx.service: Control process exited, code=exited, status=1/FAILURE
Oct 14 03:12:41 web1 systemd[1]: nginx.service: Failed with result 'exit-code'.

-u は繰り返し指定できます。journalctl -u nginx -u php8.2-fpm は、2つのサービスのログを時刻順に混ぜて表示します。エラーが2つのサービスの境界で発生する場合に便利です。ユーザーのユニット(systemctl --user)には journalctl --user -u 名前 を使います。

リアルタイムのログ:journalctl -f

sudo journalctl -u nginx -f

tail -f に相当します。最後の 10 件を表示して、新しいエントリを待ちます。サービスを再起動したり、エラーを再現したりする間、別のターミナルで開いておくと便利です。終了は Ctrl+C です。

時刻とブートによる絞り込み

障害の時刻が分かっている場合は、--since と --until で範囲を指定します。正確な日時も、相対的な指定も使えます。

journalctl --since "2026-10-14 02:50" --until "2026-10-14 03:30"
journalctl --since "1 hour ago"
journalctl --since yesterday --until today
journalctl -u nginx --since "10 min ago"

もう1つ便利な絞り込みは、システムの起動単位です。サーバーが自分で再起動した場合、原因は前のセッションの末尾にあります。

$ journalctl --list-boots
 -2 8f1c...  Sat 2026-10-12 09:01:12 UTC  Sun 2026-10-13 22:47:03 UTC
 -1 a7d2...  Sun 2026-10-13 22:48:30 UTC  Tue 2026-10-14 03:05:51 UTC
  0 c3e9...  Tue 2026-10-14 03:07:02 UTC  Tue 2026-10-14 09:15:40 UTC

$ journalctl -b -1 -e      # 1 つ前の起動の末尾
$ journalctl -b            # 現在の起動のみ

起動の一覧は、ジャーナルがディスクに保存されている場合にだけ使えます。その設定方法は後半の journald の項で説明します。

重要度による絞り込み:journalctl -p

各エントリには 0 から 7 までの syslog の優先度があります。-p は指定したレベル以上の重要なエントリを表示します。

コード名前使われる場面
0emergシステムが使用不能
1alert直ちに対応が必要
2crit致命的なエラー
3errエラー
4warning警告
5notice正常だが注目すべきイベント
6info情報メッセージ
7debugデバッグ
journalctl -p err -b              # 起動後のすべてのエラー
journalctl -p warning..err -u ssh # 1 つのサービスの重要度の範囲

journalctl -p err -b は、再起動やアップデートの後に最初に実行すると良い確認です。何が問題だったのかを数秒で把握できます。

検索とその他のフィルター

journald は各エントリに構造化されたフィールドを保存しているので、grep を使わずにフィルターできます。

journalctl _PID=1834                 # プロセス番号で
journalctl _COMM=sshd                # プログラム名で
journalctl _UID=1000                 # ユーザー ID で
journalctl /usr/sbin/sshd            # 実行ファイルのパスで
journalctl -k                        # カーネルのメッセージのみ(dmesg と同様)
journalctl -t CRON                   # syslog の識別子で
journalctl -g "Out of memory"        # テキスト検索。正規表現が使える

-g(--grep)は systemd 237 以降で使えます。古いシステムでは、通常のパイプライン journalctl --no-pager | grep ... を使ってください。異なるフィールドのフィルターは「AND」で結ばれるので、journalctl -u nginx -p err --since today は今日の nginx のエラーだけを表示します。

出力形式

-o オプションで形式を変えられます。よく使われるものは次のとおりです。

  • -o short-iso:時刻を ISO 8601 形式で表示。アプリケーションのログと比べやすくなります。
  • -o verbose:_SYSTEMD_UNIT、_PID、_BOOT_ID など、すべてのフィールドを表示。
  • -o json または json-pretty:スクリプトや jq での処理向け。
  • -o cat:日時やホスト名を含まず、メッセージの本文だけを表示。
journalctl -u myapp -o json --since today | jq -r '.MESSAGE'

journald の設定:保存と容量

設定は /etc/systemd/journald.conf にあります。変更は /etc/systemd/journald.conf.d/*.conf に書くと管理しやすくなります。最も重要なパラメータは Storage です。

  • persistent:ジャーナルを /var/log/journal にディスク保存し、再起動後も残す。
  • volatile:メモリ上だけ(/run/log/journal)。
  • auto(既定):/var/log/journal ディレクトリが存在すればディスクに保存。

一部の最小構成のイメージにはそのディレクトリがなく、再起動すると履歴が消えます。永続保存を有効にするには、次のようにします。

sudo mkdir -p /var/log/journal
sudo systemd-tmpfiles --create --prefix /var/log/journal
sudo systemctl restart systemd-journald

ジャーナルがディスク全体を占有しないように、上限を設定します。

# /etc/systemd/journald.conf.d/size.conf
[Journal]
Storage=persistent
SystemMaxUse=500M
MaxRetentionSec=1month

既定の SystemMaxUse は、ファイルシステムのサイズの 10% ですが、4 GB を超えることはありません。

journalctl のログを削除する

$ journalctl --disk-usage
Archived and active journals take up 1.8G in the file system.

sudo journalctl --vacuum-size=300M   # 300 MB 以内に保つ
sudo journalctl --vacuum-time=2weeks # 2 週間より古いエントリを削除
sudo journalctl --rotate             # 現在のファイルを閉じ、削除できるようにする

/var/log/journal のファイルを rm で削除するのは避けてください。vacuum は同じことを安全に行い、使用中のファイルには触れません。

rsyslog:従来のテキストログ

rsyslog は、syslog のメッセージ(journald から転送されたものを含む)を受け取り、ルールに従ってファイルに振り分けるデーモンです。設定は /etc/rsyslog.conf と /etc/rsyslog.d/*.conf にあります。ルールは「ファシリティ.優先度」のセレクターと、アクションで構成されます。

# /etc/rsyslog.d/50-default.conf(抜粋)
auth,authpriv.*        /var/log/auth.log
*.*;auth,authpriv.none -/var/log/syslog
kern.*                 -/var/log/kern.log

パスの前のマイナス記号は、行ごとにディスクへ同期しないことを意味します。速くなりますが、障害時には最後の数行が失われることがあります。設定を変更したら、構文を確認してサービスを再起動します。

sudo rsyslogd -N1
sudo systemctl restart rsyslog

rsyslog を journald と並べて使う主な理由は、ログを中央サーバーに転送することです。TCP で送るには1行で足ります。

# /etc/rsyslog.d/90-remote.conf
*.* @@logs.example.com:514

@ を1つ書くと UDP、2つ書くと TCP になります。サーバーが完全に故障しても、ログのコピーは別のマシンに残ります。スクリプトから独自のメッセージをシステムログに書くには logger を使います。

logger -t backup -p user.err "データベースのバックアップに失敗しました"
journalctl -t backup -n 5

logrotate:ログのローテーション

テキストログは、誰かが切り詰めない限り無限に大きくなります。その役目を担うのが logrotate です。1日に1回(cron または logrotate.timer で)現在のファイルの名前を変え、古いファイルを圧縮し、最も古いものを削除します。全体の設定は /etc/logrotate.conf、アプリケーションごとのルールは /etc/logrotate.d/ にあります。

# /etc/logrotate.d/myapp
/var/log/myapp/*.log {
    daily
    rotate 14
    compress
    delaycompress
    missingok
    notifempty
    create 0640 myapp adm
    postrotate
        systemctl reload myapp > /dev/null 2>&1 || true
    endscript
}
ディレクティブ意味
daily / weekly / size 100Mローテーションのタイミング
rotate 14保存する古いファイルの数
compress、delaycompressgzip で圧縮する。ただし最新のアーカイブは圧縮しない
missingok、notifemptyファイルがなくてもエラーにしない。空のファイルはローテーションしない
create 0640 user group新しいファイルを作るときの権限
copytruncateコピーしてから中身を空にする。ログを開き直せないプログラム向け
postrotate ... endscriptローテーション後に実行するコマンド。通常はアプリケーションにファイルを開き直させるシグナルを送る

ルールを変更せずに確認し、ローテーションを強制的に実行するには次のコマンドを使います。

sudo logrotate -d /etc/logrotate.d/myapp   # デバッグ情報付きの試行実行
sudo logrotate -f /etc/logrotate.d/myapp   # 今すぐローテーション

よくあるミスは、postrotate や copytruncate を書き忘れることです。すると、アプリケーションは古いディスクリプタで名前を変えた app.log.1 に書き続け、新しい app.log は空のままになります。

テキストログの読み方

/var/log のファイルには、標準的なツールで十分です。

sudo tail -n 100 /var/log/syslog          # 最後の行
sudo tail -F /var/log/nginx/error.log     # ローテーションを越えて追跡
sudo less +G /var/log/auth.log            # 末尾を表示した状態で開く
sudo zgrep "Failed password" /var/log/auth.log.*.gz   # 圧縮アーカイブを検索
sudo grep -c " 500 " /var/log/nginx/access.log        # 500 応答の数

大文字の tail -F に注意してください。-f と違い、logrotate がファイルを差し替えたときに、ファイルを開き直します。

障害調査の手順:夜中にサービスが止まった場合

「夜中にサービスが停止した」という事例は、次の順序で調べると効率的です。

  1. systemctl status myapp:現在の状態と、ジャーナルの最後の数行。
  2. journalctl -u myapp --since "03:00" --until "03:30":停止の時点でサービスが何を書いたか。
  3. journalctl -p err -b:同じ時間帯にシステム上の別のエラーがなかったか。
  4. journalctl -k --since "03:00" -g "Out of memory|Killed process":カーネルの OOM Killer がプロセスを終了させていないか。
  5. /var/log/myapp/ にあるアプリケーション自身のログ。圧縮された .gz のアーカイブも含む。
  6. サーバーが再起動していた場合は、journalctl -b -1 -e。

まとめ

日常のログ確認には、いくつかのコマンドで十分です。サービスには journalctl -u、流れを見るには -f、範囲を絞るには --since と -p err、再起動の調査には -b -1 を使います。テキストのログは /var/log にあり、rsyslog が振り分けと転送を行います。logrotate と journalctl --vacuum-* を使うと、ログがディスクを使い尽くすことを防げます。journalctl、ローテーション、負荷の診断は、Linux コースの講義で実践しながら解説しています。

よくある質問

journalctl が現在の起動以降の記録しか表示しないのはなぜですか?

ジャーナルがメモリ上(/run/log/journal)に保存されているためです。/var/log/journal ディレクトリを作成するか、journald.conf で Storage=persistent を設定し、systemd-journald を再起動してください。

通常のユーザーが sudo なしでシステムのジャーナルを読めるようにするには?

そのユーザーを systemd-journal グループ(Debian と Ubuntu では adm)に追加します。sudo usermod -aG systemd-journal 名前 を実行し、ログインし直してください。

別のディスクにあるシステムのジャーナルを見ることはできますか?

はい。-D オプションでジャーナルのディレクトリを指定します。例:journalctl -D /mnt/var/log/journal。--file オプションを使うと、個別の .journal ファイルを読めます。

journald があれば rsyslog は必要ですか?

必須ではありません。古いツール向けにテキストファイルが必要な場合や、ログを中央サーバーに転送する場合に役立ちます。多くの最小構成のイメージではインストールされていません。

サービスのログをファイルに書き出して同僚に送るには?

journalctl -u 名前 --since today --no-pager > service.log を実行します。できあがるのは普通のテキストファイルです。

動画でこのテーマを学ぶ

このテーマはコース「Linux: с нуля до уверенного администрирования」で実践とともに詳しく解説しています。

コースへ