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>


分享到:


相關文章: