概述

调试asp.net core程序时,在输出窗口中,在输出来源选择“调试”或“xxx-ASP.NET Core Web服务器”时,可以看到类似“info:Microsoft.AspNetCore.Hosting.Internal.WebHost[2] Request finished in 285.6ms 200 text/css”这样的内容,这就是asp.net core的日志。如果出现了未捕获的异常,在输出窗口中可以看到出错信息,如:fail: Microsoft.AspNetCore.Server.Kestrel[13]……An unhandled exception was thrown by the application. System.NullReferenceException: 未将对象引用设置到对象的实例。在……行号 xx 在……行号 xx。在网站运行过程中,如果可以把这些出错信息保存下来,就可以排查代码错误了。方法很简单:把web.config文件中aspNetCore标签的stdoutLogEnabled属性设置为true,这样,在网站运行后,默认会在/logs文件夹下产生一个stdout_xxx_xxx.log的文件,日志会保存到这里面。

logging provider

从名称“stdoutLogEnabled”来看,stdout,表示“标准输出”,即控制台输出。试着写一句Console.WriteLine(xxx),在.log文件中果然就可以看到输出的内容。如果是在调试环境,可以在输出窗口/ASP.NET Core Web服务器看到Console输出的内容。asp.net core mvc项目代码模板默认添加了三个logging provider:Console、Debug、EventSource。VS的输出窗口/ASP.NET Core Web服务器,显示的就是Console这个logging provider输出的内容,而输出窗口/调试,显示的是Debug的。所以,stdout_xxx_xxx.log文件,保存的就是Console logging provider输出的日志。

观察VS的输出窗口,可以发现,同一条日志内容,Console和Debug这两个logging provider的输出格式是不同的。

日志级别

ASP.NET Core定义了几个日志级别,表示日志的严重程度,从低到高分别是Trace 、Debug 、Information 、Warning 、Error 、Critical 。

下面是一条Debug级别的日志:

dbug: Microsoft.AspNetCore.Mvc.ModelBinding.ParameterBinder[27]
Done attempting to validate the bound parameter 'page' of type 'System.Int32'.

一条Information级别的日志:

info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[1]
Executing action method XXX.Controllers.YYYController.GetList (XXX) with arguments (8d35e231-c928-479e-95d4-b305a6a235eb, 1, 15, 1) - Validation state: Valid

在生产环境下,日志一般仅用于错误排查,所以用不到Information 等级别的大量日志,为此,可以设置一个最低日志级别,比如设置成Warning,将屏蔽Trace 、Debug 、Information级别的日志。最低日志级别可以给每个logging provider分别设置,如果没有具体设置,将采用默认设置。如,设置默认日志级别为Information:

"Logging": {
"LogLevel": {
"Default": "Information"
}
}

分别设置Debug、Console的日志级别:

  "Logging": {
"Debug": {
"LogLevel": {
"Default": "Information"
}
},
"Console": {
"LogLevel": {
"Default": "Debug"
}
},
"LogLevel": {
"Default": "Debug"
}
},

为什么针对具体的logging provider也标上"Default"?因为可以再针对日志的Log category分别设置:

  "Logging": {
"Console": {
"LogLevel": {
"Microsoft.AspNetCore.Mvc.Razor.Internal": "Warning",
"Microsoft.AspNetCore.Mvc.Razor.Razor": "Debug",
"Microsoft.AspNetCore.Mvc.Razor": "Error",
"Default": "Information"
}
},
"LogLevel": {
"Default": "Debug"
}
}

关于Log category的概念请自行查阅官方文档,不再赘述。

值得注意的时,在网站运行状态下,修改appsettings.json中的上述配置,不会造成网站重启(而修改web.config会造成网站重启),但对日志级别的控制会立即生效。所以,在网站运行不正常时,可以临时调低日志级别,以查看更多调试信息,又不会影响用户的使用。平时可以设置一个较高的日志级别,比如Error或Critical。而web.config中的stdoutLogEnabled属性要提前设置好。

输出自己的日志

可以输出自己的日志。用依赖注入的方式,注入ILogger<T>对象,然后用LogInformation()、LogWarning()等方法可以方便的输出对应级别的日志。

示例代码:

    public class HomeController : Controller
{
ILogger<HomeController> _logger; public HomeController(ILogger<HomeController> logger)
{
_logger = logger;
} public IActionResult Index()
{
_logger.LogInformation("访问主页");
try
{
int i = 0;
int j = 1 / i;
}
catch (Exception ex)
{
_logger.LogWarning($"发生异常了:{ex.Message},调用堆栈:{ex.StackTrace}");
}
throw new Exception("这是一个测试错误"); return View();
}
}

产生的部分日志(级别设置为Information):

info: CommonCoreMvcTest.Controllers.HomeController[0]
访问主页
warn: CommonCoreMvcTest.Controllers.HomeController[0]
发生异常了:尝试除以零。,调用堆栈: 在 CommonCoreMvcTest.Controllers.HomeController.Index() 位置 E:\xxx\Test\CommonCoreMvcTest\Controllers\HomeController.cs:行号 28
fail: Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware[1]
An unhandled exception has occurred while executing the request.
System.Exception: 这是一个测试错误
在 CommonCoreMvcTest.Controllers.HomeController.Index() 位置 E:\xxx\Test\CommonCoreMvcTest\Controllers\HomeController.cs:行号 36
在 lambda_method(Closure , Object , Object[] )
在 Microsoft.AspNetCore.Mvc.Internal.ActionMethodExecutor.SyncActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
在 Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.<InvokeActionMethodAsync>d__12.MoveNext()
--- 引发异常的上一位置中堆栈跟踪的末尾 ---
……

添加web.config到源代码项目中

新建的asp.net core 2.2项目,默认没有web.config文件。得在网站发布后才能修改产生的web.config文件内容吗?没必要,可以通过“添加”、“新建项”、“Web配置文件”的方式,手动添加web.config文件到源码项目中。

使日志包含时间

asp.net core的日志不包含时间,这是个大问题,在3.0版本后,Console log provider可以配置时间格式了。经过搜索,我发现一个好用的第三方log provider:LoggingAdvanced.Console。可以用它来取代Console log provider。具体步骤如下:

1、安装nuget包LoggingAdvanced.Console

2、修改Program.cs的CreateWebHostBuilder方法,在其中的方法调用链的最后,调用ConfigureLogging方法,修改后的代码如下:

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.ConfigureLogging((hostingContext, loggingBuilder) =>
{
loggingBuilder.ClearProviders();//清除所有logging provider loggingBuilder.AddDebug();//恢复添加Debug logging provider loggingBuilder.AddEventSourceLogger();//恢复添加EventSource logging provider var loggingSection = hostingContext.Configuration.GetSection("Logging"); loggingBuilder.AddConsoleAdvanced(loggingSection);//添加LoggingAdvanced.Console logging provider
});

3、修改appsettings.json的中的Logging部分,修改后如下:

"Logging": {
"IncludeTimestamp": true,
"IncludeLogNamespace": true,
"TimestampPolicy": {
"TimeZone": "Ulaanbaatar Standard Time",
"Format": "yyyy/MM/dd HH:mm:ss.fff"
},
"LogLevel": {
"Default": "Warning"
}
}

输出的部分日志:

[2020.03.07 22:39:36] info: HomeController: 访问主页
[2020.03.07 22:39:36] warn: HomeController: 发生异常了:尝试除以零。,调用堆栈: 在 CommonCoreMvcTest.Controllers.HomeController.Index() 位置 E:\xxx\Test\CommonCoreMvcTest\Controllers\HomeController.cs:行号 28
[2020.03.07 22:39:36] fail: ExceptionHandlerMiddleware[1]: An unhandled exception has occurred while executing the request.
System.Exception: 这是一个测试错误
在 CommonCoreMvcTest.Controllers.HomeController.Index() 位置 E:\xxx\Test\CommonCoreMvcTest\Controllers\HomeController.cs:行号 36
在 lambda_method(Closure , Object , Object[] )
在 Microsoft.AspNetCore.Mvc.Internal.ActionMethodExecutor.SyncActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
在 Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.<InvokeActionMethodAsync>d__12.MoveNext()
……

技巧

用浏览器查看.log文件,日志有更新,刷新一下就好了。

参考资料

1、Logging in .NET Core and ASP.NET Core

2、LoggingAdvanced.Console

总结:利用asp.net core日志进行生产环境下的错误排查(asp.net core version 2.2,用IIS做服务器)的更多相关文章

  1. Python开发程序:生产环境下实时统计网站访问日志信息

    日志实时分析系统 生产环境下有需求:要每搁五分钟统计下这段时间内的网站访问量.UV.独立IP等信息,用直观的数据表格表现出来 环境描述: 网站为Nginx服务,系统每日凌晨会对日志进行分割,拷贝到其他 ...

  2. Python开发【项目】:生产环境下实时统计网站访问日志信息

    日志实时分析系统 生产环境下有需求:要每搁五分钟统计下这段时间内的网站访问量.UV.独立IP等信息,用直观的数据表格表现出来 环境描述: 网站为Nginx服务,系统每日凌晨会对日志进行分割,拷贝到其他 ...

  3. 四步法分析定位生产环境下MySQL上千条SQL中的问题所在

    第一步:通过以下两种方式之一来打开慢查询功能 (1)方式一:通过修改mysql的my.cnf文件 如果是5.0或5.1等版本需要增加以下选项: log-slow-queries="mysql ...

  4. 生产环境下JAVA进程高CPU占用故障排查

    问题描述:生产环境下的某台tomcat7服务器,在刚发布时的时候一切都很正常,在运行一段时间后就出现CPU占用很高的问题,基本上是负载一天比一天高. 问题分析:1,程序属于CPU密集型,和开发沟通过, ...

  5. 生产环境下JAVA进程高CPU占用故障排查---temp

    问题描述:生产环境下的某台tomcat7服务器,在刚发布时的时候一切都很正常,在运行一段时间后就出现CPU占用很高的问题,基本上是负载一天比一天高. 问题分析:1,程序属于CPU密集型,和开发沟通过, ...

  6. 生产环境下,MySQL大事务操作导致的回滚解决方案

    如果mysql中有正在执行的大事务DML语句,此时不能直接将该进程kill,否则会引发回滚,非常消耗数据库资源和性能,生产环境下会导致重大生产事故. 如果事务操作的语句非常之多,并且没有办法等待那么久 ...

  7. 生产环境下,oracle不同用户间的数据迁移。第三部分

    任务名称:生产环境下schema ELON数据迁移至schema TIAN########################################前期准备:1:确认ELON用户下的对象状态se ...

  8. Java生产环境下性能监控与调优详解视频教程 百度云 网盘

    集数合计:9章Java视频教程详情描述:A0193<Java生产环境下性能监控与调优详解视频教程>软件开发只是第一步,上线后的性能监控与调优才是更为重要的一步本课程将为你讲解如何在生产环境 ...

  9. 生产环境下一定要开启mysqlbinlog

    在没有备份数据库的情况下,可以用binlog进行恢复 在生产环境下安全第一,损失一点点效率换来的安全还是值得的. http://www.cnblogs.com/zc22/archive/2013/06 ...

随机推荐

  1. 计算a^b==a+b在(l,r)的对数Codeforces Round #597 (Div. 2)

    题:https://codeforces.com/contest/1245/problem/F 分析:转化为:求区间内满足a&b==0的对数(解释见代码) ///求满足a&b==0在区 ...

  2. QQ消息群发助手(超级简单)

    大家好!我开发的小工具,效果见动图: 下载地址 QQ群发助手.rar 代码: def Login(): global Flag try: bot.Login(['-q',v1.get()]) tkin ...

  3. WAIC | 奇点云携「酷炫AI应用」亮相2019世界人工智能大会

    你是否还在疑惑“人工智能可否改变世界?” 那么,你该有一些危机感了. 机器视觉.自然语言处理.智能语音.机器人问诊.智慧驾驶……这些AI技术及应用早已渗入了我们日常生活的点滴. 29日,以「智联世界, ...

  4. python语法基础-面向对象-进阶-长期维护

    ###############    @property定义属性    ############## # 所以对于定义属性你有好几种方式了和种类了,# 静态属性,动态属性, # property # ...

  5. jquery框架概览(二)

    (function(window, undefined) { })(window) window对象作为参数传进闭包的好处 JavaScript 全局对象.函数以及变量均自动成为 window 对象的 ...

  6. 深入JVM内核--常用JVM配置参数

    Trace跟踪参数 -verbose:gc -XX:+printGC 可以打印GC的简要信息 [GC 4790K->374K(15872K), 0.0001606 secs] [GC 4790K ...

  7. C++逆序输出字符串

    使用库函数 //使用库函数 #include <iostream> #include <string> #include <algorithm> using nam ...

  8. mvn测试常用命令

    -Dmaven.test.failure.ignore=true  测试报错忽略 例子: mvn package -DAPP_ENV=dev -Dmaven.test.failure.ignore=t ...

  9. motionbuilder安装未完成,某些产品无法安装的解决方法

    motionbuilder提示安装未完成,某些产品无法安装该怎样解决呢?,一些朋友在win7或者win10系统下安装motionbuilder失败提示motionbuilder安装未完成,某些产品无法 ...

  10. CAD卸载/完美解决安装失败/如何彻底卸载清除干净cad各种残留注册表和文件的方法

    在卸载cad重装CAD时发现安装失败,提示是已安装或安装失败.这是因为上一次卸载后没有清理干净,系统会误认为已经安装过了.有的同学是新装的系统也会出现安装失败的情况,这是因为C++ 或者.NET的原因 ...