ToB企服应用市场:ToB评测及商务社交产业平台
标题:
c# 实现一个简朴的非常日志记录(非常迭代+分片+定时清理)+AOP Rougamo全
[打印本页]
作者:
泉缘泉
时间:
2024-12-25 22:23
标题:
c# 实现一个简朴的非常日志记录(非常迭代+分片+定时清理)+AOP Rougamo全
1. 日志目录和文件管理
日志目录:日志文件存储在 ./Exceptions 目录下。
日志文件定名:日志文件的定名格式为 yyyy_MM_dd.log,表现当天的日期。假如当天的日志文件大小超过 maxFileSizeBytes(3KB),则会创建新的日志文件,文件名格式为 yyyy_MM_dd_P{cnt}.log,此中 cnt 是日志文件的编号。
日志文件编码:日志文件使用 UTF-8 编码。
2. 非常日志记录
WriteExceptionLog(Exception ex) 方法:
该方法用于记录非常信息。首先检查日志目录是否存在,假如不存在则创建。
获取当前日期的日志文件列表,并选择最新的日志文件(按文件名顺序)。
假如日志文件存在且大小超过 maxFileSizeBytes,则创建一个新的日志文件,文件名中包罗 _P{cnt},此中 cnt 是文件的编号。
将非常信息追加到日志文件中,使用 GetLogEntry(ex) 方法天生非常信息的日志条目。
末了调用 CleanupOldLogFiles() 方法清理超过 maxLogFileAgeDays(1天)的旧日志文件。
3. 日志条目天生
GetLogEntry(Exception ex, int depth = 0) 方法:
– 该方法递归地天生非常信息的日志条目。
– 每层非常信息使用 depth 参数控制缩进,便于阅读。
– 日志条目包括非常时间、非常信息、非常对象和调用堆栈。
– 假如非常有嵌套的内部非常(InnerException),则递归调用 GetLogEntry 方法天生内部非常的日志条目。
4. 旧日志文件清理
CleanupOldLogFiles() 方法:
– 该方法用于清理超过 maxLogFileAgeDays(1天)的旧日志文件。
–获取日志目录中全部 .log 文件,检查文件的末了修改时间,假如超过 maxLogFileAgeDays,则删除该文件。
5. 非常处置处罚
非常处置处罚:在 WriteExceptionLog(Exception ex) 方法中,全部的利用都在 lock 块中举行,确保线程安全。假如发生非常,内部非常会被捕捉但不会记录,制止日志记录自己抛出的非常导致步伐瓦解。
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows;
using System.Windows.Shapes;
namespace DataParser.Helpers;
public class LogHelper
{
private static readonly object objException = new object();
private static readonly string logDirectory = "./Exceptions";
private static string curfileName = $"{DateTime.Now:yyyy_MM_dd}.log";
private static readonly int maxLogFileAgeDays = 1;
private static readonly long maxFileSizeBytes = 3*1024;
private static readonly Encoding encoding =Encoding.UTF8;
static int cnt= 0;
public static void WriteExceptionLog(Exception ex)
{
try
{
lock (objException)
{
if (!Directory.Exists(logDirectory))
{
Directory.CreateDirectory(logDirectory);
}
var files = Directory.GetFiles(logDirectory, "*.log")
.Select(x=>System.IO.Path.GetFileName(x))
.Where(x => x.Contains($"{DateTime.Now:yyyy_MM_dd}"));
if(files.Count()>0)
{
var tmp = files.OrderBy(x => x.Length);
curfileName = tmp.Last();
if (curfileName.Contains("_P"))
{
Match match = Regex.Match(curfileName, @"_P(\d+)");
if (match.Success)
{
string str = match.Groups[1].Value;
int.TryParse(str, out cnt);
}
}
}
else
{
curfileName = $"{DateTime.Now:yyyy_MM_dd}.log";
}
string fileName = System.IO.Path.Combine(logDirectory, curfileName);
string logEntry = GetLogEntry(ex);
if (File.Exists(fileName) && (new FileInfo(fileName).Length > maxFileSizeBytes))
{
cnt++;
fileName = System.IO.Path.Combine(logDirectory, $"{DateTime.Now:yyyy_MM_dd}_P{cnt}.log");
}
else if(!fileName.Contains("_P"))
{
cnt = 0;
}
File.AppendAllText(fileName, logEntry, encoding);
CleanupOldLogFiles();
}
}
catch (Exception innerEx)
{
}
}
private static string GetLogEntry(Exception ex, int depth = 0)
{
string indent = new string(' ', depth * 4);
string logEntry =
$"{indent}【异常时间】{DateTime.Now}{Environment.NewLine}" +
$"{indent}【异常信息】{ex.Message}{Environment.NewLine}" +
$"{indent}【异常对象】{ex.Source}{Environment.NewLine}" +
$"{indent}【调用堆栈】{Environment.NewLine} {ex.StackTrace?.Trim() ?? "N/A"}{Environment.NewLine}{Environment.NewLine}{Environment.NewLine}";
if (ex.InnerException != null)
{
logEntry += GetLogEntry(ex.InnerException, depth + 1);
}
return logEntry;
}
private static void CleanupOldLogFiles()
{
var files = Directory.GetFiles(logDirectory, "*.log")
.Select(f => new FileInfo(f))
.Where(f => (DateTime.Now - f.LastWriteTime).TotalDays > maxLogFileAgeDays);
foreach (var file in files)
{
File.Delete(file.FullName);
}
}
}
复制代码
Rougamo 实现AOP
导包Rougamo.Fody
using DataParser.Helpers;
using Rougamo;
using Rougamo.Context;
namespace DataParser
{
public class ExceptionLogAttribute : MoAttribute
{
public override void OnException(MethodContext context)
{
LogHelper.WriteExceptionLog(context.Exception);
context.HandledException(this, null);
}
}
}
复制代码
public partial class MainViewModel:IRougamo<ExceptionLogAttribute>
{}
复制代码
MainViewModel 类实现了接口 IRougamo<ExceptionLogAttribute>。这意味着在这个类中,全部被 ExceptionLogAttribute 特性标记的方法或类,都会在抛出非常时自动调用 ExceptionLogAttribute 的 OnException 方法
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/)
Powered by Discuz! X3.4