C# 手动写入日志,过大写入新文件

老项目没有用logf4j等日志框架,使用的是手动写入文件的方式存储日志。当日志过大会出现写入缓慢问题。下面采用IO异步写入以及文件过大分片等方式解决问题。

cs 复制代码
private static readonly object _lock = new object();
private const long MaxFileSize = 10 * 1024 * 1024; // 10MB

public void SaveTextAsync(string data, string ex, string methods)
{
    try
    {
        DateTime date = DateTime.Now;
        string logData = date.ToString("yyyy-MM-dd HH:mm:ss") + "\r\n" + data + "\r\n" + ex;
        string strDate = date.ToString("yyyyMMdd");
        string strDateTxt = strDate + ".txt";

        string programPath = AppDomain.CurrentDomain.BaseDirectory.Substring(0, 2);
        string logDir = Path.Combine(programPath + "", "\\MESBUG", strDate, methods);
        lock (_lock)
        {

            if (!Directory.Exists(logDir))
            {
                Directory.CreateDirectory(logDir);
            }

            // 获取当前最新的日志文件
            string filePath = GetLatestLogFile(logDir, strDate);

            // 检查文件大小并切割
            filePath = CheckFileSizeAndRotate(filePath, logDir, strDate);

            byte[] logDataBytes = System.Text.Encoding.UTF8.GetBytes(logData + Environment.NewLine);

            FileStream fs = new FileStream(filePath, FileMode.Append, FileAccess.Write, FileShare.None, 4096, true);

            // 异步写入
            fs.BeginWrite(logDataBytes, 0, logDataBytes.Length, new AsyncCallback(EndWriteCallback), fs);

        }
    }
    catch (Exception ex2)
    {
        return;
    }

}

// 获取日志目录中最新的日志文件
private string GetLatestLogFile(string logDir, string strDate)
{
    // 获取日志目录下所有日志文件,按文件名排序
    var logFiles = Directory.GetFiles(logDir, $"{strDate}_*.txt")
                            .OrderByDescending(f => f)
                            .FirstOrDefault();

    if (logFiles == null)
    {
        // 如果没有找到分片日志文件,则返回默认的日志文件路径
        return Path.Combine(logDir, strDate + ".txt");
    }

    return logFiles;
}

// 检查文件大小并切割日志文件
private string CheckFileSizeAndRotate(string filePath, string logDir, string strDate)
{
    FileInfo fileInfo = new FileInfo(filePath);

    // 如果文件超过指定大小,则创建新文件
    if (fileInfo.Exists && fileInfo.Length > MaxFileSize)
    {
        string newFileName = $"{strDate}_{DateTime.Now.ToString("HHmmss")}.txt";
        return Path.Combine(logDir, newFileName);
    }

    return filePath;
}

private void EndWriteCallback(IAsyncResult ar)
{
    FileStream fs = (FileStream)ar.AsyncState;
    fs.EndWrite(ar);
    fs.Close();
}
相关推荐
牛哇网络工作室19 小时前
UnityHDRP写实数字人全流程基础5—语音输入和语音识别
android·unity·c#·游戏引擎·aigc·语音识别·xcode
zlinear数据采集卡1 天前
数据采集卡从入门到精通(9):分辨率与精度——16位卡不等于1/65536的精度
开发语言·数据库·fpga开发·开源·c#
深澈Vincel1 天前
我用 C# + WebView2 做了一个针对“流氓软件”的“一键清理工具“:架构实践与踩坑记录
c#
zlinear数据采集卡1 天前
数据采集卡从入门到精通(7):流水线型ADC——级级接力,高速与高精的平衡术
开发语言·arm开发·嵌入式硬件·fpga开发·c#
kingwebo'sZone1 天前
C# 根据公式计算的方法
开发语言·c#
阿部多瑞 ABU1 天前
告别手工核图:基于 .NET + MuPDFCore 的 CAD 等轴测 PDF 材料表提取与新旧版本对比实战
后端·算法·ui·pdf·c#
条形码D1 天前
DRG综合管理分析系统-目前已经支持CHS-DRG3.0
c#·drg·3.0分组器·drg分组器·chs-drg3.0分组器
Alex Gram2 天前
数据库同步工具PanguSync图文教程
java·mysql·postgresql·sqlserver·c#·数据库同步软件·数据库同步工具
头茬韭菜2 天前
第 10 篇:「Fluss 实战案例集」—— 完整解决方案与最佳实践
c#·linq·fluss
淡海水2 天前
01-05-运行时-JIT优化全景-内联去虚拟化边界检查消除
windows·c#·虚拟化·jit·内联·边界检查消除