老项目没有用logf4j等日志框架,使用的是手动写入文件的方式存储日志。当日志过大会出现写入缓慢问题。下面采用IO异步写入以及文件过大分片等方式解决问题。
private static readonly object _lock = new object();
private const long MaxFileSize = 10 * 1024 * 1024; // 10MBpublic 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();
}