首先,写Exception类的extensions
public static string ToStrings(this Exception ex)
{
if (ex == null)
{
return string.Empty;
}
var result = new StringBuilder();
result.AppendLine("============================");
var inner = ex;
while (inner != null)
{
result.AppendLine(ex.Message);
result.AppendLine("----------------------------");
result.AppendLine(ex.StackTrace);
inner = ex.InnerException;
}
return result.ToString();
}
之后,定义HandleErrorAttribute的继承类
public class ExtendedExceptionHandlerAttribute: HandleErrorAttribute
{
private static readonly ConcurrentQueue<Exception> ExceptionQueue = new ConcurrentQueue<Exception>();
public override void OnException(ExceptionContext context)
{
base.OnException(context);
ExceptionQueue.Enqueue(context.Exception);
}
public static void CaptureException(string path)
{
ThreadPool.QueueUserWorkItem(c =>
{
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
}
while (true)
{
if (ExceptionQueue.Count > 0)
{
var exist = ExceptionQueue.TryDequeue(out var ex);
if (exist && ex != null)
{
var fName = Path.Combine(path, DateTime.Today.ToString("yyyy-MM-dd") + ".txt");
File.AppendAllText(fName, ex.ToStrings());
}
else
{
Thread.Sleep(3000);
}
}
else
{
Thread.Sleep(3000);
}
}
}, path);
}
}
之后,在在MVC项目的App_Start的FilterConfig.cs 的 RegisterGlobalFilters,使用
filters.Add(new ShuFan.Infrastructure.Web.ExtendedExceptionHandlerAttribute());
并注释掉原有的 filters.Add(new HandleErrorAttribute());
最后,在在Application_Start中的最后,加入
ExtendedExceptionHandlerAttribute.CaptureException(Server.MapPath("~/Logs/"))