Javascript Sentry.io在asynchronous Node.js服务器上管理错误范围/上下文

Javascript Sentry.io在asynchronous Node.js服务器上管理错误范围/上下文,javascript,node.js,asynchronous,scope,sentry,Javascript,Node.js,Asynchronous,Scope,Sentry,基本上,Node.js中有并发请求。 而且,您可能希望使用特定于每个请求的数据来丰富可能的错误。 此请求特定的数据可以通过以下方式在应用程序的不同部分收集: Sentry.configureScope(scope=>scope.setSomeUsefulData(…) Sentry.addBreadcrumb({…}) 稍后在深层嵌套异步函数调用中的某个地方抛出错误。 Sentry如何知道之前收集的哪些数据实际上与此特定错误相关,考虑到请求是同时处理的,并且在发生错误时,无法访问某些Sent

基本上,Node.js中有并发请求。 而且,您可能希望使用特定于每个请求的数据来丰富可能的错误。 此请求特定的数据可以通过以下方式在应用程序的不同部分收集:

  • Sentry.configureScope(scope=>scope.setSomeUsefulData(…)
  • Sentry.addBreadcrumb({…})
稍后在深层嵌套异步函数调用中的某个地方抛出错误。 Sentry如何知道之前收集的哪些数据实际上与此特定错误相关,考虑到请求是同时处理的,并且在发生错误时,无法访问某些Sentry“范围”以获取与导致错误的此特定请求相关的数据

还是我必须通过所有函数调用传递sentry范围?像

server.on('request',(requestContext)=>{
//创建新的哨兵范围
Sentry.configureScope(sentryScope=>{
getProductById(id,sentryScope);//并将其传递给
});
});
//一直到。。。
函数parseNumber(输入,sentryScope){
// ...
}

或者哨兵是否使用某种魔法将特定数据映射到相关事件?还是我遗漏了什么?

似乎他们使用Node.js Domains()为每个请求创建单独的“上下文”

从Sentry文档中,您需要使用requestHandler才能正常工作

例如,对于express():

处理程序如下所示:

(发件人:@sentry/node/dist/handlers.js)

因此,您可以看到根据新请求创建的新域

我发现这些信息主要是通过发现以下问题:

如果您希望将“上下文”添加到节点后端的其他异步部分(例如,如果您的工作线程/某些工作不是从HTTP请求启动的…),则上述问题中的示例说明了如何做到这一点(通过手动创建集线器/域…)

如果您感兴趣,现在还可以使用async_钩子在Node.js中使用各种异步函数/回调/设置超时保持一定的上下文感:

这是一个很好的介绍:

?

以及一些实现此功能的图书馆:

例如,类似这样的方法应该有效:

const ALS = require("async-local-storage");

function withScope(fn, requestId) {
  ALS.scope();
  ALS.set("requestId", requestId, false);
  return await fn();
}

async function work() {
  try {
    await part1();
    await part2();
  } catch(e) {
     Sentry.withScope((scope) => {
       scope.setTag("requestId", ALS.get("requestId"));
       Sentry.captureException(new Error("..."))
     }) 
  }
}

withScope(work, "1234-5678");

不过,您必须自己跟踪面包屑,例如,要添加面包屑:

ALS.set("breadcrumbs", [...ALS.get("breadcrumbs"), new_breadcrumb]);
您需要在Sentry中的beforeSend()回调中手动设置这些参数:

beforeSend: function(data) {
  data.breadcrumbs = ALS.get("breadcrumbs");
  return data;
}
ALS.set("breadcrumbs", [...ALS.get("breadcrumbs"), new_breadcrumb]);
beforeSend: function(data) {
  data.breadcrumbs = ALS.get("breadcrumbs");
  return data;
}