问题描述
我有一个 C# .NET Core Azure Function App,我正在使用 ILogger 将日志发送到 Application Insights。到目前为止,这运行良好。
函数头:
public static void Run([TimerTrigger("0 30 * * * *")] TimerInfo myTimer,ILogger log,ExecutionContext context)
ILogger 使用:
log.Log@R_983_4045@ion($"MyFunction trigger function executed at: {DateTime.Now}");
在 App Insights 中,我看到日志包含默认信息,例如它来自哪个函数应用,以及包含上述字符串的 message
。
但是,现在我想记录自定义日志。我有一个 IEnumerable<IDictionary<string,string>>
并且我希望列表的每个字典元素都是一个单独的日志。理想情况下,我可以有一个日志,其中每个字段都是字典中的一个键,其值是相应的值。或者,我可以在日志中使用某种 customDimensions 字段,它是一个包含列表中 1 个字典中的所有键值对的对象。
目的是使日志易于在 Kusto 中查询。我想避免在 App Insights 中查询它们时必须解析它们。
注意事项:
- 既然我已经将 ILogger 用于现有日志记录,那么有没有办法使用 ILogger 接口执行上述对象日志记录?
- 如果没有,我如何使用不同的记录器记录上述对象?
我看了很多其他类似的帖子,但似乎没有一个得到完整的回答。
解决方法
这是我以前使用过的模式:
public class LogService : ILogService
{
private readonly ILogger<LogService> _log;
private readonly Dictionary<string,object> _customProperties = new Dictionary<string,object>();
public LogService(ILogger<LogService> log)
{
_log = log;
}
public void SetCustomProperty(string key,object value)
{
_customProperties.Add(key,value);
}
public void LogInformation(string message,params object[] args)
{
Log(LogLevel.Information,message,args);
}
public void LogWarning(string message,params object[] args)
{
Log(LogLevel.Warning,args);
}
...etc
private void Log(LogLevel logLevel,string message,params object[] args)
{
using (_log.BeginScope(_customProperties))
{
_log.Log(logLevel,args);
}
}
}
重要的一点是最后一个方法Log(LogLevel logLevel,params object[] args)
。它将 _log.Log()
包装在 using
中,并使用 _log.BeginScope()
将自定义属性添加到日志消息中,日志消息应该在 Application Insights“自定义属性”部分中可见。