你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

监视无服务器事件处理

本文提供有关监视无服务器事件驱动体系结构的指南。

通过监视,可以深入了解系统的行为和运行状况。 可帮助你构建环境的整体视图、检索历史趋势、关联各种因素并衡量性能、消耗或错误率的变化。 使用监视,可以针对可能影响服务质量的条件或者与特定环境关系紧密的条件定义警报。

本文演示如何使用 Azure Monitor 监视使用事件中心Azure Functions 生成的无服务器应用程序。 本文探讨可监视的有用指标,介绍如何与 Application Insights 集成并捕获自定义指标,并提供代码示例。

假设

本文假设你有一个体系结构,如无服务器事件处理参考体系结构中所述。 基本上:

  • 事件到达 Azure 事件中心。
  • 触发函数应用来处理事件。
  • Azure Monitor 可用于体系结构。

Azure Monitor 中的指标

首先,我们需要确定需要哪些指标,然后才能开始制定有关体系结构的有用见解。 每个资源执行不同的任务,进而生成不同的指标。

事件中心的这些指标将有助于捕获有用的见解:

  • 传入请求数
  • 传出的请求数
  • 限制的请求数
  • 成功的请求
  • 传入消息数
  • 传出的消息数
  • 捕获的消息数
  • 传入字节数
  • 传出字节数
  • 捕获的字节数
  • 用户错误

同样,Azure Functions 中的这些指标也有助于捕获有用的见解:

  • 函数执行计数
  • 连接
  • 数据位于
  • 数据输出
  • HTTP 服务器错误
  • 请求
  • 应用程序队列中的请求数
  • 响应时间

使用诊断日志记录捕获见解

将上述指标一起分析,有助于制定和捕获以下见解:

  • 事件中心处理的请求速率
  • Azure Functions 处理的请求速率
  • 事件中心总吞吐量
  • 用户错误
  • Azure Functions 持续时间
  • 端到端延迟
  • 每个阶段的延迟
  • 丢失的消息数
  • 多次处理的消息数

若要确保事件中心捕获必要的指标,必须先启用诊断日志(默认情况下处于禁用状态)。 然后必须选择所需的日志,并将正确的 Log Analytics 工作区配置为发送日志的目标。

我们需要的日志和指标类别是:

  • OperationalLogs
  • AutoScaleLogs
  • KafkaCoordinatorLogs(适用于 Apache Kafka 工作负载)
  • KafkaUserErrorLogs(适用于 Apache Kafka 工作负载)
  • EventHubVNetConnectionEvent
  • AllMetrics

Azure 文档提供了有关如何为 Azure 事件中心设置诊断日志的说明。 以下屏幕截图显示了一个示例“诊断设置”配置面板,其中选择了正确的日志和指标类别,并将某个 Log Analytics 工作区设置为目标。 (如果使用外部系统分析日志,则可以改用“流式传输到事件中心”的选项。)

事件中心“诊断设置”配置面板的屏幕截图,其中显示了所选的正确日志和指标类别,以及设置为目标的 Log Analytics 工作区。

注意

若要利用日志诊断来捕获见解,应在不同的命名空间中创建事件中心。 这是因为 Azure 中的约束。

在给定事件中心命名空间中设置的事件中心在 Azure Monitor 指标中表示在名为 EntityName 的维度下。 在 Azure 门户中,通常可以在该 Azure Monitor 实例上查看特定事件中心的数据。 但是,当指标数据路由到日志诊断时,目前无法通过筛选 EntityName 维度来查看每个事件中心的数据。

解决方法是在不同的命名空间中创建事件中心,这样有助于查找特定中心的指标。

使用 Application Insights

可以启用 Application Insights,以从 Azure Functions 捕获指标和自定义遥测数据。 这样可以根据自己的具体目的定义分析,从而通过另一种方式获取无服务器事件处理方案的重要见解。

此屏幕截图显示了 Application Insights 中自定义指标和遥测的示例列表:

屏幕截图显示了 Application Insights 中自定义指标和遥测的示例列表。

默认自定义指标

在 Application Insights 中,Azure Functions 的自定义指标存储在 customMetrics 表中。 该表包括以下值,跨不同函数实例的时间线:

  • AvgDurationMs
  • MaxDurationMs
  • MinDurationMs
  • Successes
  • Failures
  • SuccessRate
  • Count

这些指标可用于高效计算在运行中调用的多个函数实例的聚合平均值。

此屏幕截图显示在 Application Insights 中查看这些默认自定义指标的界面:

屏幕截图显示在 Application Insights 中查看默认自定义指标的界面。

自定义消息

Azure Functions 代码中记录的自定义消息(使用 ILogger)是从 Application Insights traces 表中获取的。

traces 表具有以下重要属性(其中包括):

  • timestamp
  • cloud_RoleInstance
  • operation_Id
  • operation_Name
  • message

下面是 Application Insights 界面中的自定义消息示例:

屏幕截图显示 Application Insights“跟踪”数据表中的自定义消息的示例。

如果传入的事件中心消息或 EventData[] 记录为此自定义 ILogger 消息的一部分,则 Application Insights 中也会提供该消息。 此功能在某些情况下很有用。

对于无服务器事件处理方案,我们记录从事件中心接收的 JSON 序列化消息正文。 这使我们能够捕获原始字节数组,以及 SystemProperties(例如 x-opt-sequence-numberx-opt-offsetx-opt-enqueued-time)。 若要确定事件中心接收每条消息的时间,请使用 x-opt-enqueued-time 属性。

示例查询:

traces
| where timestamp between(min_t .. max_t)
| where message contains "Body"
| extend m = parse_json(message))
| project timestamp = todatetime(m.SystemProperties.["x-opt-enqueued-time"])

示例查询将返回类似于以下示例结果的消息,默认情况下,该消息记录在 Application Insights 中。 Trigger Details 的属性可用于按 PartitionIdOffsetSequenceNumber 查找和捕获关于已接收消息的其他见解。

示例查询的示例结果:

"message": Trigger Details: PartitionId: 26, Offset: 17194119200, EnqueueTimeUtc: 2020-11-03T02:14:01.7740000Z, SequenceNumber: 843572, Count: 10,

警告

Azure Java 函数库当前存在一个问题,该问题会在使用 EventHubTrigger 的情况下阻止对 PartitionIDPartitionContext 的访问。 在此 GitHub 问题报告中了解详细信息。

通过 Application Insights 使用事务 ID 跟踪消息流

在 Application Insights 中,可以通过对事务的 Operation Id 值执行事务搜索查询来查看与特定事务相关的所有遥测。 这对于捕获事务通过事件流管道时消息的平均时间的百分位值特别有用。

以下屏幕截图显示了 Application Insights 界面中的“事务搜索”示例。 在查询字段中输入所需的 Operation ID(该字段带有放大镜标识,并在此处以红色框显示)。 在主窗格的底部,Results 选项卡按顺序显示匹配的事件。 在每个事件条目中,Operation ID 值以深蓝色突出显示,以便于验证。

屏幕截图显示 Application Insights 界面中的“事务搜索”示例。

为特定操作 ID 生成的查询如下所示。 请注意,Operation ID GUID 在第三行的 where * has 子句中指定。 此示例将查询范围进一步缩小至两个不同的 datetimes 之间。

union isfuzzy=true availabilityResults, requests, exceptions, pageViews, traces, customEvents, dependencies
| where timestamp > datetime("2020-10-09T06:58:40.024Z") and timestamp < datetime("2020-11-11T06:58:40.024Z")
| where * has "1c8c9d7073a00e4bbdcc8f2e6570e46"
| order by timestamp desc
| take 100

下面是 Application Insights 界面中查询及其匹配结果的屏幕截图:

屏幕截图显示 Application Insights 界面的一部分,其中包含为特定操作 ID 生成的查询结果。实际查询显示在顶部区域中,匹配结果则列在下面。

从 Azure Functions 捕获自定义指标

.NET 函数

结构化日志记录在 .NET Azure 函数中用于捕获 Application Insights 跟踪表中的自定义维度。 然后,可以使用这些自定义维度来查询数据。

例如,下面是 .NET TransformingFunction 中的日志语句:

log.LogInformation("TransformingFunction: Processed sensorDataJson={sensorDataJson}, " +
    "partitionId={partitionId}, offset={offset} at {enqueuedTimeUtc}, " +
    "inputEH_enqueuedTime={inputEH_enqueuedTime}, processedTime={processedTime}, " +
    "transformingLatencyInMs={transformingLatencyInMs}, processingLatencyInMs={processingLatencyInMs}",
    sensorDataJson,
    partitionId,
    offset,
    enqueuedTimeUtc,
    inputEH_enqueuedTime,
    processedTime,
    transformingLatency,
    processingLatency);

在 Application Insights 上创建的结果日志包含上述参数作为自定义维度,如以下屏幕截图所示:

屏幕截图显示由之前的 C-sharp 代码示例在 Application Insights 中创建的日志。

可以按如下方式查询这些日志:

traces
| where timestamp between(min_t .. max_t)
// Function name should be of the function consuming from the Event Hub of interest
| where operation_Name == "{Function_Name}"
| where message has "{Function_Name}: Processed"
| project timestamp = todatetime(customDimensions.prop__enqueuedTimeUtc)

注意

为了确保不会影响这些测试中的性能,我们已使用 host.json 文件为 Application Insights 打开了 Azure Functions 日志的采样设置,如下所示。 这表示从日志记录捕获的所有统计信息都会被视为平均值,而不是实际计数。

host.json 示例:

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

Java 函数

目前,Java Azure 函数不支持结构化日志记录来捕获 Application Insights 跟踪表中的自定义维度。

例如,下面是 Java TransformingFunction 中的日志语句:

LoggingUtilities.logSuccessInfo(
    context.getLogger(), 
    "TransformingFunction", 
    "SuccessInfo", 
    offset, 
    processedTimeString, 
    dateformatter.format(enqueuedTime), 
    transformingLatency
);

在 Application Insights 上创建的结果日志在消息中包含上述参数,如下所示:

屏幕截图显示由之前的 Java 代码示例在 Application Insights 中创建的日志。

可以按如下方式查询这些日志:

traces
| where timestamp between(min_t .. max_t)
// Function name should be of the function consuming from the Event Hub of interest
| where operation_Name in ("{Function name}") and message contains "SuccessInfo"
| project timestamp = todatetime(tostring(parse_json(message).enqueuedTime))

注意

为了确保不会影响这些测试中的性能,我们已使用 host.json 文件为 Application Insights 打开了 Azure Functions 日志的采样设置,如下所示。 这表示从日志记录捕获的所有统计信息都会被视为平均值,而不是实际计数。

host.json 示例:

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

作者

本文由 Microsoft 维护, 它最初是由以下贡献者撰写的。

主要作者:

若要查看非公开的 LinkedIn 个人资料,请登录到 LinkedIn。