ASP.NET CORE 全局异常捕获+LOG4NET记录日志

项目一旦出现异常,记录错误日志就显得尤为重要。今天我就分享在ASP.NET CORE中全局捕获异常并记录日志的代码,下面给出具体实现过程。


1、日志实现类

/// <summary>

///

///

public class InitRepository

{

/// <summary>

///

///

public static ILoggerRepository LogRepository { get; set; }

}

/// <summary>

///

///

public class LogHelper

{

private static readonly ILog logerror = LogManager.GetLogger(InitRepository.LogRepository.Name, "logerror");

private static readonly ILog loginfo = LogManager.GetLogger(InitRepository.LogRepository.Name, "loginfo");

#region 全局异常错误记录持久化

/// <summary>

/// 全局异常错误记录持久化

///

/// <param>

/// <param>

public static void WriteError(string throwMsg, Exception ex)

{

string errorMsg = string.Format("\\r\\n[名称]:{0}\\r\\n[方法]:{4}\\r\\n[类型]:{1}\\r\\n[信息]:{2}\\r\\n[堆栈]:{3}", new object[] { throwMsg,

ex.GetType().Name, ex.Message, ex.StackTrace.Trim(),ex.StackTrace.Split(" in ")[0].Replace("at","").Trim() });

errorMsg += "\\r\\n";

logerror.Error(errorMsg);

}

#endregion

#region 自定义操作记录

/// <summary>

///

///

/// <param>

/// <param>

/// <param>

public static void WriteInfo(string name, string message, string method = "")

{

string errorMsg = string.Format("\\r\\n[名称]:{0}", new object[] { name });

if (!string.IsNullOrWhiteSpace(message))

{

errorMsg += $"\\r\\n[方法]:{method} ";

}

errorMsg += $"\\r\\n[信息]:{message}";

errorMsg += "\\r\\n";

loginfo.Info(errorMsg);

}

public static void WriteInfo(string throwMsg, Exception ex)

{

string errorMsg = string.Format("\\r\\n[名称]:{0}\\r\\n[方法]:{4}\\r\\n[类型]:{1}\\r\\n[信息]:{2}\\r\\n[堆栈]:{3}", new object[] { throwMsg,

ex.GetType().Name, ex.Message, ex.StackTrace.Trim(),ex.StackTrace.Split(" in ")[0].Replace("at","").Trim() });

errorMsg += "\\r\\n";

loginfo.Info(errorMsg);

}

#endregion

}

2、全局异常捕获类

public class GlobalExceptions : IExceptionFilter

{

private readonly IHostEnvironment _env;

public GlobalExceptions(IHostEnvironment env)

{

_env = env;

}

public void OnException(ExceptionContext context)

{

var json = new JsonErrorResponse(); //这里面是自定义的操作记录日志

json.Message = "内部服务器错误";

if (_env.IsDevelopment())

{

json.DevelopmentMessage = context.Exception.StackTrace;//堆栈信息

}

context.Result = new InternalServerErrorObjectResult(json);

//采用log4net 进行错误日志记录

LogHelper.WriteError(json.Message, context.Exception);

}

}

public class InternalServerErrorObjectResult : ObjectResult

{

public InternalServerErrorObjectResult(object value) : base(value)

{

StatusCode = StatusCodes.Status500InternalServerError;

}

}

public class JsonErrorResponse

{

/// <summary>

/// 生产环境的消息

///

public string Message { get; set; }

/// <summary>

/// 开发环境的消息

///

public string DevelopmentMessage { get; set; }

}

3、Startup注册

public Startup(IConfiguration configuration)

{

Configuration = configuration;

repository = LogManager.CreateRepository("NetCoreRepository");

XmlConfigurator.Configure(repository, new FileInfo("log4net.config"));

Utils.InitRepository.LogRepository = repository;

}


4、配置log4net.config文件

<configuration>

<log4net>

<appender>

<layout>

<logger>

<level>

<appender-ref>

<appender>

<param>

<param>

<param>

<param>

<param>

<param>

<param>

<layout>

<conversionpattern>

<logger>

<level>

<appender-ref>

<appender>

<param>

<param>

<param>

<param>

<param>

<param>

<param>

<layout>

<conversionpattern>

<root>

<level>

<appender-ref>

<appender-ref>

<appender-ref>


5、异常测试

/// <summary>

/// 用户登录

///

/// <param>账号

/// <param>密码

/// <returns>

[HttpPost]

[Route("Login")]

public string Login(string userName , string password)

{

Utils.LogHelper.WriteInfo("用户登录", $"账号:{userName},密码:{password}", method + "." + System.Reflection.MethodBase.GetCurrentMethod().Name);

int a = 10;

int b = 0;

//测试除0异常

int c = a / b;

return "success";

}


6、错误展示

2020-02-16 23:21:04,719 [10] ERROR logerror [(null)] -

[名称]:内部服务器错误

[方法]:Demo.WebAPI.Controllers.UserController.Login(String userName, String password)

[类型]:DivideByZeroException

[信息]:Attempted to divide by zero.

[堆栈]:at Demo.WebAPI.Controllers.UserController.Login(String userName, String password) in F:\\work2020\\Demo\\Demo.WebAPI\\Controllers\\UserController.cs:line 52

at lambda_method(Closure , Object , Object[] )

at Microsoft.Extensions.Internal.ObjectMethodExecutor.Execute(Object target, Object[] parameters)

at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.SyncObjectResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)

at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeActionMethodAsync()

at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)

at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeNextActionFilterAsync()

--- End of stack trace from previous location where exception was thrown ---

at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)

at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)

at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeInnerFilterAsync()

--- End of stack trace from previous location where exception was thrown ---

at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<invokenextexceptionfilterasync>g__Awaited|25_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)/<invokenextexceptionfilterasync>


分享到:


相關文章: