当前位置: 首页 > 知识库问答 >
问题:

如何使用依赖注入正确设置Azure功能日志、实时度量和应用洞察

丌官信厚
2023-03-14

现在看来,Azure Functions portal接口默认为新的“管理体验”,它看起来与Azure的其他部分更加相似,因此,我们使用日志记录和跟踪的方式更加明显地有问题。

我的问题是:是否有人有关于如何设置Azure函数日志、实时度量和应用程序洞察跟踪的代码示例,以便:

  1. 使用依赖注入
  2. 使用新的“管理体验”界面

当前,为了查看特定Azure函数正在执行什么操作,我必须访问旧的Azure接口并研究日志流。这些函数确实起作用,它们在日志流中吐出信息,但只在旧接口中吐出信息,在监视方面似乎没有太多其他方面起作用。使用旧接口:

  • 调用日志,即按“functions(Read Only)>[function]>Monitor”下的“Monitor”链接时获得的日志,显示没有任何调用,即使根据日志确实调用了函数。
  • “实时应用程序度量”链接会显示默认的“不可用:您的应用程序处于脱机状态或使用较旧的SDK”,并显示一些动画演示图。

一个月前还不错。现在,没那么多了。

使用新接口:

  • Monitoring>日志流除了“Connected!”(连接!)一词外,不显示任何内容。
  • 监视>Log Stream>在Live Metrics中再次打开只会产生默认值“不可用:您的应用程序处于脱机状态或使用较旧的SDK”。
    null

我不明白为什么一个月前它突然停止工作了,为什么这么多东西似乎与新界面不起作用。我们的功能的NuGet包都是最新的。

在日志记录方面,日志记录程序是依赖项注入的,这样我们就可以在多个类中使用它,而不仅仅是在默认函数中使用它。cs类:

using Microsoft.Extensions.Logging;

public class EventForwarder
{
    private readonly ILogger<EventForwarder> log;

并且我们通过使用扩展方法进行日志记录,真的没有什么花哨的:

using Microsoft.Extensions.Logging;

public static class LoggerExtensions
{
    public static void Info(this ILogger log, string msg) => log.LogInformation(msg);

应用程序insights跟踪器也是使用这里建议的一个变通方法注入的依赖项,即我们的Startup.cs看起来是这样的:

using Microsoft.ApplicationInsights.Extensibility;
using Microsoft.Azure.Functions.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection;

[assembly: FunctionsStartup(typeof(EventForwarder.Startup))]
namespace EventForwarder
{
    public class Startup : FunctionsStartup
    {
        public override void Configure(IFunctionsHostBuilder builder)
        {
            // https://github.com/Azure/azure-functions-host/issues/5353
            builder.Services.AddSingleton(sp =>
            {
                var key = Environment.GetEnvironmentVariable("APPINSIGHTS_INSTRUMENTATIONKEY");
                return string.IsNullOrWhiteSpace(key) ? new TelemetryConfiguration() : new TelemetryConfiguration(key);
            });

我们正在执行Http重试的跟踪,除其他外,如下所示:

public class HttpRetryPolicyService
{
    private readonly ILogger<HttpRetryPolicyService> log;
    private readonly TelemetryClient insights;

    public HttpRetryPolicyService(ILogger<HttpRetryPolicyService> log,
        TelemetryConfiguration insightsConfig)
    {
        this.log = log;
        insights = new TelemetryClient(insightsConfig);
    }
...
private void LogRetry(DelegateResult<HttpResponseMessage> message, TimeSpan delay, int attempt, Context context)
{
    if (message.Exception != null)
    {
        log.Warn($"Exception details: {message.Exception}");
        insights.Track(message.Exception);
using Microsoft.ApplicationInsights;

namespace EventForwarder.Static
{
    public static class TelemetryExtensions
    {
        public static void Track(this TelemetryClient insights, string eventName)
        {
            insights.TrackEvent(eventName);
            insights.Flush();
        }

编辑#2:另外,我们的函数host.json文件看起来都是这样的:

{
    "version": "2.0",
    "healthMonitor": {
        "enabled": true,
        "healthCheckInterval": "00:00:10",
        "healthCheckWindow": "00:02:00",
        "healthCheckThreshold": 6,
        "counterThreshold": 0.80
    },
    "logging": {
        "fileLoggingMode": "always",
        "applicationInsights": {
            "enableLiveMetrics": true,
            "samplingSettings": {
                "isEnabled": true
            }
        },
        "logLevel": {
            "EventForwarder": "Information"
        }
    }
}

共有1个答案

萧心水
2023-03-14

这是什么打破你的app,移除它,一切都应该工作:

// https://github.com/Azure/azure-functions-host/issues/5353
builder.Services.AddSingleton(sp =>
{
    var key = Environment.GetEnvironmentVariable("APPINSIGHTS_INSTRUMENTATIONKEY");
    return string.IsNullOrWhiteSpace(key) ? new TelemetryConfiguration() : new TelemetryConfiguration(key);
});

我的猜测是,现在bugfix已经推出,这个变通方法实际上破坏了日志记录。

我创建了一个示例应用程序,其中日志记录和日志流非常好地工作,还使用了依赖注入。我用Windows和Linux消费计划对它进行了测试。function app是使用Azure Portal中的向导创建的,选择.NET Core 3.1。请注意trackevent不会显示在函数的日志流中。它显示在Application Insights Live Metrics。它也可以在“连接”显示后持续30s,直到显示实际日志。Live Metrics视图工作得更好,尤其是直接从应用程序洞察打开时。

我能够通过应用上面提到的“变通方法”重现您的问题。没有它,一切都很好。

完整示例:https://github.com/lxbdev/functions-v3-sample

public class Startup : FunctionsStartup
{
    public override void Configure(IFunctionsHostBuilder builder)
    {
        builder.Services.AddScoped<MyService>();
    }
  "logging": {
    "applicationInsights": {
      "samplingExcludedTypes": "Request",
      "samplingSettings": {
        "isEnabled": true
      }
    },
    "logLevel": {
      "Functions_V3_sample": "Information"
    }
  }
public MyService(ILogger<MyService> logger, TelemetryClient telemetry)
{
    Logger = logger ?? throw new ArgumentNullException(nameof(logger));
    Telemetry = telemetry ?? throw new ArgumentNullException(nameof(telemetry));
}

public void Foo()
{
    Logger.LogInformation("Foo");
    Telemetry.TrackTrace("BarLog", Microsoft.ApplicationInsights.DataContracts.SeverityLevel.Information);
    Telemetry.TrackEvent("BarEvent");
}

更新:在我最初的回答中host.json有一个问题,由于https://github.com/azure/azure-functions-host/issues/4345,示例日志没有真正持久化到AppInsights。我相应地更新了代码。

 类似资料:
  • 我想通过创建遥测初始化器为azure函数定制application insight配置。我当前的工作范围是确定一种方法,将从HTTP触发的azure函数发送的消息与另一个HTTP触发的azure函数相关联,为此,我试图遵循dzimchuk.net上的帮助。但是,我在我的azure函数项目中没有看到ApplicationInsights.config。我找到了包含app insight配置文件的Gi

  • 问题内容: 我尝试构建基于Java的应用程序。 对于依赖项注入,我使用Google Guice。 现在我想到了在应用程序中记录一些信息的问题。我不是在谈论方法调用等方式的常规日志记录。我对AOP有所了解,并且我可以像这样进行方法调用跟踪。 我要寻找的是手动记录。我需要某种方式登录应用程序中的几乎每个类。所以我考虑了两个选择: 通过使用Guice注入框架通过构造函数(或setter或private

  • 我已经使用GoogleGuice几个月了。我对它很满意,但似乎我用错了。我创造了很多辅助注射,有时还有两个注射器。 因此,我想了解这里的一般原则。 是否应该为连接主类所有内容的所有应用程序配备一个喷油器? 最佳实践是关于从应用程序一开始就尝试在构造函数中注入大量内容吗?(我看到了测试的优势) 我的主要问题是,有时我觉得某些对象组的创建属于某个组件。有必要封装它吗?你会如何处理? 当您拥有一个重要的

  • 问题内容: 我有以下查询,该查询使用日期变量,该变量在存储过程内部生成: 问题是@sp_Date值似乎被忽略了,我想知道为什么吗?我定义或使用不正确吗? 问题答案: 您的语法很好,它将返回过去6个月内的行; 您确定类型吗?

  • 通常在a.NET Core项目我将创建一个引导类来配置我的服务以及DI注册命令。这通常是的扩展方法,我可以在其中调用像和包含该方法的静态类中所需的一切都是自包含的。关键是该方法从Startup类中获取一个。 我以前在Azure函数中使用过DI,但还没有遇到这个具体要求。 我正在使用绑定到一个具体的类,该类的属性与我的以及在Azure中部署该功能时的开发/生产应用程序设置。 显然,在不起作用,因为它

  • 似乎微软推荐了Azure APIM和功能的应用洞察,尽管我找不到任何官方文档。