内置日志的使用

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. EBS trace分析

    下载Trace Analyzer,打开bin下的traceanalyzer.bat 即可分析EBS的trace文件,图形化界面,无需tkprof 需要配置javahome,确认java版本为1.6以上 ...

  2. Java面向接口编程【精品博客】

    我们从生活中去理解面向接口编程,以下举例四个案例来理解: 案例一(汽车案例): /** * 汽车标准接口 * @author Liudeli */ public interface ICar { /* ...

  3. TFS 2017 培训 - 北京某银行科技部Java研发团队

    今天受邀和微软公司的朋友一起,为北京某银行科技部的两个Java研发团队做了一场TFS系统的技术培训. 按照需求分析>开发>编译>发布>测试的流程为研发团队做了全流程的介绍. 这 ...

  4. python 检索一个目录下所有的txt文件,并把文件改为.log

    检索一个目录及子目录下所有的txt文件,并把txt文件后缀改为log: import os f_path = r'C:\Users\PycharmProjects\mystudy\Testfolder ...

  5. 《JavaScript》高级程序设计第7章 函数表达式

    7.2 闭包 定义: 闭包是指有权访问另一个函数作用域中的变量的函数. 理解闭包: 作用域链: 当某个函数被调用时,会创建一个执行环境以及相应的作用域链. 作用域链中,外部函数的活动对象始终处于第二位 ...

  6. 全球第一开源云ERP Odoo操作手册 模块安装和界面汉化指南

    之前介绍了odoo的安装和初始设置以及数据库,下面来介绍odoo的模块安装和界面汉化. 1.4 模块安装和界面汉化 Odoo 的功能包含在不同的模块中, 刚创建的数据库除 Odoo 的核心模块外, 其 ...

  7. Android的基础知识

    一.adb 的简单命令 1. adb devices  :   连接当前手机的设备 2.adb kill-server : 杀死当前的adbmingling 3.adb start-server : ...

  8. Ubuntu16.04 - 安装Courier New字体

    这应该是一个很简单的任务吧?网上很多地方告诉我们,只要在shell终端里面执行命令:"sudo apt-get installttf-mscorefonts-installer"就 ...

  9. 内置装饰器二:@property

    property 装饰器的作用 property 装饰器将方法包装成属性,将私有属性公有化,此属性只能被读取.相当于实现get方法的对象 class People: def __init__(self ...

  10. AUTO Uninstaller 双击没有反应,AU_CN点击打不开的解决办法

    AUTO Uninstaller 双击没有反应,AU_CN点击打不开的解决办法 https://pan.baidu.com/s/1cKqdxq0T0DqYfAEkiwuJbw