ASP.NET Core Web API 从静态日志记录 Class

ASP.NET Core Web API Logging from a Static Class

我在我的控制器上使用依赖注入记录得很好,现在我需要记录一些东西来自一个静态class。

如何从 记录静态class?

我不能使用依赖注入,因为它是静态的,我不能只将现有的记录器对象传递给静态 class,因为它在日志文件。

换句话说,我怎样才能从静态 class 中的 loggerfactory 获取记录器?

我遇到了一个类似的问题,他们在静态 class 中指出了一篇关于 loggerfactory 的文章,但这实际上不起作用,因为我无法从中获得新的记录器,因为它不会' t 接受静态 class 作为参数:

"Static types cannot be used as type arguments"

首先,我同意NightOwl888的回答。

但作为一个选项(将此视为一种解决方法),您可以通过方法参数注入 ILogger 依赖项 => 因此将调用此静态方法的 class 应该负责提供正确的ILogger.

的实施
static class YourClass
{
    public static void DoSomething(ILogger logger)
    {
         // do something
         // call log.Log();
    }
}

解决方案是在启动时初始化的实用程序静态 class 中静态引用 LoggerFactory:

/// <summary>
    /// Shared logger
    /// </summary>
    internal static class ApplicationLogging
    {
        internal static ILoggerFactory LoggerFactory { get; set; }// = new LoggerFactory();
        internal static ILogger CreateLogger<T>() => LoggerFactory.CreateLogger<T>();        
        internal static ILogger CreateLogger(string categoryName) => LoggerFactory.CreateLogger(categoryName);

    }

您在 Startup.cs 上初始化的:

 public Startup(ILogger<Startup> logger, ILoggerFactory logFactory, IHostingEnvironment hostingEnvironment)
        {
            _log = logger;
            _hostingEnvironment = hostingEnvironment;
            Util.ApplicationLogging.LoggerFactory = logFactory;//<===HERE

        }

然后您可以构建一个记录器以从您的静态 class 中使用,如下所示:

internal static class CoreJobSweeper
    {
        private static ILogger log = Util.ApplicationLogging.CreateLogger("CoreJobSweeper");

您可以将静态 LoggerFactory 实例与以下扩展方法一起使用,该方法接受 Type 类型的常规参数,而不是泛型类型参数: CreateLogger(ILoggerFactory, Type)

loggerFactory.CreateLogger(typeof(T)) 而不是 loggerFactory.CreateLogger<T>()

我发现这个问题及其答案很有用,但我记得我已经安装了 Serilog。我可以使用 Serilog 的默认实现,而不是实现自定义静态实例。

它带有多个不错的日志记录功能和多个重载版本。
这里有两个例子:

using Serilog;
...
    Log.Error(myException, "my message");
    Log.Warning("My message", myValue);

Serilog.Log是静态实例,在Program.cs或Startup.cs.

中配置时就绪

我在 Startup class 中添加了 ILoggerFactory 的静态成员,因此它可以在其他 classes 中使用。

public class Startup
{
    internal static ILoggerFactory LogFactory { get; set; }
    …

    public void Configure(…, ILoggerFactory logFactory)
    {
        …
        LogFactory = logFactory;
    }
}

然后在静态中使用它class。

static class YourClass
{
    private static ILogger<YourClass> Logger = Startup.LogFactory.CreateLogger<YourClass>();
…

但是这段代码会在CreateLogger抛出异常时抛出TypeInitializationException,所以你应该努力做得更好。 [1]

这是@JohnC 和@Pekaaw 的综合回答,

可以从 SeriLog 记录器创建 LoggingFactory 以保留相同的日志配置,它可以用于日志记录机制

(Microsoft.Extensions.Logging.LoggerFactory)Serilog.SerilogLoggerFactoryExtensions.AddSerilog(新Microsoft.Extensions.Logging.LoggerFactory(), Serilog.Log.Logger);

/// <summary>
/// Shared logger
/// </summary>
internal static class ApplicationLogging
{
    internal static ILoggerFactory LoggerFactory { get; set; } = (Microsoft.Extensions.Logging.LoggerFactory)Serilog.SerilogLoggerFactoryExtensions.AddSerilog(new Microsoft.Extensions.Logging.LoggerFactory(), Serilog.Log.Logger);
    internal static Microsoft.Extensions.Logging.ILogger CreateLogger<T>() => LoggerFactory.CreateLogger<T>();
    internal static Microsoft.Extensions.Logging.ILogger CreateLogger(string categoryName) => LoggerFactory.CreateLogger(categoryName);
}
public static class YourClass
{
   public static readonly ILogger _logger = ApplicationLogging.CreateLogger("YourClass");
   public static void MyMethod(string param)
   {
      try
      {
         _logger.LogInformation($"Inside MyMethod { param }");
         //Todo: my static code;
      }
   }
}