.NET Core WebAPI中MEF日志跟踪的等效配置方案咨询
.NET Core WebAPI 实现MEF日志/跟踪功能的方案
你之前配置不生效的核心原因有2个:
- .NET Core 环境下官方MEF实现的跟踪源名称为
Microsoft.Composition,和.NET Framework中的System.ComponentModel.Composition不一致,过滤器规则匹配不到日志 AddTraceSource("All")的用法不符合要求,该方法需要传入已配置好监听器的SourceSwitch实例,仅传入级别字符串不会自动绑定控制台或文件输出
具体实现方案
前置依赖
首先安装必要的NuGet包:
Microsoft.Extensions.Logging.TraceSource:用于对接.NET Core日志系统与TraceSource- 若使用文件输出,可选安装
Serilog.AspNetCore、Serilog.Sinks.File实现更灵活的日志滚动策略
方案1:沿用.NET Framework风格的TraceSource配置(最接近原有逻辑)
直接为TraceSource添加控制台和文件监听器,和原有Framework配置效果完全一致:
public class Program { public static void Main(string[] args) { CreateWebHostBuilder(args).Build().Run(); } public static IWebHostBuilder CreateWebHostBuilder(string[] args) => WebHost.CreateDefaultBuilder(args) .ConfigureAppConfiguration((hostingContext, config) => { config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) .AddEnvironmentVariables(); }) .ConfigureLogging((hostingContext, logging) => { logging.ClearProviders(); // 同时兼容.NET Core版MEF和兼容包版MEF的源名称 logging.AddFilter("Microsoft.Composition", LogLevel.Trace); logging.AddFilter("System.ComponentModel.Composition", LogLevel.Trace); // 配置TraceSource开关和监听器 var mefTraceSwitch = new SourceSwitch("MEFTraceSwitch", "All"); // 添加控制台输出 mefTraceSwitch.Listeners.Add(new ConsoleTraceListener()); // 添加文件输出,对应原有配置的composition.log mefTraceSwitch.Listeners.Add(new TextWriterTraceListener("composition.log") { TraceOutputOptions = TraceOptions.DateTime | TraceOptions.ThreadId }); logging.AddTraceSource(mefTraceSwitch); // 对应原有配置的autoflush和indentsize Trace.AutoFlush = true; Trace.IndentSize = 4; }) .UseStartup<Startup>(); }
方案2:使用Serilog实现灵活的日志输出
如果需要日志滚动、结构化输出等能力,推荐使用Serilog实现:
- 安装NuGet包:
Serilog.AspNetCore、Serilog.Sinks.Console、Serilog.Sinks.File - .NET 6+ 顶级语句配置示例:
var builder = WebApplication.CreateBuilder(args); // 配置Serilog,仅过滤MEF相关日志输出 Log.Logger = new LoggerConfiguration() .MinimumLevel.Verbose() .Filter.ByIncludingOnly(logEvent => { if (logEvent.Properties.TryGetValue("SourceContext", out var sourceContext)) { var sourceName = sourceContext.ToString(); return sourceName.Contains("Microsoft.Composition") || sourceName.Contains("System.ComponentModel.Composition"); } return false; }) .WriteTo.Console() .WriteTo.File("logs/composition_.log", rollingInterval: RollingInterval.Day, retainedFileCountLimit: 30) .CreateLogger(); builder.Host.UseSerilog(); // 注册其他服务、配置中间件逻辑... var app = builder.Build(); app.Run();
注意事项
- 如果你使用的是
System.ComponentModel.Composition的兼容移植包,仅保留对应源名称的过滤规则即可 - 若调试时仍无输出,可以暂时移除日志过滤规则,确认是否是日志级别过高导致的日志被拦截
内容的提问来源于stack exchange,提问作者Dend
相关产品推荐
相关产品推荐

