首页 文章

每个请求一次将ASP.NET CORE自定义 Logger 保存到数据库

提问于
浏览
1

我需要开发ASP.NET Core WEB API的自定义 Logger . 我想使用标准的日志记录基础结构,但是,我需要的是有点不同,因为日志记录不应该立即写入目标介质,但我需要

  • 为每个请求创建新的 Logger

  • 在内存中收集此请求的日志记录

  • 在该操作结束时或出现异常时将请求的所有记录保存为数据库中的一条记录 .

我是ASP.NET Core的新手,所以我遵循了几个教程,创建了DBLogger(实现ILogger并将记录保存到内部StringBuilder另外一个方法Save),配置,提供者,扩展,我在Startup中注册了它,它工作,但没有最后一步,这是对数据库的保存 . 在控制器中,我使用DI来获取 Logger ,所以它看起来像这样

public class ValuesController : Controller

{
    private readonly ILogger<ValuesController> _logger;

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

    [HttpGet]
    public IEnumerable<string> Get()
    {
        _logger.LogWarning("TestWarning");
        _logger.LogInformation("TestInfo");

        return new string[] { "value1", "value2" };
    }

所以我现在可以编写日志记录,但是如何调用特定Logger的附加(自定义)功能(在本例中我的DBLogger的Save()方法)?我的控制器中的_logger属性保存对应用程序内部使用的所有 Logger 的引用,但无法从代码访问该集合 .

一般来说,问题甚至可能是:如何在代码中使用自定义ILogger的自定义功能 . 或许 - 我如何获得自定义 Logger 的引用?

[编辑]这不是我的类型(DBlogger),我通过DI收到的,但我得到的是Microsoft.Extensions.Logging.Logger,包含非公共属性_logger,类型为Microsoft.Extensions.Logging.Logger,包含非公开的 Logger 集合包含我的 Logger (见下图) . 所以这就是为什么我觉得它很复杂

![1]](https://i.stack.imgur.com/1UoQo.jpg)

谢谢

菲利普

2 回答

  • 1

    //编写扩展方法保存为ILogger并将任何参数传递给StateInfo

    public static void Save(this ILogger logger, string param) {
    
    var state = new List<KeyValuePair<string, dynamic>>
    {
        new KeyValuePair<string, dynamic>("Myparam", param),
    
    };
    
    logger.Log(level,999, state, null, null);
    }
    
    public class DBLogger:ILogger{
    public void Log<TState>(LogLevel logLevel, Microsoft.Extensions.Logging.EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
    {
          if (eventId.Id == 999) //Save Event
          {
                if (state is IReadOnlyList<KeyValuePair<string, object>> stateInfo )
                {
                    foreach (var property in stateInfo)
                    {
                      if (property.Key == "Myparam")
                            {
                                var value = (string)property.Value;//do something with value
                            }
                    }
                }
         }
    }
    
  • 0

    您可以将 Logger 声明为动态:

    private readonly dynamic _logger;
    

    但是,在这种情况下,您需要确保在执行该调用时ILogger的特定实现具有一个名为Save的方法 .

    要么

    使用反射来调用save方法 . 当您的特定ILogger实现不包含名为Save的方法时,您可以使用try catch来处理此情况 .

相关问题