【发布时间】:2021-04-26 21:28:24
【问题描述】:
我必须编写一个文件实用程序来读取导入文件和创建导出文件。我正在寻找写入不同的 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>
AppHost.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 使用“默认目标”?然后,当我在控制台应用程序中工作时,如果我正在处理传入文件,如果我正在处理传出文件,我会向 _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();
【问题讨论】:
标签: c# asp.net-core nlog