如何通过依赖项注入正确设置 Azure Functions 日志记录、实时指标和应用程序洞察

2024-04-01

大约一个月前,我注意到旧的 Azure Functions 门户界面中的一些监视功能停止工作。我写了有关这些问题的更多详细信息Azure Functions 托管 GitHub https://github.com/Azure/azure-functions-host/issues/6060但我的具体问题尚未得到解答。

现在,Azure Functions 门户界面似乎默认采用新的“管理体验”,看起来与 Azure 的其他部分更加相似,因此,更明显的是我们使用日志记录和跟踪的方式存在问题。

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

  1. 与依赖注入一起使用
  2. 适用于新的“管理体验”界面

目前,为了查看特定的 Azure Function 正在做什么,我必须转到旧的 Azure 界面并研究日志流。这些功能确实有效,它们在日志流中吐出信息,但仅限于旧界面,在监控方面似乎没有太多其他功能。使用旧界面:

  • 调用日志是您按下“函数(只读)> [函数] > 监视器下的“监视器”链接时获得的日志,即使根据日志肯定正在调用函数,也根本不显示任何调用。
  • 实时应用程序指标链接会导致默认的“不可用:您的应用程序已离线或使用较旧的 SDK”以及一些动画演示图表。

一个月前这些工作正常。现在,没那么多了。

使用新界面:

  • 无论详细程度如何,“监控”>“日志流”除了“已连接!”一词外不显示任何内容。
  • 再次监控 > 日志流 > 在实时指标中打开只会产生默认的“不可用:您的应用程序已离线或使用较旧的 SDK”。

使用“功能”>“功能”> [单击某个功能] 转到新界面中的特定功能:

  • 开发人员>代码+测试>测试按钮>运行,弹出日志窗口,只显示“已连接!”没有别的,再次不管冗长。
  • 监视器 > 调用,这里没有注册任何调用跟踪,即使该函数显然是根据旧接口日志流调用的。
  • 监视器 > 日志再次只显示“已连接!”,无论内容有多冗长。

我不明白为什么它在一个月前突然停止工作,以及为什么这么多东西似乎不适用于新界面。我们的 Functions 的 NuGet 包都是最新的。

在日志记录方面,记录器是依赖注入的,因此我们可以在多个类中使用它,而不仅仅是在默认的 Functions.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);

应用程序见解跟踪器也使用建议的解决方法进行依赖项注入here https://github.com/Azure/azure-functions-host/issues/5353#issuecomment-590147499,即我们的 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();
        }

我缺少什么?

编辑#1:顺便说一句,不幸的是,在“发布”对话框中将 Application Insights 添加为服务依赖项not解决这些问题。

编辑 #2:此外,我们的 Functions 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"
        }
    }
}

这就是破坏您的应用程序的原因,将其删除,一切都应该正常:

// 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);
});

我的猜测是,既然错误修复已经推出,解决方法实际上会破坏日志记录。

我创建了一个示例应用程序,其中日志记录和日志流工作得很好,还具有依赖项注入。我使用 Windows 和 Linux 消费计划对其进行了测试。该函数应用是使用 Azure 门户中的向导创建的,选择 .NET Core 3.1。请注意TrackEvent不会显示在函数的日志流中。它显示在 Application Insights 实时指标中。显示“已连接”后最多可能需要 30 秒才能显示实际日志。实时指标视图效果更好,特别是当您直接从应用程序见解打开时。

我能够通过应用上面提到的“解决方法”来重现您的问题。没有它,一切都正常。

完整样本:https://github.com/LXBdev/Functions-V3-sample 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");
}

Update:我的原始答案和示例中的 host.json 存在问题 - 日志并未真正保留到 AppInsights,因为https://github.com/Azure/azure-functions-host/issues/4345 https://github.com/Azure/azure-functions-host/issues/4345。我相应地更新了代码。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何通过依赖项注入正确设置 Azure Functions 日志记录、实时指标和应用程序洞察 的相关文章

  • 具有不同大小结构的结构数组的 malloc()

    如果每个结构都包含一个大小不同的字符串数组 那么如何正确地 malloc 一个结构数组 因此每个结构可能有不同的大小 并且不可能 realloc 结构体数量 sizeof 结构体名称 after malloc 初始大小 sizeof 结构名
  • clang 格式换行符在错误的位置

    给出以下代码行 get abc manager get platform status abc platform status sw update status fill update status actions allowed stat
  • C 程序从连接到系统的 USB 设备读取数据

    我正在尝试从连接到系统 USB 端口的 USB 设备 例如随身碟 获取数据 在这里 我可以打开设备文件并读取一些随机原始数据 但我想获取像 minicom teraterm 这样的数据 请让我知道我可以使用哪些方法和库来成功完成此操作以及如
  • System.IO.IOException:由于意外>数据包格式,握手失败?

    有谁知道这意味着什么 System Net WebException 底层连接已关闭 发送时发生意外错误 gt System IO IOException 由于意外 握手失败 数据包格式 在 System Net Security SslS
  • (const T v) 在 C 中从来都不是必需的,对吗?

    例如 void func const int i 在这里 const是不必要的 因为所有参数都是按值传递的 包括指针 真的吗 C 中的所有参数确实都是按值传递 这意味着无论您是否包含该参数 实际参数都不会改变const or not 然而
  • 从 C 结构生成 C# 结构

    我有几十个 C 结构 我需要在 C 中使用它们 典型的 C 结构如下所示 typedef struct UM EVENT ULONG32 Id ULONG32 Orgin ULONG32 OperationType ULONG32 Size
  • 从成员函数指针类型生成函子

    我正在尝试简化 通过make fn 预处理参数的函子的生成 通过wrap 对于 arity 的成员函数n 生成函子基本上可以工作 但到目前为止只能通过显式指定成员函数的参数类型来实现 现在我想从它处理的成员函数类型生成正确的函子 struc
  • 为什么 clang 使用 -O0 生成低效的 asm(对于这个简单的浮点和)?

    我正在 llvm clang Apple LLVM 版本 8 0 0 clang 800 0 42 1 上反汇编此代码 int main float a 0 151234 float b 0 2 float c a b printf f c
  • libxml2 xmlChar * 到 std::wstring

    libxml2似乎将所有字符串存储在 UTF 8 中 如xmlChar xmlChar This is a basic byte in an UTF 8 encoded string It s unsigned allowing to pi
  • 使用 WF 的多线程应用程序的错误处理模式?

    我正在写一个又长又详细的问题 但只是放弃了它 转而选择一个更简单的问题 但我在这里找不到答案 应用程序简要说明 我有一个 WPF 应用程序 它生成多个线程 每个线程执行自己的 WF 处理线程和 WF 中的错误 允许用户从 GUI 端进行交互
  • 默认析构函数做了多少事情

    C 类中的默认析构函数是否会自动删除代码中未显式分配的成员 例如 class C public C int arr 100 int main void C myC new C delete myC return 0 删除 myC 会自动释放
  • asp.net网格分页的SQL查询

    我在用iBatis and SQLServer 使用偏移量和限制进行分页查询的最佳方法是什么 也许我添加该列ROW NUMBER OVER ORDER BY Id AS RowNum 但这只会阻止简单查询的数据访问 在某些情况下 我使用选择
  • 使用 mingw32 在 Windows 上构建 glew 时“DllMainCRTStartup@12”的多个定义

    我关注了这个主题 使用 mingw 使建筑物在 Windows 上闪闪发光 https stackoverflow com questions 6005076 building glew on windows with mingw 6005
  • 初始化 LPCTSTR /LPCWSTR [重复]

    这个问题在这里已经有答案了 我很难理解并使其正常工作 基本上归结为我无法成功初始化这种类型的变量 它需要有说的内容7 2E25DC9D 0 USB003 有人可以解释 展示这种类型的正确初始化和类似的值吗 我已查看此站点上的所有帮助 将项目
  • Visual Studio 2017 完全支持 C99 吗?

    Visual Studio 的最新版本改进了对 C99 的支持 最新版本VS2017现在支持所有C99吗 如果没有 C99 还缺少哪些功能 No https learn microsoft com en us cpp visual cpp
  • C语言声明数组没有初始大小

    编写一个程序来操纵温度详细信息 如下所示 输入要计算的天数 主功能 输入摄氏度温度 输入功能 将温度从摄氏度转换为华氏度 独立功能 查找华氏度的平均温度 我怎样才能在没有数组初始大小的情况下制作这个程序 include
  • 为什么文件更新时“如果较新则复制”不复制文件?

    我在 Visual Studio Express 中有一个解决方案 如下所示 The LogicSchemaC 中的类 将在运行时解析指定的 XML 文件 以下是在main的方法Program cs LogicSchema ls new L
  • C++、三元运算符、std::cout

    如何使用 C 用三元运算符编写以下条件 int condition1 condition2 condition3 int double result int or double std cout lt lt condition1 resul
  • 在 Xamarin 中获取 OutOfMemoryException

    java lang OutOfMemoryError 考虑增加 JavaMaximumHeapSize Java 执行时内存不足 java exe 我的 Visualstudio Xamarin 项目出现内存不足异常 请帮助我如何解决此问题
  • C#中为线程指定特殊的cpu

    我有 2 个线程 我想告诉其中一个在第一个 cpu 上运行 第二个在第二个 cpu 上运行 例如在具有两个 cpu 的机器中 我怎样才能做到这一点 这是我的代码 UCI UCIMain new UCI Thread UCIThread ne

随机推荐