C# Tips | ログ・例外・診断:ログローテート

C# C#
スポンサーリンク

はじめに:ログローテートは“ログを永遠に増やさないための自動整理術”

ログを出し続けるアプリは、放っておくと ログファイルが無限に肥大化 します。
その結果、ディスクがいっぱいになり、アプリが止まることすらあります。

そこで必要になるのが ログローテート(Log Rotation) です。
これは、

古いログファイルを別名に切り替える
新しいログファイルに書き始める
必要に応じて圧縮・削除する

という「ログの自動入れ替え」仕組みのことです。

初心者でも理解しやすいように、実務でよく使うローテーションの考え方と C# 実装例を丁寧に解説します。


ログローテートの基本概念

ログローテートは「ログファイルの世代管理」

ログローテートの目的は、次の 2 つを同時に満たすことです。

ログを残す(調査のため)
ログを増やしすぎない(ディスク保護のため)

そのために、ログファイルを「世代(世代番号や日付)」で管理します。

例:
app.log(最新)
app-20260506.log(昨日)
app-20260505.log(一昨日)

このように、新しいログは常に新しいファイルに書き、古いログは別ファイルに退避するのがローテーションです。

ここでの重要ポイントは、
「ログを切り替えるタイミング」を決めることがローテーションの本質
という点です。


ログローテートのタイミングをどう決めるか

日付で切り替える(日次ローテーション)

最も一般的なのが「日付で切り替える」方式です。

今日:app.log
昨日:app-20260505.log
一昨日:app-20260504.log

日付ローテーションは、バッチや業務アプリでよく使われます。

メリット
読みやすい
調査しやすい
運用ルールを決めやすい

サイズで切り替える(サイズローテーション)

ログが大量に出るアプリでは、サイズで切り替える方式もあります。

例:
1MB を超えたら app.logapp.1.log にリネーム
さらに超えたら app.2.log にローテーション

メリット
大量ログでもディスクを守れる
日付に関係なく安定運用できる

ここでの重要ポイントは、
「日付ローテーションは読みやすさ重視」「サイズローテーションは安全性重視」
という違いです。


C# で作るシンプルな日付ローテーション

今日のログと昨日のログを自動で切り替える

まずは、最もシンプルな「日付ローテーション」を実装してみます。

using System;
using System.IO;

public static class DailyLogRotator
{
    public static string GetLogFilePath(string logDir)
    {
        Directory.CreateDirectory(logDir);

        var today = DateTime.Today.ToString("yyyyMMdd");
        return Path.Combine(logDir, $"app-{today}.log");
    }

    public static void WriteLog(string logDir, string message)
    {
        var path = GetLogFilePath(logDir);
        var line = $"{DateTime.Now:yyyy-MM-dd HH:mm:ss} {message}{Environment.NewLine}";
        File.AppendAllText(path, line);
    }
}
C#

使い方はこうです。

DailyLogRotator.WriteLog("logs", "アプリ開始");
DailyLogRotator.WriteLog("logs", "処理中...");
C#

毎日、別ファイルに自動で切り替わります。

ここでの重要ポイントは、
「ログファイル名に日付を入れるだけで、ローテーションがほぼ完成する」
ということです。


C# で作るサイズローテーション

サイズが一定を超えたらファイルを切り替える

次は「サイズローテーション」の例です。

using System;
using System.IO;

public static class SizeLogRotator
{
    public static void WriteLog(string logDir, string baseName, string message, long maxSizeBytes = 1_000_000)
    {
        Directory.CreateDirectory(logDir);

        var logPath = Path.Combine(logDir, baseName + ".log");

        if (File.Exists(logPath) && new FileInfo(logPath).Length > maxSizeBytes)
        {
            var timestamp = DateTime.Now.ToString("yyyyMMdd_HHmmss");
            var rotatedPath = Path.Combine(logDir, $"{baseName}-{timestamp}.log");
            File.Move(logPath, rotatedPath);
        }

        var line = $"{DateTime.Now:yyyy-MM-dd HH:mm:ss} {message}{Environment.NewLine}";
        File.AppendAllText(logPath, line);
    }
}
C#

使い方はこうです。

SizeLogRotator.WriteLog("logs", "app", "ログメッセージ");
C#

サイズが上限を超えると、自動でローテーションされます。

ここでの重要ポイントは、
「サイズローテーションでは、ファイル名にタイムスタンプを付けると衝突しない」
という点です。


ローテーション後の処理:圧縮・削除と組み合わせる

ローテーションは「ログ管理の第一段階」

ローテーションは「ログを分ける」だけで、
ディスクを守るには 圧縮削除 が必要です。

典型的な流れは次のようになります。

今日のログは生のまま
昨日のログは圧縮(ZIP / GZip)
30 日より前のログは削除

ローテーション → 圧縮 → 削除
という三段構えで、ログ管理が完成します。

ここでの重要ポイントは、
「ローテーションは“ログを整理する仕組み”、圧縮と削除は“ログを減らす仕組み”」
という役割分担です。


ログローテートをユーティリティ化するメリット

どのプロジェクトでも使い回せる「ログ管理の基盤」になる

ローテーション処理をユーティリティとしてまとめておくと、

バッチ処理
デスクトップアプリ
コンソールツール
オンプレのサービス

どこでも同じ仕組みを使い回せます。

特に、次のようなメリットがあります。

ログファイルが肥大化しない
調査しやすいログ構造になる
圧縮・削除と組み合わせやすい
運用ルールをコードとして明文化できる

ここでの重要ポイントは、
「ログローテートは“運用の安定性”を支える基盤技術」
ということです。


まとめ:ログローテートは“ログを安全に残し続けるための必須技術”

ログローテートの本質は、

ログを永遠に増やさず、
必要な期間だけ安全に残し、
調査しやすい形に整理すること

です。

押さえておくべきポイントは次の通りです。

日付ローテーションは読みやすく、業務で最も使われる
サイズローテーションは大量ログに強い
ローテーション後は圧縮・削除と組み合わせる
ファイル名に日付やタイムスタンプを入れると管理しやすい
ユーティリティ化すると、どのプロジェクトでも再利用できる

ここまで理解できていれば、
「ログが増えて困る」から卒業して、
“ログを安全に残し続ける設計”ができるエンジニアに近づけます。

タイトルとURLをコピーしました