是否有可能在 CosmosDB 的 Azure Function 中完美地监控 Change Feed 工作

Is it possible to monitor Change Feed work perfectly in Azure Function from CosmosDB

我有一个 Azure 函数,它会触发来自 CosmosDB 的 Change Feed,然后将其文档 ETL 到 MS SQL。但是当服务器(CosmosDB 或 Azure Function 主机)以某种方式承受压力时,提要会延迟几秒到几分钟甚至丢失。目前我有解决方法来防止数据工厂丢失并每天重新同步它。

现在我想实现监控的测量,比如延迟时间,成功或失败的提示,决定我是否应该放大DTU,或者做一些服务分析。我无法查询所有 Cosmos 和 SQL 来比较它们,尽管这是通过简单查询计数来检测丢失的最后一种方法。

这可能吗?

对于健康监控,您可以启用将健康监控检查发送到您的 App Insights:https://docs.microsoft.com/azure/cosmos-db/how-to-configure-cosmos-db-trigger-logs

通过以下方式启用日志记录:

{
  "version": "2.0",
  "logging": {
    "fileLoggingMode": "always",
    "logLevel": {
      "Host.Triggers.CosmosDB": "Trace"
    }
  }
}

这会捕获尝试执行检查点时触发器内部发生的任何严重错误(例如,租赁集合已被删除)。

至于延迟获取更改,最常见的原因详述如下:https://docs.microsoft.com/azure/cosmos-db/troubleshoot-changefeed-functions#my-changes-take-too-long-to-be-received

请记住,在大多数情况下,新批次的更改是在当前执行处理完当前批次后读取的。通常,如果您遵循 Functions best practices 并且 Functions 很苗条,它们不会造成问题,但是如果您看到您的 Function 需要很长时间来处理更改(某些东西不是线性的,例如,它处理 10 个事件1 秒,但 30 秒内有 50 个事件,这是您在 App Insights per Function execution 中看到的指标),它可能表明函数代码的复杂性不理想。

还有一种方法可以将 Change Feed Estimator 连接到另一个 Function,它基本上可以揭示您在 Change Feed 中落后的程度:https://medium.com/microsoftazure/azure-cosmos-db-functions-cookbook-monitoring-trigger-pending-work-800b24589235

想法是您可以使用 TimerTrigger 并将其与当前触发器配置混合以创建 Estimator 并使用它(有关完整说明,请参阅 post):

[FunctionName("Monitor")]
public static async Task Monitor(
    [TimerTrigger("*/1 * * * * *", RunOnStartup = true)] TimerInfo timer, // Timer will trigger every 1 second, adjust CRON expression
    [CosmosDB("%MonitoredDatabase%", "%MonitoredCollection%", ConnectionStringSetting = "CosmosDB")] DocumentClient monitoredCollectionClient, 
    [CosmosDB("%MonitoredDatabase%", "leases", ConnectionStringSetting = "CosmosDB")] DocumentClient leaseCollectionClient,
    ILogger log)
{
    var estimator = GetRemainingWorkEstimator(monitoredCollectionClient, leaseCollectionClient);
    var remainingWork = await estimator.GetEstimatedRemainingWork();
    // Send custom metric to App Insight
    log.LogInformation(remainingWork.ToString());
    log.LogMetric("RemainingWork", remainingWork);
}