拦截 Azure Function 主机关闭:刷新 Application Insights TelemetryClient

Posted

技术标签:

【中文标题】拦截 Azure Function 主机关闭:刷新 Application Insights TelemetryClient【英文标题】:Intercept Azure Function Host Shutdown: Flush Application Insights TelemetryClient 【发布时间】:2016-08-14 02:27:17 【问题描述】:

我正在使用 Azure Functions:主要是尝试将现有的网络作业迁移到 Azure Functions,现在是时候将 Application Insights 集成到我的一个函数中了。

所以基本上我只需要TelemetryClient 的一个实例,但这假设我能够在应用程序停止时刷新内存缓冲区。

我使用了 TimerTrigger,但它只是用于测试目的。

我引用了 Microsoft.ApplicationInsights nuget 包 (from this SO post),我的 run.csx 文件如下所示:

using System;
using Microsoft.ApplicationInsights;
using Microsoft.Azure.WebJobs;

public static void Run(TimerInfo myTimer, TraceWriter log)

    MyTimerJob.TelemetryClient.TrackEvent("AzureFunctionTriggered");
    log.Verbose($"C# Timer trigger function executed at: DateTime.Now");
    

public static class MyTimerJob

    public static readonly TelemetryClient TelemetryClient;

    static MyTimerJob()
        TelemetryClient = new TelemetryClient()
             InstrumentationKey = "MyInstrumentationKey" ;

        // When it shutdowns, we flush the telemty client.
        new WebJobsShutdownWatcher().Token.Register(() =>
        
            TelemetryClient.TrackEvent("TelemetryClientFlush");
            TelemetryClient.Flush();
        );
    

这个实现有点棘手……

我有一个静态的TelemetryClient 以确保我将重用同一个实例。 我尝试使用WebJobsShutdownWatcher 来检测主机何时停止,以便我可以刷新 TelemetryClient。

为了模拟应用程序关闭,我在底层 Web 应用程序中创建了一个 "test" 应用程序设置,并在我希望主机重新启动时对其进行修改:

很遗憾,这不起作用...我没有从应用洞察信息中心看到任何名称为 "TelemetryClientFlush" 的事件:

所以我现在想知道当azure函数主机停止时是否有任何方法可以拦截?

【问题讨论】:

您能否将 $log 语句添加到您的关闭回调中以确认代码完全运行。查看 WebJobsShutdownWatcher 源代码,需要遵循几个条件才能运行关闭回调:github.com/Azure/azure-webjobs-sdk/blob/master/src/… 【参考方案1】:

除了 Mathew 所描述的内容之外,您可能还想玩弄我们将在请求时传递的取消令牌。

如果您向函数添加CancellationToken 类型参数,我们将传入一个令牌,该令牌将在主机正常关闭时发出信号。使用它可能会让你接近你需要什么:

using System;
using System.Threading;
using Microsoft.ApplicationInsights;

public static readonly TelemetryClient TelemetryClient = new  TelemetryClient() InstrumentationKey = "MyInstrumentationKey" ;
public static bool first = true;
public static void Run(TimerInfo myTimer, TraceWriter log, CancellationToken token)

    if(first)
        token.Register(() =>
        
            TelemetryClient.TrackEvent("TelemetryClientFlush");
            TelemetryClient.Flush();
        );
        first = false;
    

    TelemetryClient.TrackEvent("AzureFunctionTriggered");
    log.Verbose($"C# Timer trigger function executed at: DateTime.Now");

【讨论】:

这样我可以存储取消令牌并注册将在主机关闭时执行的操作? 是的,如果尚未注册(即第一次调用您的函数),您需要注册该操作。当/如果令牌发出信号时,将调用该操作。 Fabio,我没有编辑我的问题或发布新答案,而是使用我使用的示例代码编辑了您的答案(这对于不熟悉 webjob sdk 的人可能很有用)。效果很好!!!谢谢。【参考方案2】:

虽然 Azure Functions 确实在 WebJobs SDK 之上运行,但它不在传统的 Kudu WebJobs 基础架构下运行。 WebJobsShutdownWatcher 实际上依赖于 Kudu 主机的功能,特别是 WEBJOBS_SHUTDOWN_FILE 指示的哨兵文件。基本上,当 Kudu 主机关闭时,它会触及观察者正在监视的这个文件。由于没有触及此类文件,因此不会触发您的代码。

我们可以进行更改以允许观察者按原样工作,或者我们可以为函数引入一种新模式。我在我们的 repo here 中记录了一个问题,跟踪这个建议。我认为场景很重要,我们会考虑一下。

【讨论】:

以上是关于拦截 Azure Function 主机关闭:刷新 Application Insights TelemetryClient的主要内容,如果未能解决你的问题,请参考以下文章

Azure Blob 存储异常“现有连接被远程主机强行关闭”

azure blob storage-无法从传输连接读取数据:现有连接被远程主机强行关闭

如何在页面刷新时保持活跃的onclick [关闭]

在 Azure 函数中禁用主机锁租约更新调用的日志记录

如何使用 id_token 从 Azure Function 应用程序获取 Azure access_token?

如何在 Visual Studio 中的不同端口上运行 Azure Function 应用程序