375 字
2 分钟
C# 日志记录方案
一个不依赖框架、灵活的日志记录类。
优点:
- 不依赖其他框架,极简灵活。
- 分块存储,不怕单文件过大。
- 写日志时自动检测创建文件,不担心删除文件后写入不了。
- 随用随调,静态实现,任何地方直接调用就能记录日志。
Logs.cs
public static class Logs{ private static readonly ConcurrentQueue<(string Level, string Message, DateTime Time)> LogQueue = new(); private static readonly CancellationTokenSource TokenSource = new(); private static readonly string LogRoot = Path.Combine(AppContext.BaseDirectory, "Log"); // 存储路径,默认程序根目录下的Log文件夹下 private static readonly long MaxFileSize = 5 * 1024 * 1024; // 5MB private static DateTime _lastLogTime = DateTime.MinValue; private static readonly object WriteLock = new();
static Logs() { Task.Factory.StartNew(ProcessQueue, TaskCreationOptions.LongRunning); }
public static void Info(string message) => Enqueue("info", message); // 详情记录 public static void Error(string message) => Enqueue("error", message); // 错误记录 // 可继续扩展...
private static void Enqueue(string level, string message) { LogQueue.Enqueue((level.ToLower(), message, DateTime.Now)); }
private static async Task ProcessQueue() { while (!TokenSource.IsCancellationRequested) { while (LogQueue.TryDequeue(out var entry)) { try { WriteLog(entry.Level, entry.Message, entry.Time); } catch { // 可扩展重试逻辑或写入到 fallback 文件 } } await Task.Delay(100); // 避免空转 } }
private static void WriteLog(string level, string message, DateTime time) { var basePath = Path.Combine(LogRoot, time.ToString("yyyy_MM")); Directory.CreateDirectory(basePath);
var filePrefix = Path.Combine(basePath, $"{time:dd}_{level}"); var filePath = GetAvailableLogFile(filePrefix);
var content = $"[{time:yyyy-MM-dd HH:mm:ss.fff}] {message}{Environment.NewLine}";
lock (WriteLock) { File.AppendAllText(filePath, content, Encoding.UTF8); }
_lastLogTime = time; }
private static string GetAvailableLogFile(string basePath) { for (int i = 0; i < 1000; i++) { var filePath = i == 0 ? $"{basePath}.txt" : $"{basePath}_{i}.txt"; if (!File.Exists(filePath) || new FileInfo(filePath).Length < MaxFileSize) return filePath; }
throw new IOException("日志文件已超过最大数量限制"); }
public static void Stop() { TokenSource.Cancel(); }}使用示例:
Logs.Info("记录详情日志");Logs.Error("记录错误日志");