asp.net core添加全局异常处理及log4net、Nlog应用
0、目录
整体架构目录:ASP.NET Core分布式项目实战-目录
一、介绍
此篇文章将会介绍项目的全局异常收集以及采用log4net或者NLog记录。
众所周知,一旦自己的项目报错,如果没有进行处理都是显示不友好的,有得甚至直接爆出错误页面,看的也是很奇怪。
为了避免出现这样的错误以及在错误出现的时候可以进行收集错误,供维护人员进行bug修改,因此需要进行全局异常的收集。
让我们开始部署吧。
此篇文章的目录
1、log4net使用
2、Nlog使用
后期将会把NLog+ELK进行结合部署收集我们的asp.net core的项目。大家可以拭目以待吧。
二、部署(log4net使用)
1、新建一个asp.net core webapi的项目
然后目前我先引入 log4net nuget包。
2、然后创建一个log4net.config文件
此文件中,我创建了一个是记录 错误的文件夹(LogError)以及是记录操作的文件夹(LogInfo),代码如下:我把需要记录的文件放在了log文件夹下面。
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<log4net>
<!-- 错误日志类-->
<logger name="logerror">
<level value="ALL" />
<appender-ref ref="ErrorAppender" />
</logger>
<!-- 错误日志附加介质-->
<appender name="ErrorAppender" type="log4net.Appender.RollingFileAppender">
<!--日志文件路径-->
<param name="File" value="Log\\LogError\\" />
<!--是否是向文件中追加日志-->
<param name="AppendToFile" value="true" />
<!--log保留天数-->
<param name="MaxSizeRollBackups" value="" />
<!--最大文件大小-->
<param name="MaxFileSize" value="" />
<!--日志文件名是否是固定不变的-->
<param name="StaticLogFileName" value="false" />
<!--日志文件名格式为:--.log-->
<param name="DatePattern" value="yyyy-MM-dd".htm"" />
<!--日志根据日期滚动-->
<param name="RollingStyle" value="Date" />
<!--信息日志布局-->
<layout type="log4net.Layout.PatternLayout">
<param name="ConversionPattern" value="<HR COLOR=red>%n【异常时间】:%d [%t] <BR>%n【异常级别】:%-5p <BR>%n%m <BR>%n <HR Size=1>" />
</layout>
</appender> <!-- 信息日志类 -->
<logger name="loginfo">
<level value="ALL" />
<appender-ref ref="InfoAppender" />
</logger>
<!-- 信息日志附加介质-->
<appender name="InfoAppender" type="log4net.Appender.RollingFileAppender">
<!--日志文件路径-->
<param name="File" value="Log\\LogInfo\\" />
<!--是否是向文件中追加日志-->
<param name="AppendToFile" value="true" />
<!--log保留天数-->
<param name="MaxSizeRollBackups" value="" />
<param name="MaxFileSize" value="" />
<!--日志文件名是否是固定不变的-->
<param name="StaticLogFileName" value="false" />
<!--日志文件名格式为:--.log-->
<param name="DatePattern" value="yyyy-MM-dd".htm"" />
<!--日志根据日期滚动-->
<param name="RollingStyle" value="Date" />
<!--信息日志布局-->
<layout type="log4net.Layout.PatternLayout">
<param name="ConversionPattern" value="<HR COLOR=blue>%n日志时间:%d [%t] <BR>%n日志级别:%-5p <BR>%n%m <BR>%n <HR Size=1>" />
</layout>
</appender>
</log4net> <!-- To customize the asp.net core module uncomment and edit the following section.
For more info see https://go.microsoft.com/fwlink/?linkid=838655 -->
<!--
<system.webServer>
<handlers>
<remove name="aspNetCore"/>
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified"/>
</handlers>
<aspNetCore processPath="%LAUNCHER_PATH%" arguments="%LAUNCHER_ARGS%" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" />
</system.webServer>
--> </configuration>
3、在asp.net core项目中 Startup.cs 中需要添加初始化log4net的仓储名,主要是用来给log4net标记一个名称,这边可以随意。
4、在项目中创建一个类用来记录log的日志格式以及数据分类存放
创建LogHelper.cs,
定义log格式,当然自己可以随意定义哈。
#region 全局异常错误记录持久化
/// <summary>
/// 全局异常错误记录持久化
/// </summary>
/// <param name="throwMsg"></param>
/// <param name="ex"></param>
public static void ErrorLog(string throwMsg, Exception ex)
{
string errorMsg = string.Format("【抛出信息】:{0} <br>【异常类型】:{1} <br>【异常信息】:{2} <br>【堆栈调用】:{3}", new object[] { throwMsg,
ex.GetType().Name, ex.Message, ex.StackTrace });
errorMsg = errorMsg.Replace("\r\n", "<br>");
errorMsg = errorMsg.Replace("位置", "<strong style=\"color:red\">位置</strong>");
logerror.Error(errorMsg);
}
#endregion
#region 自定义操作记录
/// <summary>
/// 自定义操作记录,与仓储中的增删改的日志是记录同一张表
/// </summary>
/// <param name="throwMsg"></param>
/// <param name="ex"></param>
public static void WriteLog(string throwMsg, Exception ex)
{
string errorMsg = string.Format("【抛出信息】:{0} <br>【异常类型】:{1} <br>【异常信息】:{2} <br>【堆栈调用】:{3}", new object[] { throwMsg,
ex.GetType().Name, ex.Message, ex.StackTrace });
errorMsg = errorMsg.Replace("\r\n", "<br>");
errorMsg = errorMsg.Replace("位置", "<strong style=\"color:red\">位置</strong>");
logerror.Error(errorMsg);
}
#endregion
5、有了以上的log格式,这样我就开始定义一下全局异常处理吧
我这边先创建一个全局异常处理类 GlobalExceptions.cs 然后需要在startup.cs中注入
在ConfigureServices 方法中注入。
//注入全局异常捕获
services.AddMvc(o =>
{
o.Filters.Add(typeof(GlobalExceptions));
});
6、GlobalExceptions类中添加处理,当然异常需要继承IExceptionFilter。
代码如下:
GlobalExceptions
public class GlobalExceptions : IExceptionFilter
{
private readonly IHostingEnvironment _env;
public GlobalExceptions(IHostingEnvironment env)
{
_env = env;
}
public void OnException(ExceptionContext context)
{
var json = new JsonErrorResponse();
//这里面是自定义的操作记录日志
if (context.Exception.GetType() == typeof(UserOperationException))
{
json.Message = context.Exception.Message;
if (_env.IsDevelopment())
{
json.DevelopmentMessage = context.Exception.StackTrace;//堆栈信息
}
context.Result = new BadRequestObjectResult(json);//返回异常数据
}
else
{
json.Message = "发生了未知内部错误";
if (_env.IsDevelopment())
{
json.DevelopmentMessage = context.Exception.StackTrace;//堆栈信息
}
context.Result = new InternalServerErrorObjectResult(json);
} //采用log4net 进行错误日志记录
LogHelper.ErrorLog(json.Message, context.Exception); }
}
public class InternalServerErrorObjectResult : ObjectResult
{
public InternalServerErrorObjectResult(object value) : base(value)
{
StatusCode = StatusCodes.Status500InternalServerError;
}
}
JsonErrorResponse.cs
public class JsonErrorResponse
{
/// <summary>
/// 生产环境的消息
/// </summary>
public string Message { get; set; }
/// <summary>
/// 开发环境的消息
/// </summary>
public string DevelopmentMessage { get; set; }
}
UserOperationException.cs
/// <summary>
/// 操作日志
/// </summary>
public class UserOperationException : Exception
{
public UserOperationException() { }
public UserOperationException(string message) : base(message) { }
public UserOperationException(string message, Exception innerException) : base(message, innerException) { }
}
自此,全局异常配置完成,然后我们可以测试一下,随便写一个除以0的代码在日志记录中就会出现如下的展示:
哇,发现我的错误日志的格式非常的清楚,当然这个跟我的做事态度以及性格有很大的关系的啦,毕竟楼主还是很帅的。哈哈哈。
三、NLog使用
1、在项目中添加nlog的nuget包引入,“NLog.Web.AspNetCore”
2、创建nlog.config文件,大家会发现我的log格式跟上面的格式操作,而且我的分层层次也很清楚。哈哈.
<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
autoReload="true">
<!-- the targets to write to -->
<targets>
<!-- 输出到文件,这个文件记录所有的日志 -->
<target xsi:type="File" name="allfile" fileName="Log\LogAll\${shortdate}.htm"
layout="<HR COLOR=red>${longdate}<BR>${logger}<BR>${uppercase:${level}}<BR>${message} ${exception}<HR Size=1>" /> <!-- 输出到文件,这个文件记录错误日志 -->
<target xsi:type="File" name="logError" fileName="Log\LogError\${shortdate}.htm"
layout="<HR COLOR=red>【异常时间】:${date} <BR>【异常级别】:${level:uppercase=true} <BR>${message}<HR Size=1>" /> <!-- 输出到文件,这个文件记录操作日志 -->
<target xsi:type="File" name="logInfo" fileName="Log\LogInfo\${shortdate}.htm"
layout="<HR COLOR=red>【操作时间】:${date} <BR>【操作级别】:${level:uppercase=true} <BR>${message}<HR Size=1>" />
</targets>
<!-- rules to map from logger name to target -->
<rules>
<!--All logs, including from Microsoft-->
<logger name="*" minlevel="Trace" writeTo="allfile" />
<logger name="*" minlevel="Error" writeTo="logError" />
<logger name="*" minlevel="Info" writeTo="logInfo" />
<logger name="Microsoft.*" maxLevel="Info" final="true" />
</rules>
</nlog>
注:然后将此文件点击右键,选择属性,把复制输出目录修改为“始终复制”,无法不修改,则会无法加载此文件。
3、在startup.cs中的 Configure方法注入
//ILoggerFactory loggerFactory
loggerFactory.AddNLog();
NLog.LogManager.LoadConfiguration("nlog.config"); //填入上面创建的文件的名称
然后运行以下即可看到在bin/debug下面生成文件夹
4、创建NLogHelp.cs类
public class NLogHelp
{
public static Logger logger = LogManager.GetCurrentClassLogger();
public static void ErrorLog(string throwMsg, Exception ex)
{
string errorMsg = string.Format("【异常信息】:{0} <br>【异常类型】:{1} <br>【堆栈调用】:{2}",
new object[] { throwMsg, ex.GetType().Name, ex.StackTrace });
errorMsg = errorMsg.Replace("\r\n", "<br>");
errorMsg = errorMsg.Replace("位置", "<strong style=\"color:red\">位置</strong>");
logger.Error(errorMsg);
}
public static void InfoLog(string operateMsg)
{
string errorMsg = string.Format("【操作信息】:{0} <br>",
new object[] { operateMsg });
errorMsg = errorMsg.Replace("\r\n", "<br>");
logger.Info(errorMsg);
}
}
5、在上面log4net中的GlobalExceptions类把
LogHelper.ErrorLog(json.Message, context.Exception)替换成如下:NLogHelp.ErrorLog(json.Message,context.Exception)即可。 运行测试如下:
【异常时间】:// ::36.786
【异常级别】:ERROR
【异常信息】:错误消息:Failed to create instance of type
at AspectCore.Injector.ServiceCallSiteResolver.ResolvePropertyInject(ServiceDefinition service)
【异常类型】:InvalidOperationException
【堆栈调用】: at AspectCore.Injector.ServiceCallSiteResolver.ResolveTypeService(TypeServiceDefinition typeServiceDefinition)
at AspectCore.Injector.ServiceCallSiteResolver.ResolvePropertyInject(ServiceDefinition service)
at System.Collections.Concurrent.ConcurrentDictionary`.GetOrAdd(TKey key, Func` valueFactory)
at AspectCore.Injector.ServiceResolver.b
自此,完美搞定,等后期我将会介绍采用ELK+NLog进行数据采集及展示,请大家拭目以待吧。
asp.net Core 交流群:787464275 欢迎加群交流
如果您认为这篇文章还不错或者有所收获,您可以点击右下角的【推荐】按钮精神支持,因为这种支持是我继续写作,分享的最大动力!
微信公众号:欢迎关注 QQ技术交流群: 欢迎加群
asp.net core添加全局异常处理及log4net、Nlog应用的更多相关文章
- aspnetcore配置log4net并添加全局异常处理
第一步:在NuGet中引用log4net 第二步:创建log4net.config <?xml version="1.0" encoding="utf-8" ...
- 学习ASP.NET Core(10)-全局日志与xUnit系统测试
上一篇我们介绍了数据塑形,HATEOAS和内容协商,并在制器方法中完成了对应功能的添加:本章我们将介绍日志和测试相关的概念,并添加对应的功能 一.全局日志 在第一章介绍项目结构时,有提到.NET Co ...
- asp.net core 教程(七)-异常处理、静态文件
Asp.Net Core-异常处理 Asp.Net Core-异常处理 在这一章,我们将讨论异常和错误处理.当 ASP.NET Core应用程序中发生错误时,您可以以各种不同的方式来处理.让我们来看看 ...
- asp.net core MVC 全局过滤器之ExceptionFilter异常过滤器(一)
本系类将会讲解asp.net core MVC中的内置全局过滤器的使用,将分为以下章节 asp.net core MVC 过滤器之ExceptionFilter异常过滤器(一) asp.net cor ...
- 插上腾飞的翅膀:为asp.net core添加protobuf支持
没时间解释了,快上车. 通过NuGet获取Zaabee.AspNetCoreProtobuf Install-Package Zaabee.AspNetCoreProtobuf 在Startup.cs ...
- ASP.NET Core 添加NLog日志支持(VS2015update3&VS2017)
1.创建一个新的ASP.NET Core项目 2.添加项目依赖 NLog.Web.AspNetCore 3.在项目目录下添加nlog.config文件: <?xml version=" ...
- Asp.net Core 添加 EF 工具并执行初始迁移错误解决方法(Add-Migration Initial---Build failed.)
1.问题: 首次在ASP.NET Core项目中使用Code First模式的Entity Framework框架,在添加EF工具并做初始化迁移(perform initial migration), ...
- Asp.net Core WebApi 全局异常类
通过全局异常类,所有程序中遇到的错误都会被拦截,并友好的返回结果. 1.自定义一个全局异常处理类中间件 using Microsoft.AspNetCore.Http; using Newtonsof ...
- 第七节:Asp.Net Core内置日志和整合NLog(未完)
一. Asp.Net Core内置日志 1. 默认支持三种输出方式:控制台.调试(底部输出窗口).EventSource,当然也可以在Program类中通过logging.ClearProviders ...
随机推荐
- php中session中的反序列
1.php 键名 + 竖线 + 经过 serialize() 函数反序列处理的值2.php_binary 键名的长度对应的 ASCII 字符 + 键名 + 经过 serialize() 函数 ...
- linq的左连接右连接内连接用法
1.左连接: var LeftJoin = from e in ListOfEmployees join d in ListOfDepartment on e.DeptID equals d.ID i ...
- windows下搭建nginx+php开发环境
windows下搭建nginx+php开发环境 1.前言 windows下大多我们都是下载使用集成环境,但是本地已经存在一个集成环境,但不适合项目的需求.因此准备再自己搭建一个环境. 2.准备 工具: ...
- Gradle Goodness: Display Available Tasks
To see which tasks are available for our build we can run Gradle with the command-line option -t or ...
- JavaScript or jQuery 获取option value值 以及文本内容的方法
1.html <div class="form-group"> <label>保险公司</label> <select class=&qu ...
- ASP.NET MVC 自动模型验证
经常看到这个代码 在controller 中写入验证模型,每个需要验证的action 都写-.. ,就问你烦不烦~ 可以利用 ASP.NET MVC 的 action 拦截机制 自动处理. 1 新建验 ...
- 为什么我们要做三份 Webpack 配置文件
时至今日,Webpack 已经成为前端工程必备的基础工具之一,不仅被广泛用于前端工程发布前的打包,还在开发中担当本地前端资源服务器(assets server).模块热更新(hot module re ...
- oracle同义词语句备份
--创建同义词create synonym T_SYSTEM_USERDEPARTMENT for xtzl.T_SYSTEM_USERDEPARTMENT;--查询同义词SELECT * FROM ...
- Objective-C 方法交换实践(三) - Aspects 源码解析
一.类与变量 AspectOptions typedef NS_OPTIONS(NSUInteger, AspectOptions) { AspectPositionAfter = 0, /// 原方 ...
- react 配置开发环境
一:先自行下载安装node和npm 二:cnpm install create-react-app -g 三:create-react-app my-project 四:cd my-project ...