一个c#的简单日志记录类,避免使用Nuget依赖

发布于:2025-04-04 ⋅ 阅读:(27) ⋅ 点赞:(0)

直接上效果和代码:

代码:

using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using Microsoft.VisualBasic.Logging;

public static class LogHelper
{
    private static TraceSource _logSource;
    private static FileLogTraceListener _fileListener;
    private static string _currentLogPath;
    private const int MaxLogSizeKB = 500; // 日志文件最大500KB
    private const int KeepLogFiles = 3;   // 保留最近3个日志文件

    /// <summary>
    /// 初始化日志系统(支持按大小滚动)
    /// </summary>
    public static void Initialize(string logDirectory = null, string baseFileName = "App")
    {
        _logSource = new TraceSource("AppLogSource");
        _logSource.Switch = new SourceSwitch("LogSwitch") { Level = SourceLevels.All };

        // 初始化日志路径
        string logDir = logDirectory ?? $"{AppDomain.CurrentDomain.BaseDirectory}\\Logs";
        Directory.CreateDirectory(logDir);

        // 创建初始日志文件
        CreateNewLogFile(logDir, baseFileName);
    }

    /// <summary>
    /// 记录日志(自动检查文件大小)
    /// </summary>
    public static void Log(string message, TraceEventType eventType = TraceEventType.Information)
    {
        if (_logSource == null) throw new InvalidOperationException("请先调用 Initialize()");

        // 写入日志
        _logSource.TraceEvent(eventType, 0, $"{DateTime.Now:yyyy-MM-dd HH:mm:ss} - {message}");

        // 检查文件大小
        CheckAndRotateLog();
    }

    /// <summary>
    /// 创建新日志文件并清理旧文件
    /// </summary>
    private static void CreateNewLogFile(string logDir, string baseFileName)
    {
        // 关闭旧监听器
        if (_fileListener != null)
        {
            _logSource.Listeners.Remove(_fileListener);
            _fileListener.Close();
            _fileListener.Dispose();
        }

        // 生成带序号的新文件名(例如:App_1.log)
        int fileIndex = GetNextFileIndex(logDir, baseFileName);
        _currentLogPath = Path.Combine(logDir, $"{baseFileName}_{fileIndex}.log");

        // 创建新监听器
        _fileListener = new FileLogTraceListener
        {
            LogFileCreationSchedule = LogFileCreationScheduleOption.None,
            Location = LogFileLocation.Custom,
            CustomLocation = logDir,
            BaseFileName = Path.GetFileNameWithoutExtension(_currentLogPath),
            Append = true,
            AutoFlush = true
        };

        _logSource.Listeners.Add(_fileListener);

        // 清理旧文件
        CleanOldLogs(logDir, baseFileName);
    }

    /// <summary>
    /// 获取下一个可用文件序号
    /// </summary>
    private static int GetNextFileIndex(string logDir, string baseFileName)
    {
        var files = Directory.GetFiles(logDir, $"{baseFileName}_*.log");
        return files.Length + 1;
    }

    /// <summary>
    /// 清理旧日志文件(保留最近 KeepLogFiles 个)
    /// </summary>
    private static void CleanOldLogs(string logDir, string baseFileName)
    {
        var files = Directory.GetFiles(logDir, $"{baseFileName}_*.log")
            .OrderBy(f => File.GetCreationTime(f))
            .ToList();

        while (files.Count > KeepLogFiles)
        {
            File.Delete(files.First());
            files.RemoveAt(0);
        }
    }

    /// <summary>
    /// 检查当前日志文件大小并滚动
    /// </summary>
    private static void CheckAndRotateLog()
    {
        try
        {
            var fileInfo = new FileInfo(_currentLogPath);
            if (fileInfo.Exists && fileInfo.Length > MaxLogSizeKB * 1024)
            {
                CreateNewLogFile(Path.GetDirectoryName(_currentLogPath),
                    Path.GetFileNameWithoutExtension(_currentLogPath).Split('_')[0]);
            }
        }
        catch (Exception ex)
        {
            Trace.TraceError($"日志滚动失败: {ex.Message}");
        }
    }
}

可以实现滚动记录日志,效率不算高,如果追求效率考虑使用seriallog库等,这个库只适合简单工具,不想依赖其他库的情况下使用。