Serilog 与 Application Insights 的 Azure 函数集成,日志在搜索中可见但未出现在故障事件时间线中

时间:2021-06-01 06:19:51

标签: .net-core azure-functions azure-application-insights serilog

我正在尝试将 Serilog 与 Application Insights 接收器一起用于日志记录。我可以在 Azure 门户 (Application Insights) 的搜索栏中看到日志,但如果我们在“故障”或“性能”选项卡中查看事件的时间线,则看不到相同的日志。谢谢

以下是用于在 FunctionStartup 中注册 Logger 的代码,然后将其注入 Function 中以进行日志记录:

var logger = new LoggerConfiguration()
                               .Enrich.FromLogContext()
                               .Enrich.WithProperty("ApplicationName", "testApp")
                               .Enrich.WithProperty("Environment", "Dev")                               
                               .WriteTo.ApplicationInsights(GetTelemetryClient("Instrumentationkey"), TelemetryConverter.Traces)
                               .CreateLogger();
builder.Services.AddSingleton<ILogger>(logger);

Telementory 客户端正在从辅助方法中获取:

public static TelemetryClient GetTelemetryClient(string key)
        {
            var teleConfig = new TelemetryConfiguration { InstrumentationKey = key };

            var teleClient = new TelemetryClient(teleConfig);

            return teleClient;
        }

host.json

{
    "version": "2.0",
    "logging": {
        "applicationInsights": {
            "samplingExcludedTypes": "Request",
            "samplingSettings": {
                "isEnabled": true
            }
        }
    }
}

3 个答案:

答案 0 :(得分:0)

我明白你的意思,请允许我在这里总结一下我的测试结果。

首先,failure blade 不是用来提供一个时间线来追踪细节(在异常发生之前发生了什么),而是为了显示所有的异常,错误发生的频率,有多少用户受到影响等,更有可能站在高处看整个节目。

为了实现您的目标,我认为您可以在 Logs 刀片中使用此 kql 查询或在交易刀片中查看它。

union traces, requests,exceptions
| where operation_Id == "178845c426975d4eb96ba5f7b5f376e1"

enter image description here 基本上,我们可以在执行链中添加许多日志,例如在控制器中,记录输入参数,然后记录数据组合或格式化的结果,将异常信息记录在catch中,这是我的测试代码。我在失败刀片中看不到任何其他信息,但在事务刀片中,我可以看到时间线。

public class HelloController : Controller
    {
        public string greet(string name)
        {
            Log.Verbose("come to greet function");
            Log.Debug("serilog_debug_info");
            Log.Information("greet name input " + name);
            int count = int.Parse(name);
            Log.Warning("enter greet name is : {0}", count);
            return "hello " + name;
        }
    }

enter image description here

而且我们很容易发现,整个链共享同一个operationId,通过所有这些日志,我们可以查明错误的行代码。顺便说一句,如果我用 try/catch 包围代码,则失败刀片中将不会捕获异常。

==================================

使用Serilog integrate app insights,我们需要发送serilog到applicationinsights,我们会在交易搜索中看到很多Traces,所以最好把MinimumLevel做成信息和更高.下面的截图是我的日志详情,我们也可以通过operationId使用kql查询来查看整个链条。

enter image description here

答案 1 :(得分:0)

您可以按照 Azure Application Insights 在其 GitHub 存储库上提供的解决方案轻松解决此问题,根据此 Github Issue,您可以使用 DI 配置 TelemetryConfiguration,即

services.Configure<TelemetryConfiguration>(
 (o) => {
   o.InstrumentationKey = "123";
   o.TelemetryInitializers.Add(new OperationCorrelationTelemetryInitializer());
 });

或者您可以像这样手动配置它:

var config = TelemetryConfiguration.CreateDefault();
var client = new TelemetryClient(config);

因此在您的代码中,您必须将 GetTelemetryClient 更改为

public static TelemetryClient GetTelemetryClient(string key)
    {
        var teleConfig = new TelemetryConfiguration { InstrumentationKey = key };

        var teleClient = new TelemetryClient(teleConfig);

        return teleClient;
    }

到这里

public static TelemetryClient GetTelemetryClient(string key)
    {
        var teleConfig = TelemetryConfiguration.CreateDefault();

        var teleClient = new TelemetryClient(teleConfig);

        return teleClient;
    }

答案 2 :(得分:0)

为了使用上面 Azure Functions 的回答中提到的遥测配置使用日志记录,我们只需要更新下面的代码片段中的函数,并且在部署时它应该自己获取 Instrumentation 密钥

public static TelemetryClient GetTelemetryClient()
 {
   var teleConfig = TelemetryConfiguration.CreateDefault();
    
   var teleClient = new TelemetryClient(teleConfig);
    
   return teleClient;
 }

但要在本地和在 Azure 上部署后运行。我们需要在函数Startup中添加类似这样的东西,去掉上面的Function。

builder.Services.Configure<TelemetryConfiguration>((o) =>
                {
                   o.InstrumentationKey = "KEY";
                   o.TelemetryInitializers.Add(new OperationCorrelationTelemetryInitializer());
                });
        
builder.Services.AddSingleton<ILogger>(sp =>
                {
                var logger = new LoggerConfiguration()
                 .Enrich.FromLogContext()
                 .Enrich.WithProperty("ApplicationName", "TEST")
                 .Enrich.WithProperty("Environment", "DEV")
                 .WriteTo.ApplicationInsights( 
        
                 sp.GetRequiredService<TelemetryConfiguration>(), TelemetryConverter.Traces).CreateLogger(); 
        
                 return logger;
               });

之后我们只需要在我们的类/azure 函数中使用典型的 DI 来使用 ILogger

public class Test{
      public ILogger _log;
      public void Test(ILogger log){
        _log=log;
      }
   }
相关问题