从 Function App ILogger (C#) 在 Application Insights 中记录自定义对象

问题描述

我有一个 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“自定义属性”部分中可见。