C# NLog写入.Net Core 3.1中的多个日志

C# NLog写入.Net Core 3.1中的多个日志,c#,asp.net-core,nlog,C#,Asp.net Core,Nlog,我必须编写一个文件实用程序,它将用于读取导入文件和创建导出文件。我希望写入不同的NLog文件,这取决于我是使用导入文件还是创建导出文件。今天我一直在搜索和阅读不同的文章,但我不是在搜索正确的东西,就是不了解如何使用依赖项注入写入不同的日志文件 这是我正在尝试的基本概念。我运行一个控制台应用程序,它使用JSON文件读取文件设置列表。文件设置/config JSON文件将有一个设置,让我知道这是一个出站文件,而不是一个入站文件。所以,假设我正在处理的当前文件是一个出站文件,我将把它的日志记录写到我的

我必须编写一个文件实用程序,它将用于读取导入文件和创建导出文件。我希望写入不同的NLog文件,这取决于我是使用导入文件还是创建导出文件。今天我一直在搜索和阅读不同的文章,但我不是在搜索正确的东西,就是不了解如何使用依赖项注入写入不同的日志文件

这是我正在尝试的基本概念。我运行一个控制台应用程序,它使用JSON文件读取文件设置列表。文件设置/config JSON文件将有一个设置,让我知道这是一个出站文件,而不是一个入站文件。所以,假设我正在处理的当前文件是一个出站文件,我将把它的日志记录写到我的OutboundFiles.log,而不是我的InboundFiles.log

目前,我在创建的大多数.Net核心控制台应用程序中都使用了以下功能,它将使用_log(例如:_log.LogInformation)将其写入单个日志文件。我不明白的是,根据我使用的文件时间以及我将如何为不同的日志名和目录更改NLog.config文件,我如何才能说出我将写入的_logOutbound.LogInformation和_logInbound.LogInformation。下面是我当前用于写入单个文件的代码

Program.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();
            }
        }
    }
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.config文件中有多个目标,如下面的示例所示,我如何告诉.Net Core我希望以哪个为目标

例如,使用下面的目标,我如何告诉依赖项注入我想要创建一个名为_logout的对象使用“OutgoingTarget”目标,一个_logIncoming对象目标使用“IncomingTarget”目标,然后_log使用“DefaultTarget”目标?然后,当我在控制台应用程序中处理传入文件时,如果我处理传出文件,我会向_logIncoming和_logoutgo写入一些内容

我之所以要找这样的东西是为了做一份临时报告。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(“测试”)中得到一个错误,它说“iLogger工厂不包含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.");
}
}
公共类AppHost:IAppHost
{
私有只读ILogger_日志;
专用只读IConfiguration\u配置;
私有只读iLogger工厂登录名;
私有只读iLogger工厂\u注销;
公用AppHost(ILogger日志、ILogger工厂日志、IConfiguration配置)
{
_log=log;
_logIncoming=(ILoggerFactory)loggerFactory.CreateLogger(“IncomingLogger”);
_LogoutGong=(ILoggerFactory)loggerFactory.CreateLogger(“OutgoingLogger”);
_配置=配置;
}
公开募捐
{
_登录信息(“应用程序启动”);
_logIncoming.LogInformation(“测试传入日志”);
_logoutgo.LogInformation(“测试传出日志”);
}
}
Program.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();
            }
        }
    }
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 host=host.CreateDefaultBuilder()
.ConfigureAppConfiguration((hostingContext,config)=>
{
config.SetBasePath(Path.Combine(AppContext.BaseDirectory));
config.AddJsonFile(“appsettings.json”,可选:true,reloadOnChange:true);
})
.ConfigureServices((上下文、服务)=>
{
services.AddTransient();
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 ...");
}
//您可以将多个属性注入作用域,或者使用字典而不是数组
使用(logger.BeginScope(new[]{newkeyvaluepair(“ProcessFile”,logFileName)}))
{
logger.LogInformation(“处理文件…”);
}
然后在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
中并发处理


另请参见:

我不清楚指定的导入/导出文件应如何影响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 ...");
}
//您可以将多个属性注入作用域,或者使用字典而不是数组
使用(logger.BeginScope(new[]{newkeyvaluepair(“ProcessFile”,logFileName)}))
{
logger.LogInformation(“处理文件…”);
}
然后在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
中发生的所有日志记录都将进入一个专用文件。您可以有多个thre
<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}/AppLog.log"
      layout="${longdate}|${message}" />
    <target xsi:type="IncomingTarget" 
      name="DefaultTarget" 
      fileName="${LogDirectory}/IncomingTarget.log"
      layout="${longdate}|${message}" />
    <target xsi:type="File" 
      name="OutgoingTarget" 
      fileName="${LogDirectory}/OutgoingTarget.log"
      layout="${longdate}|${message}" />
  </targets>  

  <rules>
    <logger name="Microsoft.*" maxlevel="Info" final="true" /> <!-- BlackHole without writeTo -->
    <logger name="IncomingLogger" minlevel="Debug" writeTo="IncomingTarget" final="true" />
    <logger name="OutgoingLogger" minlevel="Debug" writeTo="OutgoingTarget" final="true" />
    <logger name="*" minlevel="Debug" writeTo="DefaultTarget" />
  </rules>
</nlog>