You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vercel Serverless Functions集成Elastic APM无数据接收问题求助

NextJS + Elastic APM 在Vercel Serverless环境下无法上报数据的问题及解决办法

问题详情

我把NextJS应用和Elastic APM做了集成,核心逻辑是在每个API请求里初始化apm对象,收集请求链路并发送到Elastic APM。这套方案在本地开发和Docker部署环境都能正常工作,但部署到Vercel转为Serverless Functions后,Elastic APM始终收不到数据。

Serverless函数日志最后一行显示APM在尝试发送span,但数据没到APM服务器:

{
    "log.level": "debug",
    "@timestamp": "2024-04-18T08:45:47.694Z",
    "log.logger": "elastic-apm-node",
    "ecs.version": "8.10.0",
    "message": "sending span {\"span\":\"08ffc510e6b2a80d\",\"parent\":\"42b99f30dbacb024\",\"trace\":\"f03e53c3d6846a888f8f69c753b3aa81\",\"name\":\"POST xxxx.ingest.sentry.io\",\"type\":\"external\"}"
}

我的APM初始化文件apm.ts代码:

import apm from 'elastic-apm-node';

if (!apm.isStarted()) {
    apm.start({
        // 配置信息
    });
}

export default apm;

API处理文件apiHandler.ts中设置上下文的代码:

apm.setUserContext({
    email: session.user.email,
    id: session.user.id,
});
apm.setCustomContext({});

本地环境的APM能正常显示应用数据,但Vercel部署后完全没数据。

核心原因

Vercel Serverless Functions是短生命周期的无状态函数,函数执行完成后会立刻被销毁。而Elastic APM Node.js agent默认是异步发送数据的,这就导致函数结束时,APM的上报请求还没发完就被终止,数据根本传不到服务器。

解决步骤

  1. 强制等待APM数据上报完成
    在API请求处理的最后,手动调用apm.flush()并等待它执行完毕,确保所有未发送的APM数据都提交成功。修改apiHandler.ts:

    // 放在请求响应返回前的最后一步
    await apm.flush();
    

    如果用的是App Router的Server Components或者getServerSideProps,一定要保证在请求生命周期结束前执行这个操作。

  2. 核对Vercel环境下的APM配置
    确保APM的serverUrl、secretToken、serviceName这些核心配置是通过Vercel环境变量传递的(别硬编码),并且在初始化时明确指定环境标识:

    apm.start({
        serviceName: 'your-service-name',
        serverUrl: process.env.ELASTIC_APM_SERVER_URL,
        secretToken: process.env.ELASTIC_APM_SECRET_TOKEN,
        environment: process.env.NODE_ENV || 'production',
        logLevel: 'debug' // 开启调试方便排查
    });
    
  3. 检查Vercel网络权限
    Vercel Serverless Functions对外请求有默认限制,要确认Elastic APM的服务地址在Vercel的出站白名单里。如果是私有部署的APM服务,可能需要配置Vercel的VPC访问或者使用代理。

  4. 调整APM Agent的适配参数
    针对Serverless的短生命周期特性,调整Agent的超时和队列设置,避免函数超时:

    apm.start({
        // 其他配置
        apiRequestTime: 5000, // 上报请求超时时间,单位毫秒
        apiRequestSize: 768 * 1024,
        queueLimit: 1000
    });
    
  5. 验证函数执行时长
    查看Vercel函数的执行日志,确认函数是在apm.flush()完成后才结束的。如果函数执行时间太短,可以加一点微小延迟,但别太长,避免影响性能。

内容的提问来源于stack exchange,提问作者Ilham Fadhilah

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 19:03:22