内置日志的使用

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

  1. NuGet添加 NLog.Web.AspNetCore

    <PackageReference Include="Microsoft.AspNetCore.App" />
  2. 添加配置文件

    新建一个文件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>
  3. 修改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();
  4. 输出到数据库

    除了把日志输出到文件之外,也可以保存到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>
  5. 配置简要说明

    targets:用于配置输出相关内容,比如 type 属性可选项为File、Mail、Console等,用于设置输出目标,layout属性用于设置输出信息的组成元素及格式。

    rules: 其实是一个“路由表”,日志是从上到下匹配的。 logger name="Microsoft." maxlevel="Info" final="true" 一句话的 final="true" 过滤掉了"Microsoft." Info级别以下的日志。

  6. 全局异常中间件

    除了输出日志外,可以写一个中间件来处理全局的异常。

    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

  1. ELK简介

    ELK是三个开源软件的缩写,分别表示:Elasticsearch , Logstash, Kibana , 它们都是开源软件。现在新增了一个FileBeat,它是一个轻量级的日志收集处理工具。

    • Logstash: 是动态数据收集管道,能够同时从多个来源采集数据、转换数据、然后将数据存到数据库中。
    • Elastaicsearch: 分布式搜索和分析引擎,提供搜集、分析、存储数据三大功能。。
    • Kibana:数据可视化Web。
    • Beats: 轻量型采集器的平台,从边缘机器向 Logstash 和 Elasticsearch 发送数据。

  2. 环境快速搭建

    这里使用docker-compose一键搭建ELK测试环境:

    1. 请确保已经安装Docker-compose

      docker-compose --version
    2. 下载代码从 The ELK stack powered by Docker and Compose 从并运行:

      git clone https://github.com/deviantony/docker-elk.git
      cd docker-elk
      docker-compose up -d
    3. 浏览器上访问安装服务器的ip:5601 可以打开 kibana 管理后台

      • 5000: Logstash TCP input.
      • 9200: Elasticsearch HTTP
      • 9300: Elasticsearch TCP transport
      • 5601: Kibana
  3. 修改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。

  4. 其他写入Elasticsearch的方法

    把日志写入Elasticsearch的方法可以有多种:

    • Logstash:如上面的例子。它的优势是灵活性和诸多插件,它的问题是性能以及资源消耗。
    • Filebeat:轻量级的日志传输工具,可以将将日志直接传输存储到 Elasticsearch,也可经过Logstash或者Kafka/Redis。
    • .Net Core logger provider:如果仅限于 .Net Core的话,可以基于Elasticsearch的 .Net Core SDK封装一个日志提供程序直接写入Elasticsearch。

参考

ASP.NET Core 中的日志记录的更多相关文章

  1. (14)ASP.NET Core 中的日志记录

    1.前言 ASP.NET Core支持适用于各种内置和第三方日志记录提供应用程序的日志记录API.本文介绍了如何将日志记录API与内置提供应用程序一起使用. 2.添加日志提供程序 日志记录提供应用程序 ...

  2. ASP.NET Core 异常处理与日志记录

    1. ASP.NET Core 异常处理与日志记录 1.1. 异常处理 1.1.1. 异常产生的原因及处理 1.1.2. ASP.NET Core中启动开发人员异常页面 1.2. 日志记录 1.2.1 ...

  3. 玩转ASP.NET Core中的日志组件

    简介 日志组件,作为程序员使用频率最高的组件,给程序员开发调试程序提供了必要的信息.ASP.NET Core中内置了一个通用日志接口ILogger,并实现了多种内置的日志提供器,例如 Console ...

  4. asp.net core 系列 13 日志

    一.概述 ASP.NET Core 支持适用于各种内置和第三方日志记录, 供程序的日志记录 API,本文介绍了如何将日志记录 API 与内置提供程序一起使用.对于第三方日志记录提供程序使用,文章最后有 ...

  5. asp.net core 集成 log4net 日志框架

    asp.net core 集成 log4net 日志框架 Intro 在 asp.net core 中有些日志我们可能想输出到数据库或文件或elasticsearch等,如果不自己去实现一个 Logg ...

  6. Asp.Net Core中利用Seq组件展示结构化日志功能

    在一次.Net Core小项目的开发中,掌握的不够深入,对日志记录并没有好好利用,以至于一出现异常问题,都得跑动服务器上查看,那时一度怀疑自己肯定没学好,不然这一块日志不可能需要自己扒服务器日志来查看 ...

  7. ASP.NET Core 1.0 开发记录

    官方资料: https://github.com/dotnet/core https://docs.microsoft.com/en-us/aspnet/core https://docs.micro ...

  8. 谈谈ASP.NET Core中的ResponseCaching

    前言 前面的博客谈的大多数都是针对数据的缓存,今天我们来换换口味.来谈谈在ASP.NET Core中的ResponseCaching,与ResponseCaching关联密切的也就是常说的HTTP缓存 ...

  9. 在 .NET Core 中使用 DiagnosticSource 记录跟踪信息

    前言 最新一直在忙着项目上的事情,很久没有写博客了,在这里对关注我的粉丝们说声抱歉,后面我可能更多的分享我们在微服务落地的过程中的一些经验.那么今天给大家讲一下在 .NET Core 2 中引入的全新 ...

随机推荐

  1. underscore functions

    // 创建一个用于设置prototype的公共函数对象 var ctor = function() {}; 1..bind(function, object, [*arguments]) :绑定fun ...

  2. REST格式

    首先要明确一点:REST 实际上只是一种设计风格,它并不是标准.(所以你可以看到网上一大堆的各种最佳实践,设计指南,但是没有人说设计标准).aisuhua/restful-api-design-ref ...

  3. Delphi for iOS开发指南(8):在iOS应用程序中使用Tab组件来显示分页

    Delphi for iOS开发指南(8):在iOS应用程序中使用Tab组件来显示分页 在FireMonkey iOS应用程序中的Tab Tab由FMX.TabControl.TTabControl定 ...

  4. web中浏览PDF文件

    1.在web中浏览pdf文件. 2.支持大多数主流浏览器,包括IE8 3.参考网址: https://pdfobject.com/ http://mozilla.github.io/pdf.js/ & ...

  5. ASP.NET Core使用Elasticsearch记录NLog日志

    ASP.NET Core使用Elasticsearch记录NLog日志 1.新建一个 ASP.NET Core项目 2.安装Nuge包 运行:Install-Package NLog.Web.AspN ...

  6. 使用libxml2进行xml开发(一)

    (一)Windows下使用MinGW和Code::Blocks环境配置libxml2 笔者此次是在windows 7下使用MinGW和Code::Blocks开发C程式的,手上的一个项目需要使用soc ...

  7. Python3.5 学习九

    进程与线程 线程(Thread)是计算机运算调度的最小单位,它存在于进程中,是实际运作单位.每个进程都可能并发多线程. 每一个程序的内存是独立的. 线程:是操作系统最小的运算调度单位,是一串指令的集合 ...

  8. 【JS深入学习】——函数创建和重载

    今天做一个关注/取消的功能,由于需要向后台发送请求,想通过控制用户点击发送的频次减少不必要的请求,即在一定时间内,用户点击多次但只发送一次数据,自然而然想到了使用[函数节流]. function th ...

  9. 记一次使用SecureCRT连接局域网巨慢的问题

    环境:Win7 32bit + SecureCRT 6.5 中文 使用工作机上的SecureCRT登录公司内网的跳板机,发现很慢,每次都得等待好几分钟才弹出输出私匙密码的框.咨询了一下其他同事,发现他 ...

  10. iOS完全自学手册——[三]Objective-C语言速成,利用Objective-C创建自己的对象

    1.前言 上一篇已经介绍了App Delegate.View Controller的基本概念,除此之外,分别利用storyboard和纯代码创建了第一个Xcode的工程,并对不同方式搭建项目进行了比较 ...