我需要为ASP.NET Core WEB API开发自定义记录器。 我想使用标准的日志记录基础结构,但是,我需要的是有点不同,因为日志记录不应该立即写入目标介质,但我需要
我是ASP.NET Core的新手,所以我遵循了几个教程,创建了DBLogger(实现ILogger并将记录保存到内部StringBuilder +另外一个方法Save),配置,提供者,扩展,我在Startup中注册了它它的工作原理,但没有最后一步,这是对数据库的保存。 在控制器中,我使用DI来获取记录器,所以它看起来像这样
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属性保存对应用程序内部使用的所有记录器的引用,但无法从代码访问该集合。
一般来说,问题甚至可能是:如何在代码中使用自定义ILogger的自定义功能。或许 - 我怎样才能获得对自定义记录器的引用?
[编辑] 这不是我的类型(DBlogger),我通过DI收到的,但我得到了Microsoft.Extensions.Logging.Logger,包含Microsoft.Extensions.Logging.Logger类型的非公共属性_logger,包含包含我的记录器的非公开记录器集合(见下图)。所以这就是为什么我觉得它很复杂
由于
菲利普
答案 0 :(得分:1)
//编写一个扩展方法Save for 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
}
}
}
}
}
答案 1 :(得分:0)
您可以将记录器声明为动态:
private readonly dynamic _logger;
但是,在这种情况下,您需要确保在执行该调用时ILogger的特定实现具有一个名为Save的方法。
OR
使用反射来调用save方法。当您的特定ILogger实现不包含名为Save的方法时,您可以使用try catch来处理这种情况。