使用AWS X-ray在Lambda中使用node.js时出现错误:“无法从上下文中获取当前子/段”。

23

我正在尝试将AWS X-ray集成到我的项目中(使用Node.js和Serverless框架)。我正在尝试将X-ray连接到我的一个Lambda函数上,但是我遇到了问题。

Error: Failed to get the current sub/segment from the context.
    at Object.contextMissingRuntimeError [as contextMissing] (/.../node_modules/aws-xray-sdk-core/lib/context_utils.js:21:15)
    at Object.getSegment (/.../node_modules/aws-xray-sdk-core/lib/context_utils.js:92:45)
    at Object.resolveSegment (/.../node_modules/aws-xray-sdk-core/lib/context_utils.js:73:19).....

以下是代码:

import { DynamoDB } from "aws-sdk";
import AWSXRay from 'aws-xray-sdk';

export const handler = async (event, context, callback) => {

    const dynamo = new DynamoDB.DocumentClient({
        service: new DynamoDB({ region })
    });

    AWSXRay.captureAWSClient(dynamo.service);

    try {
        // call dynamoDB function 
    } catch(err) {
        //...
    }
}

对于这个问题,我使用了来自https://forums.aws.amazon.com/thread.jspa?messageID=821510&#821510的解决方案。

我尝试过的另一个解决方案来自https://forums.aws.amazon.com/thread.jspa?messageID=829923&#829923

代码如下:

import AWSXRay from 'aws-xray-sdk';
const AWS = AWSXRay.captureAWS(require('aws-sdk'));

export const handler = async (event, context, callback) => {

    const dynamo = new AWS.DynamoDB.DocumentClient({region});

    //....
}

依然无法正常工作...

感激任何形式的帮助。


1
你在什么时候遇到这个错误?是在本地测试时吗?正如错误信息所说,你的上下文对象(第二个参数)似乎缺少所需的片段。X-Ray想要使用它们,以便跟踪调用去哪里,每个操作需要多长时间等等。因此,它需要一个有效的上下文。(当我运行带有虚假上下文对象的本地测试时,我也遇到了同样的问题。) - Hieron
1
@Hieron 感谢您的回复。实际上,我正在使用无服务器框架,并且我使用了 serverless-offline 插件来帮助我在本地运行。这个上下文是真实的还是假的?我使用的解决方案是启用 Lambda 函数中的配置。 - pyy
1
好的,所以你正在本地运行,所以问题可能是上下文与实际在AWS上运行时不完全相同。这也意味着它可能不是AWS / Lambda的问题,而是无服务器离线插件的问题。也许可以在他们的Github页面上询问他们? - Hieron
1
@pyy,解决方案是什么? - Victor P
1
@VictorP 目前,我正在使用一项Lambda功能,通过在管理控制台或CloudFormation模板中启用X-ray跟踪来实现。因此,X-ray现在可以跟踪Lambda。稍后我会花些时间尝试将X-ray与其他AWS服务配合使用。 - pyy
3个回答

16

正如您所提到的,这是因为您正在本地运行(使用 serverless-offline 插件),而 serverless-offline 插件没有提供有效的 XRAY 上下文。

解决此错误并仍能在本地调用您的函数的一种可能方式是将 AWS_XRAY_CONTEXT_MISSING 环境变量 设置为 LOG_ERROR 而不是默认值的 RUNTIME_ERROR

像这样

serverless invoke local -f functionName -e AWS_XRAY_CONTEXT_MISSING=LOG_ERROR

我没有使用serverless框架进行测试,但当出现相同的错误时,在本地调用amplify函数时它可以工作:

amplify function invoke <function-name>

3
在我的情况下,通过在.env中指定AWS_XRAY_CONTEXT_MISSING=IGNORE_ERROR有所帮助,LOG_ERROR则没有起到作用。 - Oleksandr Grin

6
我也遇到了这个错误。为了解决它,我在本地运行时禁用了XRay。在本地运行时不需要XRay,因为我可以在那时设置调试日志语句。
以下是代码示例:
let AWS = require('aws-sdk');
if (!process.env.IS_OFFLINE) {
    const AWSXRay = require('aws-xray-sdk');
    AWS = AWSXRay.captureAWS(require('aws-sdk'));
}

如果您不喜欢这种方法,您可以设置一个上下文策略来避免在上下文丢失时出错。

链接在此

AWSXRay.setContextMissingStrategy("LOG_ERROR");

0

如果您不想让错误信息混杂在输出中,可以添加一个帮助程序来忽略该错误。

// Removes noisy Error: Failed to get the current sub/segment from the context due to Xray
export async function disableXrayError() {
  console.error = jest.fn((err) => {
    if (err.message.includes("Failed to get the current sub/segment from the context")) {
      return;
    } else {
      console.error(err);
    }
  });
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接