目录

介绍

背景

使用代码

基本的

文件中配置

跟踪(Trace)和跟踪源(TraceSource)

内置跟踪侦听器

LoggerTraceListener

Harmony中的Trace,TraceSource和Logger提供程序

兴趣点


介绍

本文介绍如何在.NET Core的组件设计中使用Trace和TraceSource。如果满足以下条件,这可能会很有用:

  1. 您已经为.NET Framework和.NET Core / .NET Standard构建了组件,并且您希望保留Trace和TraceSource。
  2. 你有使用Trace和TraceSource的第三方组件。
  3. 您正在将复杂的.NET Framework应用程序迁移到.NET Core,并且现在您不想更改跟踪和日志记录设计。
  4. 您将保持跟踪和日志记录的分离和简单。

而目标读者是那些具有.NET Framework编程经验的程序员,此处讨论的知识是.NET Core 3.0和.NET Framework 2.0的最新知识,而.NET Framework 4.8是.NET Framework的最新主要版本。

背景

在.NET Core中,默认的跟踪和日志记录已升级为ILogger <T>,并且预期通过.NET Core的依赖注入来实例化各个记录器对象。ILogger<T>可以与System.Diagnostics.TraceSource进行比较,附加的ILoggerProvider对象可以与System.Diagnostics.TraceListener进行比较。

在.NET Core编程的复杂业务的应用程序中,我发现有很少的文章是在.NET Core中使用Trace和TraceSource的,几乎所有关于ILogger<T>的文章和例子,我可以在Google上找到,它们描述了如何使用ILogger,其立即被注入到Program,Startup和Controller中,而我一直在寻找在远离Program项目的组件/程序集中使用ILogger的例子或指南。

使用代码

  • 代码示例: https://github.com/zijianhuang/TraceSourceNetCore

这些代码示例包含多个项目,每个项目代表一个简单的场景和一个技术解决方案。

基本的

代码示例:ConsoleApp0

大概您已经阅读了.NET Core和ASP.NET Core中的日志记录。日志未包含在.NET Core运行时和启动逻辑中,也未包含在控制台应用程序的脚手架代码中。要使用日志记录,需要包Microsoft.Extensions.Logging。

但是,仅此程序包不足以记录到控制台。而是使用Microsoft.Extensions.Logging.Console:

并且此软件包包括Microsoft.Extensions.Logging。

using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using System;namespace ConsoleApp0
{class Program{static void Main(string[] args){Console.WriteLine("Hello World! from console");ILogger logger;IFooService fooService;using (var serviceProvider = new ServiceCollection().AddSingleton<IFooService, FooService>().AddLogging(cfg =>{cfg.AddConsole();}).BuildServiceProvider()){logger = serviceProvider.GetService<ILogger<Program>>();fooService = serviceProvider.GetService<IFooService>();}logger.LogInformation("logger information");logger.LogWarning("logger warning");fooService.DoWork();}}public interface IFooService{void DoWork();}public class FooService : IFooService{private readonly ILogger logger;public FooService(ILogger<FooService> logger){this.logger = logger;}public void DoWork(){logger.LogInformation("Doing work.");logger.LogWarning("Something warning");logger.LogCritical("Something critical");}}
}

这是执行效果:

并且您可以通过重载AddConsole()来在代码中进行进一步的配置。

.AddLogging(cfg => { cfg.AddConsole(cfg=> cfg.DisableColors=true); })
.BuildServiceProvider())

文件中配置

代码示例:ConsoleApp1

您可能更喜欢通过外部配置文件配置组件和服务,并且通常使用appsettings.json。因此,需要包Microsoft.Extensions.Configuration.Json。

var configuration = new ConfigurationBuilder().AddJsonFile("appsettings.json", false, true).Build();ILogger logger;
IFooService fooService;using (var serviceProvider = new ServiceCollection()// thanks to // https://thecodebuzz.com/logging-in-net-core-console-application/.AddSingleton<IFooService, FooService>().AddLogging(cfg => {cfg.AddConfiguration(configuration.GetSection("Logging"));cfg.AddConsole(); }).BuildServiceProvider()){logger = serviceProvider.GetService<ILogger<Program>>();//logger = serviceProvider.GetService<ILoggerFactory>().CreateLogger<Program>(); // Factory first. This works too.fooService = serviceProvider.GetService<IFooService>();}

appsettings.json内容如下

{"Logging": {"Console": {"disableColors": false},"LogLevel": {"Default": "Information","Microsoft": "Information","ConsoleApp1.FooService": "Warning","ConsoleApp1.Program": "Debug"}}
}

提示

在阅读了appsettings.json的Logging部分之后,通过DI .NET Core运行时配置控制台记录器提供程序以及诸如“Microsoft”和“ConsoleApp1.FooService”之类的记录器。

跟踪(Trace)和跟踪源(TraceSource)

System.Diagnostics.Trace和System.Diagnostics.TraceSource设计用于分离跟踪和日志记录,并且通过附加的跟踪侦听器实现日志记录。

内置跟踪侦听器

代码示例:ConsoleAppTraceListener

.NET Framework上的许多TraceListener派生类.NET Core上可用,但是像IisTraceListener这样的类在.NET Core 上不可用。

在.NET Framework上,应用程序可以通过app.config初始化Trace和TraceSource,并实例化跟踪侦听器,app.config在执行应用程序代码的第一行之前加载。

在.NET Core上,您仍可以使用各种跟踪侦听器,例如ConsoleTraceListener,因为.NET Core默认情况下不会加载配置文件,并且内置配置不关心跟踪侦听器。

using (var listener = new TextWriterTraceListener("c:\\temp\\mylog.txt"))
using (var consoleListener = new ConsoleTraceListener())
{Trace.Listeners.Add(listener);Trace.Listeners.Add(consoleListener);

因此,您必须实例化跟踪侦听器,并在应用程序startup代码中进行初始化Trace和TraceSources对象。不错,但是事情还在继续,有越来越多的第三方组件可以与ILogger<T>接口进行跟踪和日志记录。考虑到各种因素和权衡取舍,最好在TraceSource和ILogger<T>之间架起一座桥梁,因此使用Trace和TraceSource的遗留组件可以向ILogger<T>发送跟踪消息。

LoggerTraceListener

代码示例:ConsoleAppTrace

由于Trace和TraceSource只有侦听器与日志连接,因此这里的LoggerTraceListener侦听跟踪并写入ILogger<T>,ILogger<T>最终将跟踪发送给记录提供者。

public class LoggerTraceListener : TraceListener
{private readonly ILogger logger;public LoggerTraceListener(ILogger logger){this.logger = logger;}public override void Write(string message){logger.LogInformation(message);}public override void WriteLine(string message){logger.LogInformation(message);}public override void WriteLine(string message, string category){logger.LogInformation(category + ": " + message);}public override void TraceEvent(TraceEventCache eventCache, string source, TraceEventType eventType, int id){switch (eventType){case TraceEventType.Critical:logger.LogCritical(id, source);break;case TraceEventType.Error:logger.LogError(id, source);break;case TraceEventType.Warning:logger.LogWarning(id, source);break;case TraceEventType.Information:logger.LogInformation(id, source);break;case TraceEventType.Verbose:logger.LogTrace(id, source);break;case TraceEventType.Start:logger.LogInformation(id, "Start: " + source);break;case TraceEventType.Stop:logger.LogInformation(id, "Stop: " + source);break;case TraceEventType.Suspend:logger.LogInformation(id, "Suspend: " + source);break;case TraceEventType.Resume:logger.LogInformation(id, "Resume: " + source);break;case TraceEventType.Transfer:logger.LogInformation(id, "Transfer: " + source);break;default:throw new InvalidOperationException("Impossible");}}

应用程序启动(startup):

ILogger logger;using (var serviceProvider = new ServiceCollection().AddLogging(cfg =>{cfg.AddConfiguration(configuration.GetSection("Logging"));cfg.AddConsole();}).BuildServiceProvider())
{logger = serviceProvider.GetService<ILogger<Program>>();
}logger.LogInformation("logger information");
logger.LogWarning("logger warning");using (var listener = new LoggerTraceListener(logger))
{System.Diagnostics.Trace.Listeners.Add(listener);TraceSources.Instance.InitLoggerTraceListener(listener);TraceLover.DoSomething();TraceSourceLover.DoSomething();
}

现在,Trace和TraceSource的日志介质是由哪些日志提供程序附加到ILogger决定的。

Harmony中的Trace,TraceSource和Logger提供程序

代码示例:ConsoleappSeriLog

微软在.NET Core中开发了很少的具体记录器提供程序,这很可能是根据业务愿景而设计的。周围有很多第三方记录器提供程序:

  • NLog
  • Log4net
  • Serilog

有一篇很好的文章比较了这三个:

  • NLog vs log4net vs Serilog.NET日志记录框架比较

整体上我同意Serilog是最好的。

var configuration = new ConfigurationBuilder().AddJsonFile("appsettings.json", false, true).Build();Serilog.Log.Logger = new Serilog.LoggerConfiguration().Enrich.FromLogContext()//.WriteTo.Console() I prefer plugging through the config file.ReadFrom.Configuration(configuration).CreateLogger();Microsoft.Extensions.Logging.ILogger logger;
IFooService fooService;var services = new ServiceCollection();
services.AddLogging(configure => configure.AddSerilog());using (var serviceProvider = services.AddSingleton<IFooService, FooService>().BuildServiceProvider())
{logger = serviceProvider.GetService<ILogger<Program>>();fooService = serviceProvider.GetService<IFooService>();
}try
{Log.Information("Starting up");logger.LogInformation("logger information");logger.LogWarning("logger warning");fooService.DoWork();using (var listener = new LoggerTraceListener(logger)){System.Diagnostics.Trace.Listeners.Add(listener);TraceSources.Instance.InitLoggerTraceListener(listener);TraceLover.DoSomething();TraceSourceLover.DoSomething();}
}
catch (Exception ex)
{Log.Fatal(ex, "Application start-up failed");
}
finally
{Log.CloseAndFlush();
}

appsettings.json内容如下

{"TraceSource": {"WebApi": {"SourceLevels": "Information"},"HouseKeeping": { "SourceLevels": "Warning" },"DbAudit": {"SourceLevels": "Warning"}},"Serilog": {"MinimumLevel": {"Default": "Debug","Override": {"Microsoft": "Information","System": "Warning","ConsoleApp1.FooService": "Warning","ConsoleApp1.Program": "Information"}},"WriteTo": [{"Name": "Console"},{"Name": "File","Args": {"path": "%PROGRAMDATA%/my/logs/CloudPosApi_Test.log","outputTemplate": "{Timestamp:MM-dd HH:mm:ss.fff zzz} [{Level}] {ThreadId} {Message}{NewLine}{Exception}","rollingInterval": "Day"}}]}
}

兴趣点

在.NET Framework上,运行时将在执行应用程序代码的第一行之前加载app.config并将设置应用于某些内置组件。默认情况下,其他组件(例如SMTPClient和System.Diagnostics)会读取app.config

在.NET Core上,应用程序程序员负责以代码形式或通过加载配置文件进行配置

即使我已经为.NET Core编写了几年的组件,但我刚刚开始开发复杂的.NET Core商业应用程序已有几个月了,而我绝不是精通.NET Core编程的人。请指出我在本文中可能犯的一些错误。在代码示例中,有一个有关TraceSourceLoggerProvider的示例,尚不可用。令人惊讶的是,截至2020年1月8日,TraceSourceLoggerProvider在346个Google搜索结果(实际上少于60个)中,似乎没有例子。我有一个问题,你知道如何使用TraceSourceLoggerProvider吗?

在.NET Core日志记录中使用Trace和TraceSource相关推荐

  1. 使用CDN之后APACHE日志记录中IP地址不正确的解决方案

    这篇文章主要介绍了使用CDN之后APACHE日志记录中IP地址不正确的解决方案,需要的朋友可以参考下 最近在搞APACHE日志分析,装好了awstats之后,这两天进行了观察, 报表日期 月 1 月 ...

  2. 论文系统Step1:从日志记录中提取特定信息

    论文系统Step1:从日志记录中提取特定信息 前言 论文数据需要,需要实现从服务器日志中提取出用户的特定交互行为信息.日志内容如下: 自己需要获取"请求数据包一行的信息"及&quo ...

  3. jboss7 关闭日志打印_使用自定义日志记录处理程序在JBoss AS 7中跟踪SQL语句

    jboss7 关闭日志打印 使用ORM从您的特定数据库中提取数据并让其创建和发布您必须亲自编写的所有SQL语句似乎很方便. 这就是使ORM解决方案受欢迎的原因. 但是它也有一个缺点:由于ORM为您做了 ...

  4. 使用自定义日志记录处理程序在JBoss AS 7中跟踪SQL语句

    使用ORM从您的特定数据库中提取数据,并让它创建和发布您必须亲自编写的所有SQL语句似乎很方便. 这就是使ORM解决方案受欢迎的原因. 但是它也有一个缺点:由于ORM为您做了很多工作,因此您在某种程度 ...

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

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

  6. 基于.NetCore3.1系列 —— 日志记录之自定义日志组件

    前言 回顾:日志记录之日志核心要素揭秘 在上一篇中,我们通过学习了解在.net core 中内置的日志记录中的几大核心要素,在日志工厂记录器(ILoggerFactory)中实现将日志记录提供器(IL ...

  7. ASP.NET Core 日志框架:Serilog

    在 ASP.NET Core 日志模型 中对日志整体实现方式进行了介绍,通过使用内置日志记录器来实现日志的输出路径.而在实际项目开发中,使用第三方日志框架来记录日志也是非常多的,首先一般基础的内置日志 ...

  8. ASP.NET MVC的最佳日志记录库

    目录 介绍 4个日志记录库 log4net Log4net记录文本文件中 Log4net记录到数据库中 NLOG Nlog日志记录在文本文件中 NLog日志记录到数据库中 Serilog Serilo ...

  9. Entity Framework Core系列教程-25-Entity Framework Core日志

    Entity Framework Core日志 我们经常需要在EF Core中记录SQL并更改跟踪信息以进行调试. EF Core日志记录自动与.NET Core的日志记录机制集成.因此,在隐含使用E ...

最新文章

  1. 八年级计算机网络公开课,计算机网络公开课教案.doc
  2. 字符串string类的使用:回文
  3. XE3随笔6:SuperObject 的 JSON 对象中还可以包含 方法
  4. 基站基带fgpa 服务器芯片,基于FPGA的AIS基带数据处理芯片设计
  5. springboot 多数据源 读写分离 AOP方式
  6. super(Net,self).__init__() 的含义
  7. android unity 关闭应用_Unity 之 唤起调用 Android 其它应用app的方法
  8. 【连载】【FPGA黑金开发板】NIOS II那些事儿--LED实验(四)
  9. [Ext JS] Sencha Cmd命令参考之二
  10. 20162314 Experiment 3 - Sorting and Searching
  11. 俄罗斯方块、纯前端实现俄罗斯方块、俄罗斯方块代码
  12. 创翼软件linux版本,创翼客户端_创翼客户端下载[2021官方最新版]创翼客户端安全下载_ 极速下载...
  13. python蒙特卡洛_Python:从零开始的汉密尔顿蒙特卡洛
  14. Android 10.0 Launcher3 抽屉式(双层)app列表排序
  15. Android WebView点击返回键回到上一个html
  16. java使用poi操作world生成饼图,柱状图,折线图,组合图:一
  17. 计算机网络(四)——组建对等网
  18. VMware Workstation pro无法在Windows上运行,检查可在Windows上运行的此应用的更新版本(无需卸载原先版本或原先版本卸载的按钮变成灰色)
  19. KDD 2021 | 推荐系统论文集锦[持续更新]
  20. 用U盘给macbook 安装windows系统

热门文章

  1. 天线越大越好吗_无线路由知识误区!解读天线数量与信号强弱的关系
  2. python 依赖包管理_依赖管理
  3. PNG免扣艺术字体素材|为年货季准备好了么?
  4. 平面/UI设计师社区交流网站集设|给你的作品多一个展示机会
  5. 精选素材模板丨极简风简历模板
  6. 高端中餐美食餐饮海报PSD模板,看着就有食欲
  7. linux php没有bin,php - 执行Linux命令没有报错但也没有输出
  8. 计算机一级windows系统操作知识点,计算机一级考试:高分必看知识点之windows操作...
  9. vmware磁盘扩容_CentOS7扩容分区(LVM)
  10. java拥有键值对的数据结构_Java数据结构之004--HashMap