老项目没有用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();
}