当前位置: 首页 > news >正文

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

直接上效果和代码:

代码:

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库等,这个库只适合简单工具,不想依赖其他库的情况下使用。

http://www.dtcms.com/a/108499.html

相关文章:

  • Zabbix_agent自动注册教程!
  • 利用 PHP 爬虫按关键字搜索淘宝商品
  • uni-app 微信小程序 WebSocket 接入讯飞语音合成(流式版)WebAPI 示例
  • 【Redis】如何处理缓存穿透、击穿、雪崩
  • 在 Blazor 中使用 Chart.js 快速创建数据可视化图表
  • 大模型生成浏览器端的初级俄罗斯方块
  • 美团民宿 mtgsig 小程序 mtgsig1.2 分析
  • Unity中的C#脚本中文字符无法正常显示问题
  • mysql-创建和删除索引的两种方式
  • 针对 MySQL 数据库中 主键/唯一约束的更新方法 和 ON DUPLICATE KEY UPDATE 语法的详细说明及示例,并以表格总结
  • YOLOv11区域检测
  • Element Plus 常用组件
  • 超越人工智能驱动的网络攻击:现代防御者的策略
  • 电子电气架构 --- 智能座舱域控设计
  • Flutter 音视频播放器与弹幕系统开发实践
  • RK3588使用笔记:USB转232、485、422模块驱动适配
  • [蓝桥杯 2024 省 A] 训练士兵
  • 虚拟试衣间-云尚衣橱小程序-衣橱管理实现
  • 算法:二进制求和
  • 从零构建大语言模型全栈开发指南:第四部分:工程实践与部署-4.3.3低代码开发:快速构建行业应用(电商推荐与金融风控案例)
  • Python 驱动周立功200U收发报文
  • 国产系统服务器识别不到SATA盘
  • STM32学习笔记之RCC模块(实操篇)
  • 横扫SQL面试——中位数问题
  • git tag
  • Linux 中CIFS和NFS使用说明
  • MCP学习总结
  • 基于RapidIO接口的DSP+GPU工业AI实时计算解决方案
  • ‘conda‘ 不是内部或外部命令,也不是可运行的程序或批处理文件
  • 【YOLOv8】YOLOv8改进系列(12)----替换主干网络之StarNet