如何定制.NET6.0的日志记录
yuyutoo 2024-12-03 19:36 2 浏览 0 评论
在本章中,也就是整个系列的第一部分将介绍如何定制日志记录(系列内容查阅《玩转ASP.NET 6.0框架-序言》)。默认日志记录仅写入控制台或调试窗口,这在大多数情况下都很好,但有时需要写入到文件或数据库,或者,您可能希望扩展日志记录的其他信息。在这些情况下,您需要知道如何更改默认日志记录。
在本章,我们将介绍以下主题:
- 配置日志记录
- 创建自定义日志记录
- 使用第三方日志框架
以上主题涉及ASP.NET Core框架的Host层。
技术要求
为了演示,我们创建一个ASP.NET Core MVC应用程序。请打开控制台、shell或Bash终端,然后切换到工作目录,然后使用以下命令创建新的应用程序:
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.cs的WebHostBuilder,日志记录也是在这个时候被移动到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方法,我们可以直接使用WebApplicationBuilder的Logging属性:
builder.Logging.AddConfiguration(builder.Configuration.GetSection("Logging"));
builder.Logging.AddConsole();
builder.Logging.AddDebug();
现在我们已经了解了如何配置日志记录,接下来我们看看如何自定义日志记录。
创建自定义日志记录
为了演示,我们在这里创建一个小而简单的日志记录器,它能够在控制台中使用特定的日志级别对日志条目进行着色。此日志记录称为ColoredConsoleLogger,它会使用LoggerProvider创建。要指定颜色和日志级别,我们还需要添加一个配置类Configuration。
在接下来的代码片段中,将分别创建这三个关键类(Configuration、LoggerProvider和Logger):
1.ColoredConsoleLoggerConfiguration
我们创建一个名为CustomLogger.cs的文件中,它与Program.cs位于同一文件夹中,我们在CustomLogger.cs中创建ColoredConsoleLoggerConfiguration,该配置类包含三个可设置的属性:LogLevel、EventId和Color:
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(#34;{logLevel} - ");
Console.Write(#34;{eventId.Id} - {_name} - ");
Console.Write(#34;{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实例。
这里配置了不同的日志级别,您可以使用这种方法发送有关错误的电子邮件,或者将调试消息记录到别的日志接收器等等。
下图显示了日志框架的彩色输出:
在许多时候,编写自定义日志框架是没有意义的,因为已经有许多优秀的第三方日志记录框架可用,例如ELMAH、log4net和NLog。
下面,我们将介绍如何在ASP.NET Core中使用NLog。
使用第三方日志框架NLog
NLog是最早的一款可用于ASP.NET Core的日志框架,NLog提供了一个日志记录提供程序插件,可以方便地插入ASP.NET Core。(你可以通过NuGet找到NLog)
1.配置Nlog
我们需要添加一个NLog.Config配置文件,用于定义两个不同的日志记录:
- 所有标准消息记录在一个日志文件中;
- 而自定义消息记录在另一个文件中
<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添加NLog的ASP.NET Core包:
dotnet add package NLog.Web.AspNetCore
3.将NLog与IWebHostBuilder结合使用
清除ConfigureLogging方法中的其他提供程序,使用UseNLog()方法将NLog与IWebHostBuilder结合使用:
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的应用配置》。
相关推荐
- TCP协议原理,有这一篇就够了
-
先亮出这篇文章的思维导图:TCP作为传输层的协议,是一个软件工程师素养的体现,也是面试中经常被问到的知识点。在此,我将TCP核心的一些问题梳理了一下,希望能帮到各位。001.能不能说一说TC...
- Win10专业版无线网络老是掉线的问题
-
有一位电脑基地的用户,使用...
- 学习计算机网络需要掌握以下几方面基础知识
-
计算机基础知识操作系统:了解常见操作系统(如Windows、Linux)的基本操作和网络配置,例如如何设置IP地址、子网掩码、网关和DNS服务器等,以及如何通过命令行工具(如ping、tr...
- 网络工程师的圣经!世界级网工手绘268张图让TCP/IP直接通俗易懂
-
要把知识通俗地讲明白,真的不容易。——读者说TCP/IP从字面意义上讲,有人可能会认为TCP/IP是指TCP和IP两种协议。实际生活当中有时候也确实就是这两种协议。然而在很多情况下,它只是...
- 三分钟了解通信知识TCP与IP协议(含“通信技术”资料分享)
-
TCP/IPTCP/IP分层模型①应用层...
- 网闸与防火墙:网络安全设备的差异与应用
-
在网络安全领域,网闸(安全隔离网闸,GAP)和防火墙(Firewall)是两类重要的防护设备。尽管它们都服务于网络安全防护,但在设计理念、技术原理、安全效能及适用场景等方面存在显著差异,以下从五个维度...
- S7-300的TCP/IP通信
-
一、首先在项目中创建2个S7-300的站点;二、硬件组态中,设置合适的TCP/IP地址,在同一网段内;...
- 西门子S7-1500 PLC的 MODBUS TCP通信
-
MODBUSTCP使MODBUS_RTU协议运行于以太网,MODBUSTCP使用TCP/IP和以太网在站点间传送MODBUS报文,MODBUSTCP结合了以太网物理网络和网络标准TC...
- 系统规划与管理师新版备考必备:第7章考点思维导图解析
-
备考系统规划与管理师的小伙伴们,福利又来啦!今天为大家带来《系统规划与管理师(第2版)》第7章考点的思维导图,助你高效梳理重点,让备考更有方向!...
- TCP/IP、Http、Socket 有何区别与联系?
-
HTTP协议对应于应用层,Socket则是对TCP/IP协议的封装和应用(程序员层面上)。HTTP是应用层协议,主要解决如何包装数据。而我们平时说的最多的Socket是什么呢?实际上...
- 西门子PLC串口协议与以太网通信协议对比
-
西门子plc品牌众多,通信协议的类型就更多了,具体可分为串口协议和以太网通信协议两大类。...
- 网络编程懒人入门(十三):一泡尿的时间,快速搞懂TCP和UDP的区别
-
本文引用了作者Fundebug的“一文搞懂TCP与UDP的区别”一文的内容,感谢无私分享。1、引言...
- 程序员必备的学习笔记《TCP/IP详解(一)》
-
为什么会有TCP/IP协议在世界上各地,各种各样的电脑运行着各自不同的操作系统为大家服务,这些电脑在表达同一种信息的时候所使用的方法是千差万别。就好像圣经中上帝打乱了各地人的口音,让他们无法合作一样...
- 一文读懂TCP/IP协议工作原理和工作流程
-
简述本文主要介绍TCP/IP协议工作原理和工作流程。含义TCP/IP协议,英文全称TransmissionControlProtocol/InternetProtocol,包含了一系列构成互联网...
- 如何在 Windows 10 和 Windows 11 上重置 TCP/IP 堆栈
-
传输控制协议/Internet协议,通常称为TCP/IP,是您的WindowsPC如何与Internet上的其他设备进行通信的关键部分。但是当事情出错时会发生什么?你如何解决它?幸运的...
你 发表评论:
欢迎- 一周热门
-
-
前端面试:iframe 的优缺点? iframe有那些缺点
-
带斜线的表头制作好了,如何填充内容?这几种方法你更喜欢哪个?
-
漫学笔记之PHP.ini常用的配置信息
-
其实模版网站在开发工作中很重要,推荐几个参考站给大家
-
推荐7个模板代码和其他游戏源码下载的网址
-
[干货] JAVA - JVM - 2 内存两分 [干货]+java+-+jvm+-+2+内存两分吗
-
正在学习使用python搭建自动化测试框架?这个系统包你可能会用到
-
织梦(Dedecms)建站教程 织梦建站详细步骤
-
【开源分享】2024PHP在线客服系统源码(搭建教程+终身使用)
-
2024PHP在线客服系统源码+完全开源 带详细搭建教程
-
- 最近发表
- 标签列表
-
- mybatis plus (70)
- scheduledtask (71)
- css滚动条 (60)
- java学生成绩管理系统 (59)
- 结构体数组 (69)
- databasemetadata (64)
- javastatic (68)
- jsp实用教程 (53)
- fontawesome (57)
- widget开发 (57)
- vb net教程 (62)
- hibernate 教程 (63)
- case语句 (57)
- svn连接 (74)
- directoryindex (69)
- session timeout (58)
- textbox换行 (67)
- extension_dir (64)
- linearlayout (58)
- vba高级教程 (75)
- iframe用法 (58)
- sqlparameter (59)
- trim函数 (59)
- flex布局 (63)
- contextloaderlistener (56)