将.NET Core登录到文件和控制台-带时间戳

Pat*_*ric 2 .net logging timestamp dependency-injection .net-core

我是.NET核心的新手,还没有机会深入了解依赖项注入。但是我理解这个概念,并且知道这是一件好事,而且我的应用需要它。由于可能需要在某个时候增强或切换日志记录功能。

我已经启动了使用类库(.net Standard 2.0)的控制台应用程序,应该将内容注销到控制台以及日志文件中。

目前,我遵循一些指南并使用Microsoft.Extensions.Logging.Console配置日志记录(尚无文件可用)。该记录器的输出是,它为每个条目写两行,例如:

info: SampleWebConsoleApp.Program[0]
      This is a test of the emergency broadcast system.
Run Code Online (Sandbox Code Playgroud)

我不了解您,但是我有点不喜欢两行登录的输出。我的大脑无法解析:-)。我喜欢在一行上加上开头的时间戳。据我发现,似乎控制台记录器无法更改为单行并带有时间戳。

于是我的旅程开始了。我找到了Serilog,NLog或我以前使用的老朋友log4net之类的东西。

我尝试使用Serilog,因为它看起来很简单,并且还具有一个我也需要的文件记录器。因此,我开始淘汰旧的控制台记录器,并集成了Serilog控制台和文件记录器。但是后来我发现了一些这样的例子:

static void Main(string[] args)
{
        Log.Logger = new LoggerConfiguration()
          .WriteTo.File("consoleapp.log")
          .CreateLogger();
        ...
}
Run Code Online (Sandbox Code Playgroud)

但这似乎与我对依赖注入的稀疏知识相矛盾,因为我认为应该像这样配置(假设!):

private static void ConfigureServices(IServiceCollection services)
{
    ...
    services.Configure<UnknownSerilogConfigurationClass>(config => config.FileName = "consoleapp.log");
}
Run Code Online (Sandbox Code Playgroud)

我看到有人提到,Serilog本身就是记录器工厂,因此是DI的反模式。

所以现在我对从这里去哪里有些困惑。

对于一个相当简单的控制台应用程序,应该使用哪种支持依赖项注入的日志记录框架?我必须允许配置输出,以使其包含时间戳,并且输出应位于一行上。

有什么建议么?

gpa*_*oli 9

使用Serilog,非常简单。请参阅库的入门页面。

安装 NuGet 包:

dotnet add package Serilog.Sinks.File
Run Code Online (Sandbox Code Playgroud)

控制台应用程序示例:

using System;
using Serilog;

namespace SerilogExample
{
    class Program
    {
        static void Main()
        {
            Log.Logger = new LoggerConfiguration()
                .MinimumLevel.Debug()
                .WriteTo.Console()
                .WriteTo.File("logs\\logfile_yyyyDDmm.txt")
            .CreateLogger();

            Log.Information("Hello, world!");

            try
            {
                Log.Warning("Warning message..");
                Log.Debug("debug message..");
            }
            catch (Exception ex)
            {
                Log.Error(ex, "Error message");
            }

            Log.CloseAndFlush();
            Console.ReadKey();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

输出样本:

2021-01-28 00:09:42.123 -03:00 [INF] Hello, world!
2021-01-28 00:09:43.456 -03:00 [WRN] Debug message
2021-01-28 00:09:44.789 -03:00 [DBG] Debug message
2021-01-28 00:09:45.012 -03:00 [ERR] Error message
Run Code Online (Sandbox Code Playgroud)


小智 7

您可以使用NLog。配置很简单。配置完成后,您需要做的就是ILogger<T>在哪里插入T使用记录器的类类型。

nlog.config文件(不要忘记将其复制到输出目录)

<?xml version="1.0" encoding="utf-8" ?>
<!-- XSD manual extracted from package NLog.Schema: https://www.nuget.org/packages/NLog.Schema-->
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xsi:schemaLocation="NLog NLog.xsd"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      autoReload="true" >


  <!-- the targets to write to -->
  <targets>
    <!-- write logs to file -->
    <target xsi:type="File" name="target1" fileName="${basedir}/LogFile.txt"
            layout="${date}|${level:uppercase=true}|${message} ${exception}|${logger}|${all-event-properties}" />
    <target xsi:type="Console" name="target2"
            layout="${date}|${level:uppercase=true}|${message} ${exception}|${logger}|${all-event-properties}" />
  </targets>

  <!-- rules to map from logger name to target -->
  <rules>
    <logger name="*" minlevel="Trace" writeTo="target1,target2" />    
  </rules>
</nlog>
Run Code Online (Sandbox Code Playgroud)

.NET Core 2.2应用

using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using NLog.Extensions.Logging;
using System;

namespace ConsoleApp1
{
    public class Program
    {
        static void Main(string[] args)
        {
            var serviceProvider = new ServiceCollection()
                .AddSingleton<IFooService, FooService>()
                .AddLogging(builder =>
                {
                    builder.SetMinimumLevel(LogLevel.Trace);
                    builder.AddNLog(new NLogProviderOptions
                    {
                        CaptureMessageTemplates = true,
                        CaptureMessageProperties = true
                    });
                })
                .BuildServiceProvider();

            ILogger<Program> logger = serviceProvider.GetService<ILoggerFactory>()
                                        .CreateLogger<Program>();
            logger.LogInformation("Starting application...");

            var fooService = serviceProvider.GetService<IFooService>();
            fooService.DoWork();

            Console.ReadLine();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

FooService

using Microsoft.Extensions.Logging;

namespace ConsoleApp1
{
    public interface IFooService
    {
        void DoWork();
    }

    public class FooService : IFooService
    {
        private readonly ILogger _logger;

        public FooService(ILogger<FooService> logger)
        {
            _logger = logger;
        }

        public void DoWork()
        {
            _logger.LogInformation("Doing work.");
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

应用输出

2019/03/19 23:03:44.875|INFO|Starting application... |ConsoleApp1.Program|
2019/03/19 23:03:44.920|INFO|Doing work. |ConsoleApp1.FooService|
Run Code Online (Sandbox Code Playgroud)

或者,如果您不想使用NLog或任何其他日志记录提供程序,则可以创建自己的自定义控制台记录器自定义文件记录器