OneUptime 无服务器函数可观测性实战:基于 faas.name 的自动发现与 OTLP 接入指南
【免费下载链接】oneuptimeComplete open-source monitoring and observability platform.项目地址: https://gitcode.com/GitHub_Trending/on/oneuptime
在 AWS Lambda、Cloudflare Workers 等 FaaS 运行时上运行函数时,传统的服务监控视角往往难以覆盖短生命周期、弹性伸缩的执行实例。本文基于 OneUptime 的官方文档 Serverless Functions 展开,讲清楚 OneUptime 如何通过faas.name资源属性自动识别 Serverless Function、如何用标准 OTLP 环境变量完成接入,并结合仓库源码剖析自动发现、心跳保活、实例登记与规则引擎背后的真实实现,帮助你从零完成一个函数的全链路可观测接入。
工作原理:收到带 faas.name 的遥测数据即自动建档
OneUptime 无需手工创建任何"函数"实体:只要平台收到带有faas.name资源属性的 OpenTelemetry 数据,对应函数就会自动出现在Serverless Functions视图中,并聚合该函数的 traces、logs 与 metrics。这一机制适用于任何能产出 OpenTelemetry 数据的 FaaS 运行时——AWS Lambda、Google Cloud Functions、Azure Functions、Cloudflare Workers 均可。
从源码实现看,这个自动发现逻辑集中在 OTel 摄取基类的静态方法autoDiscoverServerless中,它在每一条摄取路径上运行(而不是某个专用端点),保证即使同时设置了service.name,函数遥测数据也能正确落到 Serverless 资源下:
- 身份(Identity)判定:优先取资源属性
faas.name作为函数身份;若该数据来自 FaaS 平台但没有faas.name,则回退到service.name。FaaS 平台的判定依据是cloud.platform归一化后是否落在共享注册表FAAS_CLOUD_PLATFORM_VALUES(定义于 CloudPlatform)中,该共享注册表同时被 Serverless 与 Cloud Environment 两个产品消费,从结构上避免了两者对同一平台的归属冲突; - 门控(Gate):必须同时满足"有函数身份"且"存在 FaaS 信号(
faas.name或 FaaS 平台标记)"两个条件,否则直接返回null,普通微服务数据不会被误判为函数——见 autoDiscoverServerless; - 缓存:
projectId:函数标识组合的实体 ID 会缓存 24 小时(SERVERLESS_FUNCTION_ID_CACHE_EXPIRY_SECONDS),稳态摄取下无需反复查库; - 实例登记:若资源属性中带有
faas.instance,会同步调用ServerlessFunctionInstanceService.recordInstance记录该函数实例,支撑Instances标签页的实时实例统计,见 实例登记逻辑。
// App/FeatureSet/Telemetry/Services/OtelIngestBaseService.ts(节选,L2007-L2019) // Identity: prefer faas.name; on a FaaS platform fall back to service.name. let functionIdentifier: string | null = faasName; if (!functionIdentifier && isFaasPlatform) { functionIdentifier = this.getStringAttribute( data.attributes, "service.name", ); } // Gate: need a function identity AND a FaaS signal (faas.name or platform). if (!functionIdentifier || (!faasName && !isFaasPlatform)) { return null; }一个同时设置了
service.name的函数,也会照常出现在Services视图中。Serverless Functions视图是按faas.name作用域的 FaaS 聚焦视角,二者并行不冲突。
前置条件
接入前需要准备两样东西:
- OneUptime 遥测摄取令牌(Telemetry Ingestion Token):在控制台Project Settings → Telemetry & APM → Ingestion Keys中创建,并复制
x-oneuptime-token的值; - 你所用函数语言的OpenTelemetry SDK(或自动埋点层,如 AWS Lambda 的 OTEL layer、各语言的 auto-instrumentation 包)。
资源属性规范:OneUptime 靠什么识别一个函数
OneUptime 以faas.name作为函数身份键,各属性取值及其作用如下:
| 属性 | 是否必需 | 用途 |
|---|---|---|
faas.name | 是 | 函数身份(例如checkout-handler) |
faas.version | 否 | 显示在概览页 |
faas.instance | 否 | 按实例登记,展示在Instances标签页 |
cloud.platform | 否 | aws_lambda、gcp_cloud_functions、azure_functions等 |
cloud.provider/cloud.region/cloud.account.id | 否 | 显示在概览页 |
这些属性在摄取侧并非只用于"显示"。源码中updateLastSeen会把它们写入函数行的 metadata 字段,并额外采集process.runtime.name/process.runtime.version作为运行时信息,见 自动发现与元数据落库:
await ServerlessFunctionService.updateLastSeen(functionId, { agentVersion: agentVersion || undefined, cloudPlatform: cloudPlatform || undefined, cloudProvider: this.getStringAttribute(data.attributes, "cloud.provider") || undefined, cloudRegion: this.getStringAttribute(data.attributes, "cloud.region") || undefined, cloudAccountId: this.getStringAttribute(data.attributes, "cloud.account.id") || undefined, functionVersion: this.getStringAttribute(data.attributes, "faas.version") || undefined, runtimeName: this.getStringAttribute(data.attributes, "process.runtime.name") || undefined, runtimeVersion: this.getStringAttribute(data.attributes, "process.runtime.version") || undefined, });步骤一:配置 OTLP 导出器环境变量
大多数语言的自动埋点方案都遵循标准 OpenTelemetry 环境变量约定,因此只需在函数运行时环境中设置:
OTEL_EXPORTER_OTLP_ENDPOINT="https://oneuptime.com/otlp" OTEL_EXPORTER_OTLP_HEADERS="x-oneuptime-token=YOUR_TELEMETRY_INGESTION_TOKEN" OTEL_RESOURCE_ATTRIBUTES="faas.name=checkout-handler,faas.version=1.4.2"其中:
OTEL_EXPORTER_OTLP_ENDPOINT指向 OneUptime 的 OTLP 入口。若你自托管 OneUptime,请将主机替换为自己的域名,即https://YOUR-ONEUPTIME-HOST/otlp;OTEL_EXPORTER_OTLP_HEADERS携带摄取令牌,作为数据归属项目的鉴权凭据;OTEL_RESOURCE_ATTRIBUTES用于补充 SDK 不会自动设置的资源属性——尤其是要明确声明faas.name,这是自动发现的第一优先级身份来源。
步骤二:AWS Lambda 添加 OpenTelemetry Layer
对 AWS Lambda,最简单的路径是官方提供的 OpenTelemetry Lambda layer:为你的运行时附上对应 layer,并配置以下环境变量:
AWS_LAMBDA_EXEC_WRAPPER=/opt/otel-handler OTEL_EXPORTER_OTLP_ENDPOINT=https://oneuptime.com/otlp OTEL_EXPORTER_OTLP_HEADERS=x-oneuptime-token=YOUR_TELEMETRY_INGESTION_TOKEN该 layer 会通过AWS_LAMBDA_EXEC_WRAPPER包装函数执行过程,自动完成埋点并:
- 从函数名自动填充
faas.name; - 由资源检测器(resource detector)自动补全
cloud.platform、cloud.region、cloud.account.id。
这意味着在 Lambda 场景下你甚至不需要手写faas.name——只要 layer 正确挂载,OneUptime 侧的自动发现门控条件即已满足。
实体生命周期:从创建、心跳到断连判定
函数实体并非"建一次就完事",OneUptime 在 ServerlessFunctionService 中维护了一套完整的生命周期语义:
1. 幂等创建(大小写不敏感)
findOrCreateByFunctionIdentifier以"项目 + 函数标识"为键做大小写不敏感查询。源码注释解释了这样设计的原因:唯一性约束本身是大小写不敏感的,若用大小写敏感的查询,会在faas.name大小写漂移时漏掉已有行、继而因"重名"创建失败而卡住摄取(wedge ingest);查询到已存在行时直接复用,create抛出的竞态异常(并发请求同时创建)则通过重新查询兜底,见 findOrCreateByFunctionIdentifier。
2. 带节流的心跳
每次自动发现命中后都会触发updateLastSeen,但落库通过ResourceHeartbeat.write做门控:同一函数 60 秒内(LAST_SEEN_THROTTLE_SECONDS)只写一次"存活"状态,metadata 字段按指纹去重,避免高频遥测把数据库写满。函数行创建时即标记otelCollectorStatus = "connected"并写入lastSeenAt。
3. 断连判定
后台任务markDisconnectedFunctions将lastSeenAt超过15 分钟且状态仍为connected的函数标记为disconnected。源码注释特别说明了 15 分钟阈值的由来:OTel 摄取存在约 5 分钟的维护围栏(maintenance fence),遥测持续到达时lastSeenAt合法地滞后近 5 分钟,阈值若贴着围栏 TTL 会导致健康资源状态抖动,因此取 3 倍余量,见 markDisconnectedFunctions。
4. 创建即套用标签与负责人规则
函数首次被创建时(onCreateSuccess钩子),系统会异步链式执行两个规则引擎:
- ServerlessFunctionLabelRuleEngineService:按Serverless → Settings → Label Rules中配置的规则自动打标签;
- ServerlessFunctionOwnerRuleEngineService:按 Owner Rules 自动分配负责人。
此外attachLabels采用只做加法的策略:手动在 UI 上设置的标签永不被摄取流程移除;且标签集合会以 SHA1 指纹缓存 60 秒,标签集不变时稳态摄取只产生一次内存查找。
接入后你能看到什么
函数只要发出过任意 span、log 或 metric,即出现在Serverless Functions列表中。概览页提供:
- Invocations(调用量)、error rate(错误率)、p95 duration(p95 耗时)——从 trace 数据推导,支持选择时间范围并展示趋势图;
- Instances——当前观测到的
faas.instance取值的实时计数(由上文的recordInstance登记驱动); - 完整的Logs、Traces、Metrics标签页,均按该函数的
resource.faas.name作用域过滤; - 通过Serverless → Settings → Label Rules / Owner Rules对新自动发现的函数自动套用标签与负责人。
小结:接入要点回顾
| 关注点 | 关键结论 |
|---|---|
| 身份来源 | faas.name优先;FaaS 平台上可回退service.name |
| 必需动作 | 配置 OTLP endpoint/headers 环境变量并声明faas.name |
| Lambda 捷径 | 官方 OTEL layer +AWS_LAMBDA_EXEC_WRAPPER=/opt/otel-handler,自动填充函数名与云属性 |
| 实体生命周期 | 幂等创建(大小写不敏感)→ 60 秒节流心跳 → 15 分钟无数据判断连 |
| 元数据 | faas.version、cloud.*、process.runtime.*均落入函数行 metadata 并展示在概览 |
| 规则自动化 | 创建时自动执行 Label Rules / Owner Rules;标签只做加法、不覆盖手动设置 |
需要说明的适用前提:以上机制以当前仓库代码为准,依赖函数运行时能够向https://<你的 OneUptime 主机>/otlp发起出站请求(自托管时需公网可达);faas.instance若运行时不提供则 Instances 视图无数据,但不影响函数本身的识别与指标聚合。
【免费下载链接】oneuptimeComplete open-source monitoring and observability platform.项目地址: https://gitcode.com/GitHub_Trending/on/oneuptime
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考