はじめに:ログ分析がシステム管理者の核心スキルである理由

Linuxサーバーを運用していると、障害が発生した際にまず確認するのがログ(Log)です。ログはシステムが残す一種の「ブラックボックス」であり、何がいつどのように発生したかを記録しています。セキュリティインシデントの原因追跡にも、サービス障害のデバッグにも、パフォーマンスのボトルネック特定にも、ログが出発点となります。

しかし実際の運用環境では、ログファイルは数GBから数十GBに及ぶことがあり、1日に数百万行が蓄積されることも珍しくありません。この膨大なデータから必要な情報を素早く正確に抽出する能力こそ、システム管理者やDevOpsエンジニアの核心的なスキルです。

このガイドでは、Linuxログ分析に必要なすべての基本コマンドを体系的に解説します。基本コマンドから高度なワンライナーまで、実務ですぐコピーして使える実践的な例を中心に構成しました。初心者から中級以上の実務者まで、すべての方が活用できるよう段階的に説明します。

1. Linuxログシステムの構造と重要ファイル

1.1 ログシステムのアーキテクチャ

Linuxのログシステムは大きく2つの体系に分けられます:

  • 従来のsyslog系:rsyslog、syslog-ngなどがテキストファイルとしてログを記録します。/var/log/ディレクトリ配下に保存されます。
  • systemd-journald:systemdベースのシステムでバイナリ形式でログを管理します。journalctlコマンドで照会します。

最近のほとんどのディストリビューション(RHEL 8+、Ubuntu 20.04+、Debian 11+)は両方のシステムを併用しています。journaldが一次的に収集し、rsyslogがそれをテキストファイルとしても保存する構造です。

1.2 必ず知っておくべき重要ログファイル

ログファイル 内容 主な用途
/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/cron cronジョブの実行記録 スケジュールタスクのデバッグ
/var/log/maillog メールサーバーログ メール送受信の追跡
/var/log/nginx/ Nginxアクセス・エラーログ Webトラフィック分析
/var/log/apache2/ Apacheアクセス・エラーログ Webトラフィック分析
/var/log/mysql/ MySQL/MariaDBログ DBクエリ、エラー分析
/var/log/audit/audit.log SELinux/AppArmor監査ログ セキュリティ監査、ポリシー違反
/var/log/boot.log サービス起動ログ サービス起動失敗の分析
/var/log/lastlog 最終ログイン記録(バイナリ) lastlogコマンドで照会
/var/log/wtmp ログイン・ログアウト履歴(バイナリ) lastコマンドで照会
/var/log/btmp 失敗したログイン試行(バイナリ) lastbコマンドで照会
TIP: ログファイルの場所はディストリビューションによって異なる場合があります。ls -la /var/log/でまずどのログファイルが存在するか確認する習慣をつけましょう。

1.3 ログローテーションの理解

ログファイルはlogrotateによって定期的にローテーション(rotation)されます。古いログは.1.2または.gz拡張子で保管されます:

# ログローテーションの例
/var/log/syslog          # 現在のログ
/var/log/syslog.1        # 前回のログ(非圧縮)
/var/log/syslog.2.gz     # その前のログ(圧縮)
/var/log/syslog.3.gz     # さらに前のログ(圧縮)

# 圧縮されたログファイルの検索にはzgrep、zcatを使用
zgrep "error" /var/log/syslog.2.gz
zcat /var/log/syslog.3.gz | grep "kernel"

# logrotateの設定確認
cat /etc/logrotate.conf
ls /etc/logrotate.d/

2. 基本ログ照会コマンド

2.1 tail - リアルタイムログ監視の第一歩

tailはログ分析の最も基本的かつ最も多く使用されるコマンドです。特に-fオプションはリアルタイム監視の核心です。

# 最後の10行を表示(デフォルト)
tail /var/log/syslog

# 最後の50行を表示
tail -n 50 /var/log/syslog
tail -50 /var/log/syslog          # 省略形

# リアルタイムログ監視(follow)
tail -f /var/log/syslog

# リアルタイム + 直近100行から表示
tail -n 100 -f /var/log/syslog
tail -100f /var/log/syslog        # 省略形

# 複数ファイルの同時監視
tail -f /var/log/syslog /var/log/auth.log

# ファイルがローテーションされても追跡を継続
tail -F /var/log/syslog            # 大文字-F:ファイル再オープン

# 特定キーワードのリアルタイムフィルタリング
tail -f /var/log/syslog | grep --line-buffered "error"
tail -f /var/log/syslog | grep --line-buffered -i "fail\|error\|warn"
注意: tail -fgrepをパイプで接続する際は、必ず--line-bufferedオプションを使用してください。そうしないとバッファリングにより出力が遅延する可能性があります。

2.2 head - ファイルの先頭を確認

# 先頭10行を表示(デフォルト)
head /var/log/syslog

# 先頭30行を表示
head -n 30 /var/log/syslog

# 最後の10行を除いた全体
head -n -10 /var/log/syslog

2.3 cat、less、more - ファイル全体の照会

# ファイル全体を出力(小さいファイルのみ適切)
cat /var/log/cron

# 行番号付きで出力
cat -n /var/log/cron

# ページ単位で閲覧(最も推奨)
less /var/log/syslog
# less内部のショートカット:
#   / : 前方検索
#   ? : 後方検索
#   n : 次の検索結果
#   N : 前の検索結果
#   G : ファイル末尾へ移動
#   g : ファイル先頭へ移動
#   q : 終了

# lessでリアルタイム監視(tail -fと同様)
less +F /var/log/syslog
# Ctrl+Cで閲覧モード切替、Shift+Fで再追跡モード
TIP: 大容量のログファイルにはcatの代わりに必ずlessを使用してください。catはファイル全体をメモリにロードするため、数GBのファイルではシステムに負荷をかける可能性があります。

2.4 wc - ログ統計の素早い確認

# 総行数の確認
wc -l /var/log/syslog

# 今日のエラーが何件か素早く把握
grep -c "error" /var/log/syslog
grep -ci "error\|fail\|critical" /var/log/syslog

# 複数ログファイルの行数比較
wc -l /var/log/syslog /var/log/auth.log /var/log/kern.log

3. grep - ログ検索の最強ツール

grepはログ分析で最も重要なコマンドと言っても過言ではありません。文字列パターンマッチングにより、膨大なログから必要な情報だけを素早く抽出します。

3.1 基本検索

# 特定の文字列を検索
grep "error" /var/log/syslog

# 大文字小文字を無視して検索
grep -i "error" /var/log/syslog

# 行番号を表示
grep -n "error" /var/log/syslog

# マッチした件数のみ表示
grep -c "error" /var/log/syslog

# 該当文字列を含まない行のみ表示(逆マッチ)
grep -v "info" /var/log/syslog

# 完全な単語マッチ(errorはマッチ、errorlogはマッチしない)
grep -w "error" /var/log/syslog

3.2 正規表現を活用した高度な検索

# 拡張正規表現の使用(-Eまたはegrep)
grep -E "error|fail|critical" /var/log/syslog

# IPアドレスパターン検索
grep -E "\b([0-9]{1,3}\.){3}[0-9]{1,3}\b" /var/log/auth.log

# 特定時間帯のログフィルタリング(例:午前3時台)
grep "^Mar  7 03:" /var/log/syslog

# 日付 + 時間範囲(2時〜5時)
grep -E "^Mar  7 0[2-5]:" /var/log/syslog

# SSH失敗ログイン抽出
grep "Failed password" /var/log/auth.log

# 特定ユーザーのsudoコマンド追跡
grep "sudo.*username" /var/log/auth.log

3.3 コンテキスト検索 - エラー前後の状況把握

# マッチした行の後5行を表示(After)
grep -A 5 "kernel panic" /var/log/kern.log

# マッチした行の前3行を表示(Before)
grep -B 3 "OOM" /var/log/syslog

# 前後各5行ずつ表示(Context)
grep -C 5 "segfault" /var/log/syslog

# 複合条件:errorかつnginx関連
grep "error" /var/log/syslog | grep "nginx"

# 複数ファイルで同時検索
grep -r "connection refused" /var/log/
grep -rl "connection refused" /var/log/    # ファイル名のみ出力

3.4 圧縮ログでの検索

# gz圧縮ファイルで直接検索
zgrep "error" /var/log/syslog.2.gz

# 圧縮ファイルの内容確認
zcat /var/log/syslog.2.gz | less

# 現在 + 過去のログをすべて検索
zgrep "error" /var/log/syslog /var/log/syslog.1 /var/log/syslog.*.gz

4. awk - ログデータ抽出と加工の達人

awkはテキストをフィールド単位で分離・加工するのに最適化されたツールです。ログの特定カラムだけを抽出したり、条件別に集計する際に非常に強力です。

4.1 基本フィールド抽出

# syslog形式:日付 ホスト プロセス: メッセージ
# $1=月, $2=日, $3=時刻, $4=ホスト, $5=プロセス

# 時刻とメッセージのみ抽出
awk '{print $3, $5, $0}' /var/log/syslog | tail -20

# 特定フィールドのみ出力(Nginx access logの例)
# 形式:IP - - [日付] "リクエスト" ステータスコード サイズ "リファラー" "UA"
awk '{print $1, $9}' /var/log/nginx/access.log    # IPとステータスコード

# タブ区切りファイルの処理
awk -F'\t' '{print $1, $3}' logfile.tsv

# カンマ区切り(CSV)
awk -F',' '{print $1, $NF}' logfile.csv    # 最初と最後のフィールド

4.2 条件付きフィルタリング

# HTTP 500エラーのみ抽出(Nginx/Apache)
awk '$9 == 500' /var/log/nginx/access.log

# 500番台エラーすべて
awk '$9 >= 500 && $9 < 600' /var/log/nginx/access.log

# レスポンスサイズ1MB以上のみ
awk '$10 > 1048576' /var/log/nginx/access.log

# 特定IPのリクエストのみ
awk '$1 == "192.168.1.100"' /var/log/nginx/access.log

# 特定の文字列を含む行(grepと同様)
awk '/error/' /var/log/syslog
awk '/error/ && /nginx/' /var/log/syslog    # AND条件
awk '/error/ || /warn/' /var/log/syslog     # OR条件

4.3 集計と統計

# IP別リクエスト回数集計(アクセス数トップIP)
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20

# awkのみでIPカウント
awk '{ip[$1]++} END {for (i in ip) print ip[i], i}' /var/log/nginx/access.log | sort -rn | head -20

# ステータスコード別件数
awk '{code[$9]++} END {for (c in code) print c, code[c]}' /var/log/nginx/access.log | sort -k2 -rn

# 時間帯別リクエスト件数(時間単位)
awk '{split($4, a, ":"); hour=a[2]; h[hour]++} END {for (i in h) print i, h[i]}' /var/log/nginx/access.log | sort

# 総転送バイト合算
awk '{sum += $10} END {printf "Total: %.2f GB\n", sum/1024/1024/1024}' /var/log/nginx/access.log

# URLパス別リクエスト数(GET/POST区別なし)
awk '{print $7}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -30

4.4 実践ワンライナー

# 遅いリクエストの検出(レスポンスタイム込みのログ形式を想定)
# log_formatに$request_timeが最後のフィールドの場合:
awk '{if ($NF > 3.0) print $0}' /var/log/nginx/access.log

# 分あたりのリクエスト数計算
awk '{split($4,a,"[:/]"); min=a[2]":"a[3]":"a[4]" "a[5]":"a[6]; m[min]++} END {for (i in m) print i, m[i]}' /var/log/nginx/access.log | sort | tail -20

# エラー率計算
awk '{total++; if ($9 >= 400) errors++} END {printf "Total: %d, Errors: %d, Rate: %.2f%%\n", total, errors, (errors/total)*100}' /var/log/nginx/access.log

5. sed - ログテキストの変換と抽出

sedはストリームエディタで、ログデータの変換や特定範囲の抽出に便利です。

5.1 基本的なパターン置換と抽出

# 特定の文字列を置換(出力用)
sed 's/error/ERROR/gi' /var/log/syslog | head

# 特定範囲の行のみ出力
sed -n '100,200p' /var/log/syslog          # 100〜200行目

# 特定パターン間の内容のみ抽出
sed -n '/Start of backup/,/End of backup/p' /var/log/syslog

# 特定時間範囲の抽出
sed -n '/Mar  7 14:00/,/Mar  7 15:00/p' /var/log/syslog

# 空行の削除
sed '/^$/d' /var/log/application.log

# コメント(#)行の削除
sed '/^#/d' /etc/rsyslog.conf

# IPアドレスのマスキング(セキュリティレポート用)
sed -E 's/([0-9]+\.[0-9]+\.[0-9]+\.)[0-9]+/\1***/g' /var/log/auth.log

5.2 複数コマンドと高度な活用

# 複数の置換を一度に
sed -e 's/error/ERROR/gi' -e 's/warning/WARNING/gi' /var/log/syslog

# 特定行の削除(1〜5行目を除いて出力)
sed '1,5d' /var/log/syslog

# 日付形式の変換例
echo "2026/03/07 14:30:00" | sed 's|\([0-9]*\)/\([0-9]*\)/\([0-9]*\)|\1-\2-\3|'

# 特定パターンを含む行のみ出力(grepと同様)
sed -n '/OOM/p' /var/log/syslog

6. sort、uniq、cut - ログデータの並び替えと集計

この3つのコマンドは単体でも有用ですが、パイプラインで組み合わせたときに真の威力を発揮します。

6.1 sort - 並び替え

# 基本的な並び替え(アルファベット順)
sort /var/log/auth.log

# 逆順並び替え
sort -r /var/log/auth.log

# 数値基準の並び替え
sort -n data.log

# 特定フィールド基準の並び替え(3番目のフィールド、数値逆順)
sort -t' ' -k3 -rn access.log

# 日付基準の並び替え
sort -k1,1M -k2,2n /var/log/syslog    # 月(Month)+ 日(数値)

6.2 uniq - 重複排除とカウント

# 重複排除(必ずsortと組み合わせて!)
sort /var/log/auth.log | uniq

# 重複件数を表示
sort /var/log/auth.log | uniq -c

# 重複件数で再並び替え(頻度順)
sort /var/log/auth.log | uniq -c | sort -rn

# 重複している行のみ表示
sort /var/log/auth.log | uniq -d

# ユニークな行のみ表示(1回だけ出現)
sort /var/log/auth.log | uniq -u
注意: uniq連続した重複のみを排除します。必ずsortを先に実行してからuniqを使用しないと、正しい結果が得られません。

6.3 cut - フィールドの切り出し

# 特定の区切り文字でフィールド抽出
cut -d' ' -f1 /var/log/nginx/access.log        # IPのみ抽出
cut -d':' -f1 /etc/passwd                       # ユーザー名のみ

# 文字位置基準の抽出
cut -c1-15 /var/log/syslog                      # 先頭15文字(日付時刻)

# 複数フィールドの同時抽出
cut -d' ' -f1,4,7 /var/log/nginx/access.log    # 1、4、7番目のフィールド

6.4 パイプライン組み合わせの実践例

# SSHログイン失敗IPトップ10
grep "Failed password" /var/log/auth.log | awk '{print $(NF-3)}' | sort | uniq -c | sort -rn | head -10

# 時間帯別エラー件数
grep -i "error" /var/log/syslog | awk '{print $3}' | cut -d: -f1 | sort | uniq -c | sort -rn

# Nginxリクエスト URLトップ20
awk '{print $7}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20

# アクセスしたユニークIP数
awk '{print $1}' /var/log/nginx/access.log | sort -u | wc -l

# 日付別ログ行数の推移
awk '{print $1, $2}' /var/log/syslog | sort | uniq -c

7. journalctl - systemdログ分析のすべて

systemdベースのシステムにおいてjournalctlは最も強力なログ照会ツールです。バイナリジャーナルを構造化された形式で照会し、さまざまなフィルタリングを標準でサポートしています。

7.1 基本照会

# 全ジャーナルの表示
journalctl

# 最新ログから逆順で表示
journalctl -r

# 最新50行のみ表示
journalctl -n 50

# リアルタイム監視(tail -fと同じ)
journalctl -f

# 特定の起動セッションのログ
journalctl -b              # 現在の起動
journalctl -b -1           # 前回の起動
journalctl --list-boots    # 起動履歴一覧

# ページャーなしで出力(スクリプト用)
journalctl --no-pager

7.2 時間ベースのフィルタリング

# 特定日付以降
journalctl --since "2026-03-07"

# 特定時間範囲
journalctl --since "2026-03-07 14:00" --until "2026-03-07 16:00"

# 相対時間
journalctl --since "1 hour ago"
journalctl --since "30 min ago"
journalctl --since "2 days ago"
journalctl --since yesterday
journalctl --since today

7.3 サービス/ユニットベースのフィルタリング

# 特定サービスのログのみ表示
journalctl -u nginx.service
journalctl -u sshd.service
journalctl -u mysql.service

# 複数サービスの同時照会
journalctl -u nginx.service -u php-fpm.service

# 特定サービスのリアルタイム監視
journalctl -u nginx.service -f

# 特定サービスの最近のエラーのみ
journalctl -u nginx.service -p err -n 50

7.4 プライオリティ(深刻度)フィルタリング

# 深刻度レベル別フィルタリング
# 0=emerg, 1=alert, 2=crit, 3=err, 4=warning, 5=notice, 6=info, 7=debug

journalctl -p emerg          # 緊急(システム使用不可)
journalctl -p alert          # 即時対処が必要
journalctl -p crit           # 致命的な状態
journalctl -p err            # エラー(最もよく使用)
journalctl -p warning        # 警告

# 範囲指定(crit以上の深刻なログのみ)
journalctl -p crit..emerg

# サービス + 深刻度 + 時間の組み合わせ
journalctl -u sshd.service -p err --since "1 hour ago"

7.5 出力形式の制御

# JSON形式出力(パース処理に便利)
journalctl -u nginx.service -o json-pretty -n 5

# 簡潔な1行形式
journalctl -o short-precise

# 使用可能な出力形式
# short         : デフォルトのsyslogスタイル
# short-precise : マイクロ秒単位の時刻
# short-iso     : ISO 8601形式の時刻
# verbose       : 全フィールド表示
# json          : JSON形式(1行)
# json-pretty   : JSON形式(インデント付き)
# cat           : メッセージのみ(タイムスタンプなし)

# 特定フィールドベースのフィルタリング
journalctl _COMM=sshd               # プロセス名
journalctl _PID=1234                 # PID
journalctl _UID=0                    # rootユーザー
journalctl _HOSTNAME=webserver01     # ホスト名

7.6 カーネルログとディスク使用量

# カーネルメッセージのみ(dmesgと同様)
journalctl -k
journalctl --dmesg

# ジャーナルのディスク使用量確認
journalctl --disk-usage

# ジャーナルのクリーンアップ(古いログの削除)
sudo journalctl --vacuum-time=7d     # 7日以上経過したログを削除
sudo journalctl --vacuum-size=500M   # 500MB超過分を削除

8. 実践シナリオ別ログ分析

8.1 SSHブルートフォース攻撃分析

# 失敗したSSHログイン試行の確認
grep "Failed password" /var/log/auth.log | tail -20

# 攻撃IPの抽出と頻度順の並び替え
grep "Failed password" /var/log/auth.log | \
  awk '{print $(NF-3)}' | sort | uniq -c | sort -rn | head -20

# 特定IPの試行時間帯分析
grep "Failed password" /var/log/auth.log | \
  grep "192.168.1.100" | awk '{print $1, $2, $3}'

# 成功したログインの確認
grep "Accepted" /var/log/auth.log | tail -20

# 存在しないユーザー名での攻撃試行
grep "Invalid user" /var/log/auth.log | \
  awk '{print $8}' | sort | uniq -c | sort -rn | head -20

# 時間帯別攻撃頻度(時間単位)
grep "Failed password" /var/log/auth.log | \
  awk '{print $3}' | cut -d: -f1 | sort | uniq -c | sort -rn

# journalctlでSSH分析
journalctl -u sshd.service -p warning --since "24 hours ago" --no-pager

8.2 Webサーバー障害分析(Nginx/Apache)

# 500エラー発生時点の把握
grep '" 500 ' /var/log/nginx/access.log | tail -30

# 5xxエラー率の計算
awk '{total++; if ($9 ~ /^5/) err++} END {printf "Total: %d, 5xx: %d (%.2f%%)\n", total, err, err/total*100}' \
  /var/log/nginx/access.log

# エラー発生URLパターン分析
grep '" 500 ' /var/log/nginx/access.log | \
  awk '{print $7}' | sort | uniq -c | sort -rn | head -20

# Nginxエラーログ分析
grep "error" /var/log/nginx/error.log | tail -30

# upstreamタイムアウト確認
grep "upstream timed out" /var/log/nginx/error.log | wc -l

# 秒あたりのリクエスト数(RPS)計算
awk '{split($4,a,"[:/]"); sec=a[4]" "a[5]":"a[6]":"a[7]; s[sec]++} END {for (i in s) print i, s[i]}' \
  /var/log/nginx/access.log | sort | tail -20

# 特定時間帯の遅いリクエスト(request_timeが最後のフィールド)
awk '$NF > 5.0 {print $4, $7, $NF}' /var/log/nginx/access.log | tail -20

8.3 ディスクI/OおよびOOM(Out of Memory)分析

# OOM Killerがプロセスを終了した履歴確認
grep -i "oom" /var/log/syslog
grep "Out of memory" /var/log/syslog
dmesg | grep -i "oom"

# OOMで終了されたプロセスのリスト
grep "Killed process" /var/log/syslog | \
  awk -F'[()]' '{print $2}' | sort | uniq -c | sort -rn

# journalctlでOOM確認
journalctl -k | grep -i "oom"
journalctl -k | grep "Out of memory"

# ディスク関連エラー
grep -i "I/O error" /var/log/syslog
grep -i "ext4.*error" /var/log/syslog
dmesg | grep -i "error"

# ファイルシステムの読み取り専用への切り替え検知
grep "Remounting filesystem read-only" /var/log/syslog

8.4 サービスの起動/停止/クラッシュ追跡

# サービスの起動/停止履歴
journalctl -u nginx.service | grep -i "started\|stopped\|failed"

# サービス障害の原因分析
systemctl status nginx.service
journalctl -u nginx.service --since "10 min ago" -p err

# サービス再起動頻度の分析
journalctl -u mysql.service | grep -c "Started"

# コアダンプの確認
journalctl | grep "core dump"
coredumpctl list                    # systemd-coredump使用時

# 起動失敗サービスの一覧
systemctl --failed

8.5 cronジョブのデバッグ

# cron実行履歴の確認
grep CRON /var/log/syslog
grep CRON /var/log/cron                  # RHEL/CentOS

# 特定ユーザーのcron実行確認
grep "CRON.*username" /var/log/syslog

# cronエラーのみ確認
grep CRON /var/log/syslog | grep -i "error\|fail"

# journalctlでcron確認
journalctl -u cron.service --since today

# 特定スクリプトのcron実行確認
grep "backup.sh" /var/log/syslog

9. 高度な分析テクニックとワンライナー集

9.1 xargsとfindを活用した複数ファイル分析

# 最近24時間以内に更新されたログファイルでerrorを検索
find /var/log -name "*.log" -mtime -1 -exec grep -l "error" {} \;

# すべてのログファイルで特定IPを検索
find /var/log -type f -name "*.log" | xargs grep -l "192.168.1.100" 2>/dev/null

# 特定サイズ以上のログファイルを検索
find /var/log -type f -size +100M -exec ls -lh {} \;

# 古いログファイルの整理(30日以上)
find /var/log -name "*.gz" -mtime +30 -exec ls -la {} \;

9.2 while readループによる行単位処理

# 失敗IPを1つずつ処理(例:ブロックリスト作成)
grep "Failed password" /var/log/auth.log | \
  awk '{print $(NF-3)}' | sort -u | \
  while read ip; do
    count=$(grep -c "$ip" /var/log/auth.log)
    echo "$ip: $count attempts"
  done

# 特定のエラーパターン発生時にアラート
tail -f /var/log/syslog | while read line; do
    echo "$line" | grep -q "CRITICAL" && echo "ALERT: $line" >> /tmp/alerts.log
done

9.3 dateコマンドと連携した時間ベース分析

# 最近1時間のログのみ抽出(syslog形式)
SINCE=$(date -d '1 hour ago' '+%b %e %H')
awk -v since="$SINCE" '$0 >= since' /var/log/syslog

# 昨日の日付のログ検索
YESTERDAY=$(date -d yesterday '+%b %e')
grep "^$YESTERDAY" /var/log/syslog

# 分単位のリクエスト数推移(最近1時間)
awk '{print substr($4,14,5)}' /var/log/nginx/access.log | sort | uniq -c | tail -60

9.4 実務お気に入りワンライナーベスト集

# === セキュリティ分析 ===

# 1. SSHブルートフォース攻撃IPトップ10 + GeoIPなしでの頻度分析
grep "Failed password" /var/log/auth.log | awk '{print $(NF-3)}' | sort | uniq -c | sort -rn | head -10

# 2. 現在接続中のSSHセッション
who | grep pts
ss -tnp | grep :22

# 3. sudoコマンド使用履歴
grep "COMMAND" /var/log/auth.log | awk -F: '{print $NF}' | sort | uniq -c | sort -rn | head -20

# 4. 不正なポート接続試行
grep "refused connect" /var/log/syslog | awk '{print $NF}' | sort | uniq -c | sort -rn


# === パフォーマンス分析 ===

# 5. Nginxレスポンスコード分布
awk '{print $9}' /var/log/nginx/access.log | sort | uniq -c | sort -rn

# 6. 時間帯別トラフィック(時間単位)
awk '{split($4,a,":"); print a[2]":00"}' /var/log/nginx/access.log | sort | uniq -c

# 7. 最も大きなレスポンスを生成したURL
awk '{print $10, $7}' /var/log/nginx/access.log | sort -rn | head -20

# 8. 帯域幅使用量の計算(日単位)
awk '{sum+=$10} END {printf "%.2f GB\n", sum/1024/1024/1024}' /var/log/nginx/access.log


# === 障害分析 ===

# 9. 最近のエラーログ総合(重複排除、頻度順)
grep -i "error\|fail\|critical\|fatal" /var/log/syslog | \
  sed 's/^.*\] //' | sort | uniq -c | sort -rn | head -30

# 10. サービス別再起動頻度
journalctl --since "7 days ago" | grep "Started" | \
  awk '{for(i=5;i<=NF;i++) printf $i" "; print ""}' | sort | uniq -c | sort -rn | head -20

# 11. カーネルパニック/OOPS確認
journalctl -k -p crit --since "7 days ago"
dmesg -T | grep -i "panic\|oops\|bug\|error"

# 12. ディスクフル警告関連ログ
grep -i "no space\|disk full\|ENOSPC" /var/log/syslog

10. ログ監視の自動化

10.1 シンプルなログ監視スクリプト

#!/bin/bash
# log_monitor.sh - ログ監視およびアラートスクリプト

LOG_FILE="/var/log/syslog"
ALERT_PATTERNS="error|critical|fatal|panic|OOM|segfault"
ALERT_LOG="/var/log/alert_monitor.log"
CHECK_INTERVAL=60

echo "[$(date)] Log monitor started for $LOG_FILE" | tee -a "$ALERT_LOG"

tail -Fn0 "$LOG_FILE" | while read line; do
    if echo "$line" | grep -qiE "$ALERT_PATTERNS"; then
        TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')
        echo "[$TIMESTAMP] ALERT: $line" | tee -a "$ALERT_LOG"

        # ここにアラートを追加(メール、Slackなど)
        # echo "$line" | mail -s "Log Alert" admin@example.com
    fi
done

10.2 logwatchを活用した日次レポート

# logwatchのインストール
sudo apt install logwatch          # Debian/Ubuntu
sudo yum install logwatch          # RHEL/CentOS

# 日次レポートの生成
logwatch --detail High --range today --output stdout

# メールで送信
logwatch --detail High --range yesterday --mailto admin@example.com --format html

# 特定サービスのみ分析
logwatch --service sshd --detail High --range today

10.3 multitail - マルチログリアルタイム監視

# multitailのインストール
sudo apt install multitail

# 複数ログの同時監視(画面分割)
multitail /var/log/syslog /var/log/auth.log

# カラーハイライト + フィルター
multitail -ci green /var/log/nginx/access.log -ci red /var/log/nginx/error.log

# カラースキームとフィルター適用
multitail -e "error" /var/log/syslog -e "Failed" /var/log/auth.log

10.4 lnav - 構造化ログアナライザー

# lnavのインストール
sudo apt install lnav

# 基本的な使用方法(自動フォーマット検出)
lnav /var/log/syslog

# 複数ファイルの同時分析
lnav /var/log/syslog /var/log/auth.log

# lnav内部でSQLクエリ使用
# ;SELECT log_time, log_body FROM syslog_log WHERE log_body LIKE '%error%' LIMIT 20

# 圧縮ファイルも自動サポート
lnav /var/log/syslog.*.gz
TIP: lnavはログフォーマットを自動検出し、色分け、タイムライン、ヒストグラム、SQLクエリまでサポートする非常に強力なターミナルベースのログアナライザーです。ターミナルで長時間ログ分析を行う場合に最適な選択肢です。

11. ログ分析のベストプラクティス

11.1 効率的なログ分析の習慣

  • 全体像から始めるwc -lで規模を把握 → grep -cでエラー頻度を確認 → 詳細分析に進む
  • 時間範囲を絞る:障害発生時点の前後に範囲を絞って分析すれば、不要なノイズを減らせます。
  • パイプラインを段階的に構築する:一度に複雑なワンライナーを書くのではなく、パイプを1つずつ追加しながら結果を確認しましょう。
  • aliasを活用する:よく使うログ分析コマンドを~/.bashrcにaliasとして登録しておくと効率が上がります。
  • teeで中間結果を保存するcommand | tee /tmp/result.txt | next_commandで中間結果をファイルに保管しながらパイプラインを続けることができます。

11.2 便利なbash alias設定

# ~/.bashrcに追加するログ分析alias
alias syslog='tail -f /var/log/syslog'
alias authlog='tail -f /var/log/auth.log'
alias nginxlog='tail -f /var/log/nginx/access.log'
alias nginxerr='tail -f /var/log/nginx/error.log'

alias logerror='grep -i "error\|fail\|critical" /var/log/syslog | tail -50'
alias sshfail='grep "Failed password" /var/log/auth.log | awk '\''{print $(NF-3)}'\'' | sort | uniq -c | sort -rn | head -20'
alias topip='awk '\''{print $1}'\'' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20'

alias jlog='journalctl -f'
alias jerr='journalctl -p err --since "1 hour ago" --no-pager'

11.3 セキュリティに関する注意事項

  • ログファイルの権限管理:ログファイルには機密情報(IP、ユーザー名、クエリパラメータ)が含まれる可能性があるため、適切な権限(640以下)を設定してください。
  • ログの完全性保護:侵入者がログを削除・改ざんする可能性があるため、重要なサーバーはリモートログ収集(rsyslogリモート転送、ELK、Lokiなど)を併用してください。
  • ログ保持ポリシー:法的要件とディスク容量を考慮して、logrotateと保持期間を適切に設定してください。
  • 個人情報への配慮:ログに含まれる個人情報(IP、メールアドレスなど)は、個人情報保護法に基づき適切に管理する必要があります。

12. コマンドクイックリファレンス チートシート

目的 コマンド
リアルタイム監視 tail -f /var/log/syslog
キーワードリアルタイムフィルター tail -f /var/log/syslog | grep --line-buffered "error"
エラー件数確認 grep -ci "error" /var/log/syslog
エラー前後のコンテキスト grep -C 5 "error" /var/log/syslog
IP別アクセス回数 awk '{print $1}' access.log | sort | uniq -c | sort -rn
HTTPステータスコード分布 awk '{print $9}' access.log | sort | uniq -c | sort -rn
SSH攻撃IP grep "Failed password" auth.log | awk '{print $(NF-3)}' | sort | uniq -c | sort -rn
時間帯別エラー grep "error" syslog | awk '{print $3}' | cut -d: -f1 | sort | uniq -c
サービスログ journalctl -u nginx.service -p err --since "1h ago"
カーネルエラー journalctl -k -p err
OOM確認 dmesg -T | grep -i "oom\|killed process"
ディスクエラー grep -i "I/O error\|read-only" /var/log/syslog
圧縮ログ検索 zgrep "error" /var/log/syslog.*.gz
ログ行数 wc -l /var/log/syslog
ジャーナルのディスク使用量 journalctl --disk-usage

まとめ:ログ分析は実践力がカギ

Linuxログ分析は、ツールやコマンドを知っているだけでは十分ではありません。実際の障害状況でどのログファイルを最初に確認すべきか、どのパターンでフィルタリングすべきか、結果をどう解釈すべきかという実践的な感覚が最も重要です。

このガイドで解説したコマンドを、ご自身のサーバー環境で実際に実行してみてください。grepawkの組み合わせ、journalctlのさまざまなフィルタリングオプション、sort | uniq -c | sort -rnパイプラインは、一度身につければどんなログ分析状況でも素早く対応できる武器になります。

特に覚えておくべき重要な原則は以下のとおりです:

  • 常に時間範囲を絞って始める - ログ全体を調べるのではなく、障害発生時点の前後に集中しましょう。
  • パイプラインを段階的に構築する - 一段階ずつ結果を確認しながらコマンドを追加しましょう。
  • よく使うコマンドはaliasに保存する - 緊急時にコマンドを思い出すよりaliasを入力する方が速いです。
  • リモートログ収集を併用する - ローカルログだけではセキュリティと可用性を保証できません。
  • 定期的にログを点検する - 障害が発生してからログを見るのではなく、普段からログの推移を監視する習慣が大切です。

ログ分析能力は、システム管理者、DevOpsエンジニア、SRE、セキュリティエンジニアすべてにとって不可欠なスキルです。今日学んだコマンドをすぐにターミナルで実行してみながら、自分だけの分析ルーティンを作ってみてください。