在本章中,也就是整个系列的第一部分将介绍如何定制日志记录。默认日志记录仅写入控制台或调试窗口,这在大多数情况下都很好,但有时需要写入到文件或数据库,或者,您可能希望扩展日志记录的其他信息。在这些情况下,您需要知道如何更改默认日志记录。

在本章,我们将介绍以下主题:

  • 配置日志记录
  • 创建自定义日志记录
  • 使用第三方日志框架

以上主题涉及ASP.NET Core框架的Host层。

技术要求

为了演示,我们创建一个ASP.NET Core MVC应用程序。请打开控制台、shellBash终端,然后切换到工作目录,然后使用以下命令创建新的应用程序:

dotnet new mvc -n LoggingSample -o LoggingSample

Visual Studio中双击打开该项目,或者在控制台中键入以下命令用Visual Studio Code打开该项目:

cd LoggingSample code .

配置日志记录

ASP.NET Core的早期版本中(即2.0版之前的版本),日志记录是在Startup.cs配置的。之后Startup.cs文件慢慢简化,许多配置被移动到Program.csWebHostBuilder,日志记录也是在这个时候被移动到WebHostBuilder

ASP.NET Core 3.1及更高版本的程序,Program.cs文件变得更加通用,IHostBuilder将最先创建,它是引导应用启动的关键(我们将在后面详解IHostBuilder),通过IHostBuilder,我们可以创建IWebHostBuilder用以配置ASP.NET Core

public class Program {
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
} public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args).ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}

ASP.NET Core 6.0中,Microsoft引入了简化配置的迷你API(minimal API)方法。这种方法不使用Startup文件,而是将所有配置添加到Program.cs文件,如下代码段:

var builder = WebApplication.CreateBuilder(args); 

//添加服务到容器.
builder.Services.AddControllersWithViews();
var app = builder.Build();

ASP.NET Core,您可以覆盖和自定义几乎所有内容,包括日志记录。IWebHostBuilder有很多扩展方法,允许我们覆盖不同功能的默认行为。要覆盖日志记录的默认设置,我们需要使用ConfigureLogging方法。

以下代码片段显示的日志记录与上面的ConfigureWebHostDefaults()方法中配置的日志记录几乎完全相同:

Host.CreateDefaultBuilder(args).ConfigureWebHostDefaults(webBuilder =>{
webBuilder.ConfigureLogging((hostingContext, logging) => {
logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
logging.AddConsole();
logging.AddDebug();
}).UseStartup<Startup>();

使用minimal API方法,我们不再需要ConfigureLogging方法,我们可以直接使用WebApplicationBuilderLogging属性:

builder.Logging.AddConfiguration(builder.Configuration.GetSection("Logging"));
builder.Logging.AddConsole();
builder.Logging.AddDebug();

现在我们已经了解了如何配置日志记录,接下来我们看看如何自定义日志记录。

创建自定义日志记录

为了演示,我们这里创建一个小而简单的日志记录器,它能够在控制台中使用特定的日志级别对日志条目进行着色。此日志记录称为ColoredConsoleLogger,它会使用LoggerProvider创建。要指定颜色和日志级别,我们还需要添加一个配置类Configuration

在接下来的代码片段中,将分别创建这三个关键类(ConfigurationLoggerProviderLogger):

1.ColoredConsoleLoggerConfiguration

我们创建一个名为CustomLogger.cs的文件中,它与Program.cs位于同一文件夹中,我们在CustomLogger.cs中创建ColoredConsoleLoggerConfiguration,该配置类包含三个可设置的属性:LogLevelEventIdColor

public class ColoredConsoleLoggerConfiguration
{
public LogLevel LogLevel { get; set; } = LogLevel.Warning;
public int EventId { get; set; } = 0;
public ConsoleColor Color { get; set; } = ConsoleColor.Yellow;
}

2.ColoredConsoleLoggerProvider

接下来,我们需要一个提供程序来检索配置并创建实际的日志记录实例

public class ColoredConsoleLoggerProvider : ILoggerProvider
{
private readonly ColoredConsoleLoggerConfiguration _config;
private readonly ConcurrentDictionary<string, ColoredConsoleLogger> _loggers = new ConcurrentDictionary<string,ColoredConsoleLogger>(); public ColoredConsoleLoggerProvider (ColoredConsoleLoggerConfiguration config)
{
_config = config;
} public ILogger CreateLogger(string categoryName)
{
return _loggers.GetOrAdd(categoryName,name => new ColoredConsoleLogger(name, _config));
} public void Dispose()
{
_loggers.Clear();
}
}

不要忘记引入System.Collections.Concurrent

3.ColoredConsoleLogger

第三类是我们真正使用的日志记录器:

public class ColoredConsoleLogger : ILogger
{
private static readonly object _lock = new Object();
private readonly string _name;
private readonly ColoredConsoleLoggerConfiguration _config; public ColoredConsoleLogger(
string name,
ColoredConsoleLoggerConfiguration config)
{
_name = name;
_config = config;
} public IDisposable BeginScope<TState>(TState state)
{
return null;
} public bool IsEnabled(LogLevel logLevel)
{
return logLevel == _config.LogLevel;
} public void Log<TState>(
LogLevel logLevel,
EventId eventId,
TState state,
Exception exception,
Func<TState, Exception, string> formatter)
{
if (!IsEnabled(logLevel))
{
return;
} lock (_lock)
{
if (_config.EventId == 0 || _config.EventId == eventId.Id)
{
var color = Console.ForegroundColor;
Console.ForegroundColor = _config.Color;
Console.Write($"{logLevel} - ");
Console.Write($"{eventId.Id} - {_name} - ");
Console.Write($"{formatter(state, exception)}\n");
Console.ForegroundColor = color;
}
}
}
}

我们现在需要lock(锁定) 控制台的输出——这是因为控制台本身并不是真正的线程安全的,可能出现错误的着色。

完成后,我们可以将新的记录插入到Program.cs的配置中。

using LoggingSample;

builder.Logging.ClearProviders();
var config = new ColoredConsoleLoggerConfiguration
{
LogLevel = LogLevel.Information,
Color = ConsoleColor.Red
};
builder.Logging.AddProvider(new ColoredConsoleLoggerProvider(config));

首先需要向引入LoggerSample命名空间。

using LoggingSample;

如果不想使用现有的日志框架,可以清除之前添加的所有日志框架提供程序

builder.Logging.ClearProviders();

然后,我们调用AddProvider来添加ColoredConsoleLoggerProvider实例。

这里配置了不同的日志级别,您可以使用这种方法发送有关错误的电子邮件,或者将调试消息记录到别的日志接收器等等。

下图显示了日志框架的彩色输出:

在许多时候,编写自定义日志框架是没有意义的,因为已经有许多优秀的第三方日志记录框架可用,例如ELMAHlog4netNLog

下面,我们将介绍如何在ASP.NET Core中使用NLog

使用第三方日志框架NLog

NLog是最早的一款可用于ASP.NET Core的日志框架,NLog提供了一个日志记录提供程序插件,可以方便地插入ASP.NET Core。(你可以通过NuGet找到NLog

1.配置Nlog

我们需要添加一个NLog.Config配置文件,用于定义两个不同的日志记录:

  1. 所有标准消息记录在一个日志文件中;
  2. 而自定义消息记录在另一个文件中
<targets>
<!-- 标准消息 -->
<target xsi:type="File" name="allfile" fileName="C:\git\dotnetconf\001-logging\nlog-all-${shortdate}.log"
layout="${longdate}|${event-properties:item=EventId.Id}|${logger}|${uppercase:${level}}|${message} ${exception}" /> <!-- 自定义消息 -->
<target xsi:type="File" name="ownFile-web" fileName="C:\git\dotnetconf\001-logging\nlog-own-${shortdate}.log"
layout="${longdate}|${event-properties:item=EventId.Id}|${logger}|${uppercase:${level}}| ${message} ${exception}|url: ${aspnet-request-url}|action: ${aspnet-mvc-action}" /> <target xsi:type="Null" name="blackhole" />
</targets> <!-- rules to map from logger name to target -->
<rules>
<!--All logs, including from Microsoft-->
<logger name="*" minlevel="Trace" writeTo="allfile" /> <!--Skip Microsoft logs and so log only own logs-->
<logger name="Microsoft.*" minlevel="Trace" writeTo="blackhole" final="true" />
<logger name="*" minlevel="Trace" writeTo="ownFile-web" />
</rules>

2.引入NuGet包

然后我们需要NuGet添加NLogASP.NET Core包:

dotnet add package NLog.Web.AspNetCore

3.将NLogIWebHostBuilder结合使用

清除ConfigureLogging方法中的其他提供程序,使用UseNLog()方法将NLogIWebHostBuilder结合使用:

Host.CreateDefaultBuilder(args).ConfigureWebHostDefaults(webBuilder => {
webBuilder.ConfigureLogging((hostingContext,logging) => {
//清除其他提供程序
logging.ClearProviders();
logging.SetMinimumLevel(LogLevel.Trace);
}).UseNLog().UseStartup<Startup>();
});

使用minimal API看起来简单得多:

using NLog.Web; 

var builder = WebApplication.CreateBuilder(args); 

//清除其他提供程序
builder.Logging.ClearProviders();
builder.Logging.SetMinimumLevel(LogLevel.Trace);
builder.WebHost.UseNLog();

在这里,您可以根据需要添加任意多个日志记录提供程序。

回顾 & 思考

现在,让我们回顾一下本文所涵盖的内容:

  • 配置日志记录
  • 创建自定义日志记录
  • 使用第三方日志框架

思考:我们应该如何自定义应用的配置?欢迎关注下篇内容《如何自定义.NET 6.0的应用配置》。

如何定制.NET6.0的日志记录的更多相关文章

  1. 浅析Entity Framework Core2.0的日志记录与动态查询条件

    前言 Entity Framework Core 2.0更新也已经有一段时间了,园子里也有不少的文章.. 本文主要是浅析一下Entity Framework Core2.0的日志记录与动态查询条件 去 ...

  2. Log4Net异常日志记录在asp.net mvc3.0的应用

    前言 log4net是.Net下一个非常优秀的开源日志记录组件.log4net记录日志的功能非常强大.它可以将日志分不同的等级,以不同的格式,输出到不同的媒介.本文主要是简单的介绍如何在Visual ...

  3. Log4Net异常日志记录在asp.net mvc3.0的应用(转载)

    这篇博客写的很好:http://www.cnblogs.com/qianlifeng/archive/2011/04/22/2024856.html 前言 log4net是.Net下一个非常优秀的开源 ...

  4. Swift3.0服务端开发(三) Mustache页面模板与日志记录

    本篇博客主要介绍如果在Perfect工程中引入和使用Mustache页面模板与日志记录系统.Mustache页面模板类似于PHP中的smarty模板引擎或者Java中的JSTL标签.当然Mustach ...

  5. Asp.Net Core 2.0 项目实战(9) 日志记录,基于Nlog或Microsoft.Extensions.Logging的实现及调用实例

    本文目录 1. Net下日志记录 2. NLog的使用     2.1 添加nuget引用NLog.Web.AspNetCore     2.2 配置文件设置     2.3 依赖配置及调用     ...

  6. 从壹开始前后端分离【 .NET Core2.0 +Vue2.0 】框架之十 || AOP面向切面编程浅解析:简单日志记录 + 服务切面缓存

    代码已上传Github+Gitee,文末有地址 上回<从壹开始前后端分离[ .NET Core2.0 Api + Vue 2.0 + AOP + 分布式]框架之九 || 依赖注入IoC学习 + ...

  7. SpringBoot2.0 基础案例(11):配置AOP切面编程,解决日志记录业务

    本文源码 GitHub地址:知了一笑 https://github.com/cicadasmile/spring-boot-base 一.AOP切面编程 1.什么是AOP编程 在软件业,AOP为Asp ...

  8. EF Core使用SQL调用返回其他类型的查询 ASP.NET Core 2.0 使用NLog实现日志记录 CSS 3D transforms cSharp:use Activator.CreateInstance with an Interface? SqlHelper DBHelper C# Thread.Abort方法真的让线程停止了吗? 注意!你的Thread.Abort方法真

    EF Core使用SQL调用返回其他类型的查询   假设你想要 SQL 本身编写,而不使用 LINQ. 需要运行 SQL 查询中返回实体对象之外的内容. 在 EF Core 中,执行该操作的另一种方法 ...

  9. .Net Core 3.0 使用 Serilog 把日志记录到 SqlServer

    Serilog简介 Serilog是.net中的诊断日志库,可以在所有的.net平台上面运行.Serilog支持结构化日志记录,对复杂.分布式.异步应用程序的支持非常出色.Serilog可以通过插件的 ...

随机推荐

  1. Python - 本地文件读写(初级)

  2. 决策树算法一:hunt算法,信息增益(ID3)

    决策树入门 决策树是分类算法中最重要的算法,重点 决策树算法在电信营业中怎么工作? 这个工人也是流失的,在外网转移比处虽然没有特征来判断,但是在此节点处流失率有三个分支概率更大 为什么叫决策树? 因为 ...

  3. 顺利通过EMC实验(14)

  4. 使用Visual Studio查看C++类内存分布

    书上类继承相关章节到这里就结束了,这里不妨说下C++内存分布结构,我们来看看编译器是怎么处理类成员内存分布的,特别是在继承.虚函数存在的情况下. 工欲善其事,必先利其器,我们先用好Visual Stu ...

  5. 【分享】WeX5的正确打开方式(6)——数据组件初探

    本文是[WeX5的正确打开方式]系列的第6篇文章,简单介绍一下WeX5中数据组件的特性和结构形式. 数据组件的由来 上一篇 WeX5绑定机制我们实现了一个简单的记账本应用,当时所有数据都用 JSON ...

  6. 微信小程序答题,怎么设计页面渲染,答完一题,跳到下一题

    想要的效果 1.第一页只显示第一道题的内容,如图红框2.答题后,点击下一题,内容显示第二道题的内容 代码 answer.wxml <!--pages/answer/answer.wxml--&g ...

  7. C#编写一个简易的文件管理器

    编写一个简易的文件管理器,通过本次实验,练习 TreeView.ListView 和SplitContainer 控件的使用,同时熟悉 C#文件系统的操作方法以及 File 类和 Directory类 ...

  8. zookeeper操作节点代码

    package cn.hbaf.zookeeper_api; import org.apache.curator.RetryPolicy; import org.apache.curator.fram ...

  9. javascript回调地狱真的只能Promise来解决吗?js回调地狱,Promise。

    javascript的灵活在于函数可以当作函数的参数来传递,以及它的异步回调思想.但是这就带了一个很严重的问题,那就是回调次数过多,会影响代码结构,多层嵌套影响代码的可阅读性,也不便于书写. 举个例子 ...

  10. centOS一次性更新所有依赖库

    CentOS中使用yum一次性更新安装依赖库 [tom@localhost /]# sudo -s [root@localhost /]# LANG=C [root@localhost /]# yum ...