我正在使用Express,每次使用日志调试和跟踪应用程序时,我都需要访问请求中的一些数据(标头、Cookie等)。使用其他语言(即:Java)我有一个“线程上下文”,我可以把数据放在那里,所以每当我记录一些东西时就可以访问它。但是就我所知,NodeJS没有这样的东西,因为我们只有一个线程。我试图避免在每个函数中传递req变量,以便记录该信息。是否有node或expressjs特性可以让我从任何地方获取数据?
req
7cwmlq891#
AsyncLocalStorage
https://nodejs.org/api/async_context.html
看看Continuation Local Storage,它实现了类似于异步调用链的线程上下文的东西:https://github.com/othiym23/node-continuation-local-storage还有一些人试图将异步本地存储作为一个标准化特性构建到JavaScript本身中,但他们仍然处于非常早期的阶段:TC39分区建议https://docs.google.com/presentation/d/1H3E2ToJ8VHgZS8eS6bRv-vg5OksObj5wv6gyzJJwOK0
fhg3lkii2#
AsyncLocalStorage维护一个独立的存储上下文,这可能是在请求生命周期的后续函数中访问请求上下文的方式(仅当req未传递给异步函数时)。以下是将值推送到AsyncLocalStorage的方法:
const asyncStorage = new AsyncLocalStorage(); const requestLoggerMiddleWare = (req, res, next) => { asyncStorage.run(new Map(), () => { asyncStorage.getStore().set('key', req.get('example-header')); next(); }); }; app.use(requestLoggerMiddleWare)
在异步函数调用被解析之前,此值可以在任何函数中使用。
const exampleHeader = asyncStorage.getStore().get('example-header');
osh3o9ms3#
JavaScript是单线程的这一事实并不是一个限制,也不妨碍使用“线程上下文”作为使用“普遍可访问状态”的一种手段。一旦进行异步调用,状态不再符合您的预期,问题就会出现。这就是为什么全局状态被认为是“坏习惯”的原因之一,您应该努力避免它(尤其是在JavaScript和/或Node中开发时...)。相反,你应该传递一个对象,而不是req。你应该构造你的对象或调用你的函数,这样与每个调用链相关的log示例(从请求事件开始并通过所有内部调用)。应该使用日志记录所需的任何上下文初始化log示例,在您的情况下,来自原始req的请求细节。
log
3条答案
按热度按时间7cwmlq891#
AsyncLocalStorage
类似于其他语言中的线程本地存储。https://nodejs.org/api/async_context.html
看看Continuation Local Storage,它实现了类似于异步调用链的线程上下文的东西:https://github.com/othiym23/node-continuation-local-storage
还有一些人试图将异步本地存储作为一个标准化特性构建到JavaScript本身中,但他们仍然处于非常早期的阶段:TC39分区建议https://docs.google.com/presentation/d/1H3E2ToJ8VHgZS8eS6bRv-vg5OksObj5wv6gyzJJwOK0
fhg3lkii2#
AsyncLocalStorage维护一个独立的存储上下文,这可能是在请求生命周期的后续函数中访问请求上下文的方式(仅当
req
未传递给异步函数时)。以下是将值推送到
AsyncLocalStorage
的方法:在异步函数调用被解析之前,此值可以在任何函数中使用。
osh3o9ms3#
JavaScript是单线程的这一事实并不是一个限制,也不妨碍使用“线程上下文”作为使用“普遍可访问状态”的一种手段。一旦进行异步调用,状态不再符合您的预期,问题就会出现。
这就是为什么全局状态被认为是“坏习惯”的原因之一,您应该努力避免它(尤其是在JavaScript和/或Node中开发时...)。
相反,你应该传递一个对象,而不是
req
。你应该构造你的对象或调用你的函数,这样与每个调用链相关的log
示例(从请求事件开始并通过所有内部调用)。应该使用日志记录所需的任何上下文初始化log
示例,在您的情况下,来自原始req
的请求细节。