ほのぼの C#開発

開発の基礎から、現場で使用できるC#を掲載していきます。

C# log4net ログの世代管理

log4net ログの世代管理

log4net ログの世代管理について紹介します。

 今回は、ある一定期間を過ぎたログファイルを削除する。

ログの削除

//-------------------------------------------------
// ログの削除(世代管理)
//-------------------------------------------------
new LogFileCleanupTask().CleanUp();

 

ログの世代管理クラスについて

ログの保持すべき最終の日付を取得し、過去のものは削除する。

using System;
using System.IO;
using System.Linq;
using log4net;
using log4net.Appender;

namespace Common
{

    /// <summary>
    /// ログ世代管理のタスククラスです。
    /// </summary>
    public class LogFileCleanupTask
    {
        /// <summary>
        /// ログの世代管理の削除を行います。
        /// </summary>
        public void CleanUp()
        {
            var repo = LogManager.GetAllRepositories().FirstOrDefault();

            if (repo == null)
            {
                throw new NotSupportedException("Log4Netが設定されていません");
            }

            var app = repo.GetAppenders().FirstOrDefault(x => x.GetType() == typeof (RollingFileAppender));

            if (app != null)
            {
                var appender = app as RollingFileAppender;
                
                var directory = Path.GetDirectoryName(appender.File);
                var filePrefix = Path.GetFileName(appender.File);
                filePrefix = filePrefix.Substring(0, filePrefix.Length - appender.DatePattern.Replace("\"", "").Length);

        // ログの最終保持日付
                var targetDate = DateTime.Now.Date.AddDays(-appender.MaxSizeRollBackups);
                
                // 削除の実行
                CleanUp(directory, filePrefix,targetDate, appender);
            }
        }

 

 最終日付より過去のログファイルを削除

        /// <summary>
        /// ログの世代管理の削除の実行
        /// </summary>
        /// <param name="logDirectory">削除対象のディレクトリ.</param>
        /// <param name="logPrefix">ファイルのフォーマット名</param>
        /// <param name="lastDate">世代管理の開始日</param>
        /// <param name="appender">RollingFileAppender</param>
        private void CleanUp(string logDirectory, string logPrefix,DateTime lastDate, RollingFileAppender appender)
        {
            if (string.IsNullOrEmpty(logDirectory))
            {
                throw new ArgumentException("ログのディレクトリが存在しません");
            }

            if (string.IsNullOrEmpty(logDirectory))
            {
                throw new ArgumentException("ログのファイルフォーマット名の形式が存在しません");
            }

            var dirInfo = new DirectoryInfo(logDirectory);
            if (!dirInfo.Exists)
            {
                return;
            }

            // 削除
            dirInfo.GetFiles(String.Format("{0}*.*", logPrefix))
                .Where(info => GetLogDate(info, logPrefix, appender) < lastDate)
                .ForEach(info =>
                {
                    if ((info.Attributes & FileAttributes.ReadOnly) == FileAttributes.ReadOnly)
                        info.Attributes = FileAttributes.Normal;

                    Loggers.Log.Debug(string.Format("世代管理に伴い、過去のログファイルの削除を行います。ファイル:{0}",info.FullName));
                    // 削除
                    info.Delete();
                });

        }

        /// <summary>
        /// ログの作成日付を取得します。
        /// </summary>
        /// <param name="fileInfo">ファイル情報オブジェクト</param>
        /// <param name="logPrefix">ログファイル名のフォーマット</param>
        /// <param name="app">ログのアペンダー</param>
        /// <returns>ログの作成日付</returns>
        private DateTime GetLogDate(FileInfo fileInfo, string logPrefix,RollingFileAppender app)
        {
            var year = fileInfo.Name.Substring(logPrefix.Length + app.DatePattern.IndexOf("yyyy"), 4);
            var month = fileInfo.Name.Substring(logPrefix.Length + app.DatePattern.IndexOf("MM"), 2);
            var day = fileInfo.Name.Substring(logPrefix.Length + app.DatePattern.IndexOf("dd"), 2);

            return new DateTime(Convert.ToInt32(year), Convert.ToInt32(month), Convert.ToInt32(day));
        }
    }
}