c# - NLog 写入 .Net Core 3.1 中的多个日志
问题描述
我必须编写一个文件实用程序来读取导入文件和创建导出文件。我正在寻找写入不同的 NLog 文件,具体取决于我是使用导入文件还是创建导出文件。我今天一直在搜索和阅读不同的文章,但我要么没有搜索正确的东西,我只是不明白如何使用依赖注入写入不同的日志文件。
这是我正在努力解决的基本概念。我运行一个控制台应用程序,它使用 JSON 文件读取文件设置列表。该文件设置/配置 JSON 文件将有一个设置,让我知道这是一个出站文件与一个入站文件。因此,假设我正在使用的当前文件是一个出站文件,我会将它的日志记录写入我的 OutboundFiles.log 与我的 InboundFiles.log。
目前,我将以下内容与我创建的大多数 .Net Core 控制台应用程序一起使用,它将使用 _log 将其写入单个日志文件(例如:_log.LogInformation)。我不明白的是,我怎么能说一个 _logOutbound.LogInformation 和一个 _logInbound.LogInformation ,这取决于我正在使用的文件时间以及我将如何更改不同日志的 NLog.config 文件名称和目录。这是我当前用于写入单个文件的代码。
程序.cs
public class Program
{
static void Main(string[] args)
{
var logger = NLog.Web.NLogBuilder.ConfigureNLog("nlog.config").GetCurrentClassLogger();
try
{
logger.Debug("Initializing Program.Main");
var host = Host.CreateDefaultBuilder()
.ConfigureAppConfiguration((hostingContext, config) =>
{
config.SetBasePath(Path.Combine(AppContext.BaseDirectory));
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);
})
.ConfigureServices((context, services) =>
{
services.AddTransient<IAppHost, AppHost>();
services.AddLogging(builder =>
{
builder.AddNLog("nlog.config");
});
}).Build();
var application = ActivatorUtilities.CreateInstance<AppHost>(host.Services);
application.Run();
}
catch (Exception ex)
{
logger.Error("Stopped program setup with Error. {0} | {1} | {2}", ex.Message, ex.StackTrace, ex.InnerException);
throw;
}
finally
{
// Ensure to flush and stop internal timers/threads before application-exit
NLog.LogManager.Shutdown();
}
}
}
NLog.config
<?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">
<!-- enable asp.net core layout renderers -->
<extensions>
<add assembly="NLog.Web.AspNetCore"/>
</extensions>
<variable name="LogDirectory" value="D:\logs\ApplictionName"/>
<!-- the targets to write to -->
<targets>
<target xsi:type="File"
name="DefaultTarget"
fileName="${LogDirectory}\LogFile.log"
layout="${longdate} | ${callsite} | ${message}"
archiveAboveSize="3145728"
archiveEvery="Day"
archiveFileName = "${LogDirectory}/Archive/{#}.log"
archiveNumbering = "DateAndSequence"
archiveDateFormat = "yyyyMMdd"
maxArchiveFiles = "21"
/>
<target name="ConsoleTarget"
xsi:type="Console"
layout="${longdate} ${logger:shortName=True} ${message} ${onexception:EXCEPTION OCCURRED\:${exception:format=type,message,StackTrace,method:maxInnerExceptionLevel=8:innerFormat=type,message,StackTrace,method}}"
/>
</targets>
<rules>
<logger name="Microsoft.*" maxlevel="Info" final="true" /> <!-- BlackHole without writeTo -->
<logger name="*" minlevel="Debug" writeTo="DefaultTarget,ConsoleTarget" />
</rules>
</nlog>
应用主机.cs
public class AppHost : IAppHost
{
private readonly ILogger<AppHost> _log;
private readonly IConfiguration _configuration;
public AppHost(ILogger<AppHost> log, IConfiguration config)
{
_log = log;
_configuration = config;
}
public void Run()
{
_log.LogInformation("Application START");
try
{
//*** All code goes here ***
}
catch (Exception ex)
{
_log.LogError("Error: {0} | {1} | {2}", ex.Message, ex.StackTrace, ex.InnerException);
}
_log.LogInformation("Application END");
}
}
这是我将要通读的 JSON 文件的基本示例。其中一个参数告诉我它将是一个出站文件,这是我将用于将任何日志记录写入 Outbound.log 文件的密钥。入站文件将以相同的方式工作。
"fileTypes": {
"FileName1":
{
"dayofweek": "MON",
"dayofmonth": "*",
"time": "23:00",
"inputFolder": "\\servername\emft\inbound",
"inputFileName": "FileName.pgp",
"maxInputFiles": "1",
"minInputFiles": "1",
"inputDecryptionKey": "d:\PgpKeys\private\keyname.asc",
"outputFolder": "\\servername\emft\outbound",
"outputFileName": "outfilename.txt.pgp",
"outputEncryptionKey": "d:\PgpKeys\public\keyname.asc",
"logFileType": "outbound"
}
}
问题更新
如果我的 NLog.config 文件中有多个目标,如下例所示,我如何告诉 .Net Core 我想要定位哪一个?
例如,使用下面的目标,我如何告诉依赖注入我想创建一个名为 _logOutgoing 的对象以使用“OutgoingTarget”目标,一个 _logIncoming 对象以“IncomingTarget”目标为目标,然后 _log 使用“DefaultTarget” “?然后,当我在控制台应用程序中工作时,如果我正在处理传入文件,如果我正在处理传出文件,我会向 _logIncoming 和 _logOutgoing 写一些东西吗?
我正在寻找这样的东西的原因是做一份临时报告。OutgoingTarget 和 IncomingTarget 将用于编写更多非技术报告,我将通过电子邮件将其发送给业务经理,以便他们知道发生了什么,而我将使用 DefaultTarget 供开发人员使用,并提供更多技术细节出于调试/支持原因发生了什么。
这是我在研究中发现的一个例子。
<target xsi:type="File" name="DefaultTarget" fileName="C:/AVDS/Logs/MyApps/nlog-all-${shortdate}.log"
layout="${longdate}|${uppercase:${level}}|${aspnet-traceidentifier}|${aspnet-user-identity}|${logger}|${aspnet-request-url}|${aspnet-mvc-action}|${message} ${exception:format=ToString}"
archiveFileName="C:/AVDS/Logs/MyApps/archives/nlog-all.{#}.txt"
archiveEvery="Day"
archiveNumbering="Rolling"
maxArchiveFiles="7" />
<target xsi:type="File" name="OutgoingTarget" fileName="C:/AVDS/Logs/MyApps/nlog-own-${shortdate}.log"
layout="${longdate}|${uppercase:${level}}|${aspnet-traceidentifier}|${aspnet-user-identity}|${logger}|${aspnet-request-url}|${aspnet-mvc-action}|${message} ${exception:format=ToString}"
archiveFileName="C:/AVDS/Logs/MyApps/archives/nlog-own.{#}.txt"
archiveEvery="Day"
archiveNumbering="Rolling"
maxArchiveFiles="7" />
<target xsi:type="File" name="IncomingTarget" fileName="C:/AVDS/Logs/MyApps/nlog-errors-${shortdate}.log"
layout="${longdate}|${uppercase:${level}}|${aspnet-traceidentifier}|${aspnet-user-identity}|${logger}|${aspnet-request-url}|${aspnet-mvc-action}|${message} ${exception:format=ToString}"
archiveFileName="C:/AVDS/Logs/MyApps/archives/nlog-errors.{#}.txt"
archiveEvery="Day"
archiveNumbering="Rolling"
maxArchiveFiles="7" />
修复尝试
我肯定错过了什么。我根据下面的示例添加了以下内容,但 _logIncoming.LogInformation("Testing") 出现错误,显示“ILoggerFactory 不包含 LogInformation 的定义”。我仍然是依赖注入的新手,但我想知道是否需要在 Program.cs 文件中的 .ConfigureServices 中添加一些内容?
更新了 Apphost.cs
public class AppHost : IAppHost
{
private readonly ILogger<AppHost> _log;
private readonly IConfiguration _configuration;
private readonly ILoggerFactory _logIncoming;
private readonly ILoggerFactory _logOutgoing;
public AppHost(ILogger<AppHost> log, ILoggerFactory loggerFactory, IConfiguration config)
{
_log = log;
_logIncoming = (ILoggerFactory)loggerFactory.CreateLogger("IncomingLogger");
_logOutgoing = (ILoggerFactory)loggerFactory.CreateLogger("OutgoingLogger");
_configuration = config;
}
public void Run()
{
_log.LogInformation("Application START");
_logIncoming.LogInformation("Testing Incoming log.");
_logOutgoing.LogInformation("Testing outgoing log.");
}
}
程序.cs
var host = Host.CreateDefaultBuilder()
.ConfigureAppConfiguration((hostingContext, config) =>
{
config.SetBasePath(Path.Combine(AppContext.BaseDirectory));
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);
})
.ConfigureServices((context, services) =>
{
services.AddTransient<IAppHost, AppHost>();
services.AddLogging(builder =>
{
builder.AddNLog("nlog.config");
});
}).Build();
解决方案
不确定我是否理解特定的导入/导出文件应该如何影响 NLog 输出。所以我只是在这里随机猜测:
我可能会使用ILogger.BeginScope
然后使用 NLog ${mdlc}
。
// You can inject several properties into the scope, or use Dictionary<string, object> instead of array
using (logger.BeginScope(new [] { new KeyValuePair<string, object>("ProcessFile", logFileName) }))
{
logger.LogInformation("Processing File ...");
}
然后在 NLog.config 中执行以下操作:
<nlog>
<variable name="LogDirectory" value="D:/logs/ApplictionName"/>
<variable name="LogProcessFile" value="${mdlc:ProcessFile:whenEmpty=LogFile}"/>
<targets>
<target xsi:type="File"
name="DefaultTarget"
fileName="${LogDirectory}/${LogProcessFile}.log"
layout="${longdate}|${message}" />
</targets>
<rules>
<logger name="Microsoft.*" maxlevel="Info" final="true" /> <!-- BlackHole without writeTo -->
<logger name="*" minlevel="Debug" writeTo="DefaultTarget" />
</rules>
</nlog>
然后内部发生的所有日志记录ILogger.BeginScope
都将转到一个专用文件。您可以让多个线程在各自的内部同时处理ILogger.BeginScope
。
推荐阅读
- javascript - 如何合并数组数组
- android - 在构建 VSCode 和 Android Studio (Flutter) 的 gradle 时,配置根项目“android”时出现问题
- java - 如何在 java 中创建或配置 Filehandler 以在不同的执行中对我的日志进行逻辑处理?
- r - 如何根据 R 中的最小日期差异为每个 ID 仅选择一行数据?
- powerbi - 根据同一表的另一列获取特定列的计数 - Power BI
- openvino - 问:如何获取 dldt buildinfo?
- django - 在 React 前端显示 rtsp 流
- excel - 宏按钮将文件移动到另一个文件夹
- node.js - 如何在构建模板时修复离子错误
- javascript - 如何以数组中的对象为条件在 Json 表单中使用规则?