using System; using System.IO; using System.Linq; using log4net.Appender; using log4net.Util; namespace LotteryWebApp.Common { /// /// RollingFileAppender ghi log mỗi ngày 1 file (rolling theo ngày) và chỉ giữ lại /// N file log gần nhất — các file cũ hơn sẽ tự động bị xóa để tránh đầy ổ cứng. /// Toàn bộ cấu hình nằm trong log4net.config, không cần task bên ngoài. /// public class DailyRollingFileAppender : RollingFileAppender { /// /// Số file log tối đa được giữ lại. Cấu hình qua <maxNumberOfFiles value="30" /> /// trong log4net.config. Mặc định 30. Đặt <= 0 để tắt việc tự xóa. /// public int MaxNumberOfFiles { get; set; } = 30; // Chỉ dọn log 1 lần mỗi ngày để không ảnh hưởng hiệu năng ghi log. private DateTime _lastCleanupDate = DateTime.MinValue; private readonly object _cleanupLock = new object(); protected override void AdjustFileBeforeAppend() { // Để log4net xử lý việc cuộn file theo ngày trước. base.AdjustFileBeforeAppend(); if (_lastCleanupDate == DateTime.Today) return; lock (_cleanupLock) { if (_lastCleanupDate == DateTime.Today) return; _lastCleanupDate = DateTime.Today; } CleanupOldFiles(); } /// Giữ lại MaxNumberOfFiles file .log mới nhất, xóa phần còn lại. private void CleanupOldFiles() { try { if (MaxNumberOfFiles <= 0) return; string dir = Path.GetDirectoryName(File); if (string.IsNullOrEmpty(dir) || !Directory.Exists(dir)) return; var oldFiles = new DirectoryInfo(dir) .GetFiles("*.log") .OrderByDescending(f => f.LastWriteTimeUtc) .Skip(MaxNumberOfFiles) .ToList(); foreach (FileInfo file in oldFiles) { try { file.Delete(); LogLog.Debug(GetType(), "Da xoa file log cu: " + file.Name); } catch (Exception ex) { LogLog.Warn(GetType(), "Khong xoa duoc file log: " + file.FullName, ex); } } } catch (Exception ex) { LogLog.Error(GetType(), "Loi khi don dep file log cu", ex); } } } }