ASP.NET Core 中的日志记录
内置日志的使用
Logger 是 asp .net core 的内置 service,所以我们就不需要在ConfigureService里面注册了。同时在asp.net core 2.0版本及以后,系统已经在CreateDefaultBuilder方法里默认配置了输出到Console和Debug窗口的Logger。
.ConfigureLogging(delegate(WebHostBuilderContext hostingContext, ILoggingBuilder logging)
{
logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
logging.AddConsole();
logging.AddDebug();
})
所以我们可以Controller里面直接注入ILoggerFactory然后再创建具体的Logger。
private readonly ILogger _logger;
public HomeController(ILoggerFactory logger)
{
_logger = logger.CreateLogger<HomeController>();
}
但是还有更好的方式,Container可以直接提供一个ILogger的实例,这时候呢Logger就会使用T的名字作为日志的类别:
private readonly ILogger _logger;
public HomeController(ILogger<HomeController> logger)
{
_logger = logger;
}
然后在【Output】窗口中可以看到输出的日志:
LogDemo> info: LogDemo.Controllers.HomeController[0]
LogDemo> Return Index view
Log到Debug窗口或者Console窗口还是比较方便的,但是正式生产环境中这肯定不够用。正式环境应该Log到文件或者数据库等。接下来试下Nlog。
使用Nlog
NuGet添加 NLog.Web.AspNetCore。
<PackageReference Include="Microsoft.AspNetCore.App" />
添加配置文件
新建一个文件nlog.config(建议全部小写,linux系统中要注意), 并右键点击其属性,将其“复制到输出目录”设置为“始终复制”。文件内容如下
<?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"
internalLogLevel="info"
internalLogFile="c:\temp\internal-nlog.txt"> <!-- enable asp.net core layout renderers -->
<extensions>
<add assembly="NLog.Web.AspNetCore"/>
</extensions> <!-- the targets to write to -->
<targets>
<!-- write logs to file -->
<target xsi:type="File" name="allfile" fileName="c:\temp\nlog-all-${shortdate}.log"
layout="${longdate}|${event-properties:item=EventId_Id}|${uppercase:${level}}|${logger}|${message} ${exception:format=tostring}" /> <!-- another file log, only own logs. Uses some ASP.NET core renderers -->
<target xsi:type="File" name="ownFile-web" fileName="c:\temp\nlog-own-${shortdate}.log"
layout="${longdate}|${event-properties:item=EventId_Id}|${uppercase:${level}}|${logger}|${message} ${exception:format=tostring}|url: ${aspnet-request-url}|action: ${aspnet-mvc-action}" />
</targets> <!-- rules to map from logger name to target -->
<rules>
<!--All logs, including from Microsoft-->
<logger name="*" minlevel="Trace" writeTo="allfile" /> <!--Skip non-critical Microsoft logs and so log only own logs-->
<logger name="Microsoft.*" maxLevel="Info" final="true" />
<!-- BlackHole without writeTo -->
<logger name="*" minlevel="Trace" writeTo="ownFile-web" />
</rules>
</nlog>
<Content Update="nlog.config">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
修改Program.cs文件
添加引用 NLog.Web 和 Microsoft.Extensions.Logging。
在 .UseStartup() 后添加一句.UseNLog()。如果要禁用默认的输出框日志,可以调用
logging.ClearProviders()public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.ConfigureLogging(logging =>
{
logging.ClearProviders();
logging.SetMinimumLevel(LogLevel.Trace);
})
.UseNLog();
输出到数据库
除了把日志输出到文件之外,也可以保存到SQL Server, PostgreSQL, MySQL, Elasticsearch等。下面是保存到SQL Server的一个示例配置:
<?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"
internalLogLevel="info"
internalLogFile="d:\temp\logs\internal-nlog.txt"> <!-- enable asp.net core layout renderers -->
<extensions>
<add assembly="NLog.Web.AspNetCore"/>
</extensions> <!-- the targets to write to -->
<targets>
<!-- write logs to file -->
<target xsi:type="File" name="allfile" fileName="d:\temp\logs\all-${shortdate}.log"
layout="${longdate}|${event-properties:item=EventId_Id}|${uppercase:${level}}|${logger}|${message} ${exception:format=tostring}" /> <target name="blackhole" xsi:type="Null" /> <target name="database" xsi:type="Database" dbProvider="System.Data.SqlClient">
<connectionString>
Server=.;Database=Log;Trusted_Connection=True
</connectionString>
<commandText>
insert into dbo.Log (
Application, Logged, Level, Message,
Logger, CallSite, Exception
) values (
@Application, @Logged, @Level, @Message,
@Logger, @Callsite, @Exception
);
</commandText> <parameter name="@application" layout="Application" />
<parameter name="@logged" layout="${date}" />
<parameter name="@level" layout="${level}" />
<parameter name="@message" layout="url: ${aspnet-request-url} | action: ${aspnet-mvc-action} | ${message}" /> <parameter name="@logger" layout="${logger}" />
<parameter name="@callSite" layout="${callsite:filename=true}" />
<parameter name="@exception" layout="${exception:tostring}" />
</target>
</targets> <!-- rules to map from logger name to target -->
<rules>
<!--All logs, including from Microsoft-->
<logger name="*" minlevel="Info" writeTo="allfile" /> <!--Skip non-critical Microsoft logs and so log only own logs-->
<logger name="Microsoft.*" maxLevel="Info" final="true" />
<!-- BlackHole without writeTo -->
<logger name="*" minlevel="Info" writeTo="database" />
</rules>
</nlog>
配置简要说明
targets:用于配置输出相关内容,比如 type 属性可选项为File、Mail、Console等,用于设置输出目标,layout属性用于设置输出信息的组成元素及格式。
rules: 其实是一个“路由表”,日志是从上到下匹配的。 logger name="Microsoft." maxlevel="Info" final="true" 一句话的 final="true" 过滤掉了"Microsoft." Info级别以下的日志。全局异常中间件
除了输出日志外,可以写一个中间件来处理全局的异常。
public class GlobalErrorHandlingMiddleware
{
private readonly RequestDelegate next;
private readonly ILogger<GlobalErrorHandlingMiddleware> _logger; public GlobalErrorHandlingMiddleware(RequestDelegate next, ILogger<GlobalErrorHandlingMiddleware> logger)
{
this.next = next;
this._logger = logger;
} public async Task Invoke(HttpContext context)
{
try
{
await next(context);
}
catch (Exception ex)
{ var Request = context.Request;
///访问路径
string visit_url = Request.Path;
///URL 请求方法
string method = Request.Method.ToUpper();
///URL 请求的参数
string url_paramters = string.Empty; if (method == "GET") url_paramters = Request.QueryString.Value; if (method == "POST")
{
foreach (var item in Request.Form)
url_paramters = url_paramters + item.Key + "=" + item.Value + "&";
} ///错识信息
string err_msg = ex.Message;//ex.StackTrace; ///日志格式内容
var logs_msg = $"{visit_url}#{method}#{url_paramters}#{err_msg}"; _logger.LogError(logs_msg); var statusCode = context.Response.StatusCode; var msg = $"Status Code: {statusCode}, Message: {ex.Message}"; await HandleExceptionAsync(context, msg);
}
} private static Task HandleExceptionAsync(HttpContext context, string msg)
{
//var data = new Result { Title = "异常中间件返回", Msg = msg };
//var result = JsonConvert.SerializeObject(data);
//context.Response.ContentType = "application/json;charset=utf-8";
return context.Response.WriteAsync(msg);
}
} public static class GlobalErrorHandlingMiddlewareExtensions
{
public static IApplicationBuilder UseGlobalErrorHandlingMiddleware(
this IApplicationBuilder builder)
{
return builder.UseMiddleware<GlobalErrorHandlingMiddleware>();
}
}
集成ELK
ELK简介
ELK是三个开源软件的缩写,分别表示:Elasticsearch , Logstash, Kibana , 它们都是开源软件。现在新增了一个FileBeat,它是一个轻量级的日志收集处理工具。
- Logstash: 是动态数据收集管道,能够同时从多个来源采集数据、转换数据、然后将数据存到数据库中。
- Elastaicsearch: 分布式搜索和分析引擎,提供搜集、分析、存储数据三大功能。。
- Kibana:数据可视化Web。
- Beats: 轻量型采集器的平台,从边缘机器向 Logstash 和 Elasticsearch 发送数据。
环境快速搭建
这里使用docker-compose一键搭建ELK测试环境:
请确保已经安装Docker-compose
docker-compose --version
下载代码从 The ELK stack powered by Docker and Compose 从并运行:
git clone https://github.com/deviantony/docker-elk.git
cd docker-elk
docker-compose up -d
浏览器上访问安装服务器的ip:5601 可以打开 kibana 管理后台
- 5000: Logstash TCP input.
- 9200: Elasticsearch HTTP
- 9300: Elasticsearch TCP transport
- 5601: Kibana
修改nlog配置文件
<target xsi:type="Network"
name="ownLog-tcp"
keepConnection="false"
address="tcp://IP:5000"
layout="${longdate}|${event-properties:item=EventId_Id}|${uppercase:${level}}|${logger}|${message} ${exception:format=tostring}|url: ${aspnet-request-url}|action: ${aspnet-mvc-action}" />启动项目测试,进入 kibana 后台配置并添加 index pattern。
其他写入Elasticsearch的方法
把日志写入Elasticsearch的方法可以有多种:
- Logstash:如上面的例子。它的优势是灵活性和诸多插件,它的问题是性能以及资源消耗。
- Filebeat:轻量级的日志传输工具,可以将将日志直接传输存储到 Elasticsearch,也可经过Logstash或者Kafka/Redis。
- .Net Core logger provider:如果仅限于 .Net Core的话,可以基于Elasticsearch的 .Net Core SDK封装一个日志提供程序直接写入Elasticsearch。
参考
- Logging in ASP.NET Core
- 从头编写 asp.net core 2.0 web api 基础框架
- 内置日志、使用Nlog将日志输出到文件
- Getting started with NLog and ASP.NET Core 2
- ASP.NET Core NLog MS SQL Server PostgreSQL MySQL Elasticsearch
- NLogToDatabase
- www.elastic.co
- The ELK stack powered by Docker and Compose
- 利用Filebeat+ELK 来收集.Net Core 微服务日志
- 使用ElasticSearch,Kibana,ASP.NET Core和Docker可视化数据
- ELK构建MySQL慢日志收集平台详解
ASP.NET Core 中的日志记录的更多相关文章
- (14)ASP.NET Core 中的日志记录
1.前言 ASP.NET Core支持适用于各种内置和第三方日志记录提供应用程序的日志记录API.本文介绍了如何将日志记录API与内置提供应用程序一起使用. 2.添加日志提供程序 日志记录提供应用程序 ...
- ASP.NET Core 异常处理与日志记录
1. ASP.NET Core 异常处理与日志记录 1.1. 异常处理 1.1.1. 异常产生的原因及处理 1.1.2. ASP.NET Core中启动开发人员异常页面 1.2. 日志记录 1.2.1 ...
- 玩转ASP.NET Core中的日志组件
简介 日志组件,作为程序员使用频率最高的组件,给程序员开发调试程序提供了必要的信息.ASP.NET Core中内置了一个通用日志接口ILogger,并实现了多种内置的日志提供器,例如 Console ...
- asp.net core 系列 13 日志
一.概述 ASP.NET Core 支持适用于各种内置和第三方日志记录, 供程序的日志记录 API,本文介绍了如何将日志记录 API 与内置提供程序一起使用.对于第三方日志记录提供程序使用,文章最后有 ...
- asp.net core 集成 log4net 日志框架
asp.net core 集成 log4net 日志框架 Intro 在 asp.net core 中有些日志我们可能想输出到数据库或文件或elasticsearch等,如果不自己去实现一个 Logg ...
- Asp.Net Core中利用Seq组件展示结构化日志功能
在一次.Net Core小项目的开发中,掌握的不够深入,对日志记录并没有好好利用,以至于一出现异常问题,都得跑动服务器上查看,那时一度怀疑自己肯定没学好,不然这一块日志不可能需要自己扒服务器日志来查看 ...
- ASP.NET Core 1.0 开发记录
官方资料: https://github.com/dotnet/core https://docs.microsoft.com/en-us/aspnet/core https://docs.micro ...
- 谈谈ASP.NET Core中的ResponseCaching
前言 前面的博客谈的大多数都是针对数据的缓存,今天我们来换换口味.来谈谈在ASP.NET Core中的ResponseCaching,与ResponseCaching关联密切的也就是常说的HTTP缓存 ...
- 在 .NET Core 中使用 DiagnosticSource 记录跟踪信息
前言 最新一直在忙着项目上的事情,很久没有写博客了,在这里对关注我的粉丝们说声抱歉,后面我可能更多的分享我们在微服务落地的过程中的一些经验.那么今天给大家讲一下在 .NET Core 2 中引入的全新 ...
随机推荐
- Python 实现WC功能
GitHub仓库:https://github.com/15crmor/PAC 项目要求 基本要求 -c 统计文件字符数 (实现) -w 统计文件词数 (实现) -l 统计文件行数(实现) 扩展功能 ...
- Chrome For EBS
https://chrome.google.com/webstore/detail/oracle-ebs-r12-enablement/ekkagabmggbmpmncofhgkfigmeldifnc ...
- Java类与类之间的继承关系
Java父类与子类继承关系,调用的各种关系 示例一(子类调用父类函数): // 定义一类 A public class A { // 此方法打印一句话 public void a() { System ...
- Android SQLiteOpenHelper Sqlite数据库的创建与打开
Android Sqlite数据库是一个怎样的数据库? 答:是一种嵌入式小型设备,移动设备,的数据库,应用在穿戴设备(例如:智能手表,计算手环 等等),移动设备(例如:Android系统类型的手机 等 ...
- ASP.NET MVC 4 中Razor 视图中JS无法调试
解决方法 1.首先检查IE中这2个属性是否勾选了. 2.选择IE浏览器进行调试,调试方法有2种 A:采用debugger;的方法,如下图所示: 这时不用调试断点就会在debugger位置中命中 ...
- Javascript设计模式理论与实战:观察者模式
观察者模式主要应用于对象之间一对多的依赖关系,当一个对象发生改变时,多个对该对象有依赖的其他对象也会跟着做出相应改变,这就非常适合用观察者模式来实现.使用观察者模式可以根据需要增加或删除对象,解决一对 ...
- Alwayson--问题总结一
1. Alwayson 是否依赖于域环境? 答: 是, alwayson依赖于故障转移群集(只有在故障转移群集中的SQL Server 才能启动高可行性组功能),而故障转移群集愈依赖于域环境. 2. ...
- Sql 辅助
1.清空数据表 SELECT 'TRUNCATE TABLE '+name AS TruncateSql FROM sys.tables
- MySQL远程连接失败,MySQL远程连接出现Using password:YES错误的解决办法
相信很多实用MYSQL的朋友都遇到过这种问题,就是MySQL使用localhost能够连接成功,但是使用IP连接却出现Using password:YES或者其它的连接错误.今天就把解决方法给大家说一 ...
- 使用docker来部署asp.net core的程序
使用docker来部署asp.net core程序 暂不介绍docker是个什么东西?不知道的自己百度. 第一步安装docker: 我的docker是装在centos7系统上,windows上我的也用 ...