1 回答

TA貢獻1828條經驗 獲得超6個贊
看起來他們使用 Node.js 域(https://nodejs.org/api/domain.html)為每個請求創建一個單獨的“上下文”。
從 Sentry 文檔中,您需要使用 requestHandler 才能正常工作。
例如對于快遞(https://docs.sentry.io/platforms/node/express/):
const express = require('express');
const app = express();
const Sentry = require('@sentry/node');
Sentry.init({ dsn: 'https://[email protected]/1240240' });
// The request handler must be the first middleware on the app
app.use(Sentry.Handlers.requestHandler());
// All controllers should live here
app.get('/', function rootHandler(req, res) {
res.end('Hello world!');
});
處理程序看起來像這樣:
(來自:@sentry/node/dist/handlers.js)
function requestHandler(options) {
return function sentryRequestMiddleware(req, res, next) {
if (options && options.flushTimeout && options.flushTimeout > 0) {
// tslint:disable-next-line: no-unbound-method
var _end_1 = res.end;
res.end = function (chunk, encoding, cb) {
var _this = this;
sdk_1.flush(options.flushTimeout)
.then(function () {
_end_1.call(_this, chunk, encoding, cb);
})
.then(null, function (e) {
utils_1.logger.error(e);
});
};
}
var local = domain.create();
local.add(req);
local.add(res);
local.on('error', next);
local.run(function () {
core_1.getCurrentHub().configureScope(function (scope) {
return scope.addEventProcessor(function (event) { return parseRequest(event, req, options); });
});
next();
});
};
}
exports.requestHandler = requestHandler;
因此,您可以看到根據新請求創建的新域。
我主要是通過發現這個問題來找到這個信息的:https : //github.com/getsentry/sentry-javascript/issues/1939
如果您想將“上下文”添加到 Node 后端的其他異步部分(例如,如果您有工作人員/線程/某些工作不是從 HTTP 請求啟動的……),上面的問題中有一些示例說明了如何實現完成(通過手動創建集線器/域..)。
如果您有興趣,現在也可以使用 async_hooks 來保持 Node.js 中具有各種異步函數/回調/setTimeouts 的上下文的某種意義:https ://nodejs.org/api/async_hooks.html
這是一個很好的介紹:
https://itnext.io/request-id-tracing-in-node-js-applications-c517c7dab62d?
以及一些實現此功能的庫:
https://github.com/Jeff-Lewis/cls-hooked
https://github.com/vicanso/async-local-storage
例如,這樣的事情應該工作:
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;
}
添加回答
舉報