使用 OpenTelemetry Collector 扩展层观察 Lambda

从现代应用程序中获取遥测数据非常简单(或者至少应该如此)。您设置一个收集器,该收集器要么从您的应用程序接收数据,要么要求它提供各种计数器的最新状态。这大约每分钟发生一次,如果延迟一秒或提前一秒,没有人真的会注意到。但是,如果应用程序的运行时间很短呢?如果等待数据收集的每一秒都要收费呢?那么您很可能在考虑函数即服务 (FaaS) 环境,其中最知名的是 AWS Lambda。

在此执行模型中,函数被直接调用,然后环境被冻结。您只需为实际执行时间付费,不再需要服务器来等待传入请求。这也是“无服务器”一词的由来。让函数保持运行直到可以收集指标并不是一个真正的选择,即使您愿意为此付费,不同的调用也将具有完全独立的上下文,并且不一定会了解同时发生的所有其他执行。您现在可能会说:“我将在执行结束时推送所有数据,这里没有问题!”,但这并不能解决问题。您仍然需要为发送数据所需的时间付费,并且有很多调用会累加。

但还有另一种方法!Lambda 扩展层允许您在代码旁边运行任何进程,共享执行运行时并提供附加服务。通过 opentelemetry-lambda 扩展层,您将获得一个本地端点来发送数据,同时它会跟踪 Lambda 的生命周期并确保您的遥测数据被发送到存储层。

它是如何工作的?

当您的函数首次被调用时,扩展层会启动一个 OpenTelemetry Collector 实例。Collector 的构建是一个精简版本,仅提供 Lambda 上下文中必需的组件。它会向 Lambda Extensions APITelemetry API 注册。通过这样做,它会在您的函数被执行、发出日志行或执行上下文即将关闭时收到通知。

这里是奇迹发生的地方

到目前为止,这似乎只是无用的额外工作。您仍然需要等待 Collector 导出数据,对吗?这就是特殊的 decouple 处理器发挥作用的地方。它在与 Lambda 生命周期交互的同时,分离了接收和导出组件。这使得 Lambda 可以提前返回,即使并非所有数据都已发送。在下一次调用时(或在关闭时),Collector 会继续导出数据,而您的函数则执行其任务。

Diagram showcasing how execution timing differs with and without a Collector

展示有无 Collector 时执行时间差异的图表

我该如何使用它?

截至 2024 年 11 月,opentelemetry-lambda 项目已发布 Collector 扩展层的版本。它可以通过托管在 S3 存储桶或任意 HTTP 服务器上的配置文件进行配置。也可以将配置文件与您的 Lambda 代码捆绑在一起。在这两种情况下,您都需要考虑权衡。远程配置文件会增加冷启动时间,因为需要发出额外的请求;而捆绑配置文件则在尝试控制多个 Lambda 的配置时会增加管理开销。

最简单的入门方法是使用嵌入式配置。为此,请在您的函数中添加一个名为 collector.yaml 的文件。这是一个常规的 Collector 配置文件。要利用特定于 Lambda 的扩展,需要对其进行配置。例如,下一个示例配置从 Telemetry API 接收跟踪和日志,并将它们发送到另一个端点。

receivers:
  telemetryapi:
exporters:
  otlphttp/external:
    endpoint: 'external-collector:4318'
processors:
  batch:
  decouple:
service:
  pipelines:
    traces:
      receivers: [telemetryapi]
      processors: [batch, decouple]
      exporters: [otlphttp/external]
    logs:
      receivers: [telemetryapi]
      processors: [batch, decouple]
      exporters: [otlphttp/external]

如果省略 decouple 处理器,则默认配置。在此示例中,它被明确添加以说明整个管道。有关更多信息,请参阅 自动配置

之后,将 OPENTELEMETRY_COLLECTOR_CONFIG_URI 环境变量设置为 /var/task/collector.yaml。函数重新部署后,您将看到函数日志出现!您可以在下面的视频中看到这个过程。

您的 Lambda 生成的每一行日志都将发送到指定的 external-collector 端点。您根本不需要修改代码!从那里,遥测数据像往常一样流向您的后端。由于在 Lambda 未激活时遥测数据的传输可能会被冻结,因此日志可能会延迟到达。它们将在下次执行期间或关闭间隔期间到达。

如果您想进一步了解您的应用程序,还可以查看 特定语言的自动插装层

最后修改于 2025 年 2 月 5 日:feat: new blog post "Observing Lambdas" (#5990) (78deeaee)