我们如何 dynamic-scoping 在 NodeJs 中实现事务跟踪?

How to we do dynamic-scoping to implement transaction tracing in NodeJs?

我正在构建一个客户端和一个服务器端框架 (NodeJs),我想在其中跟踪事务。 我可以在客户端和服务器之间传递 headers (transaction_id),但是,我希望能够自动设置 transaction_id。 这意味着如果定义了 header,中间件应该能够在上下文中读取和设置事务 ID,以便 down-stream 调用可以读取它。

构建包装器不在问题范围内。我正在苦苦挣扎的是能够动态创建一个范围并在那里存储值。

注意 – 我正在使用 'strict' 模式,该模式不允许在节点中进行动态范围界定。所以需要另一种方式。 注意 – 我正在使用 Promises 进行 client-server 调用。

Sequelize,最流行的 orm 之一使用模块 continuation local storage

希望对你有所帮助

这是我最终解决的方法 –

我使用了 CLS,它允许我们跟踪动态范围。

阅读有关 CLS 的所有文本需要一段时间,所以这里是我所做的总结(外行术语)

注意 - 我在 'strict' 模式下使用 NodeJs。这意味着我不能使用动态范围。鉴于它是一个生产系统,我想保持严格模式。因此,实现动态范围的另一种方法。

1) CLS 创建动态 context/scope。这使我们能够设置/获取仅在我们处于创建的范围内之前可见的键值对。

2) 因为我使用的是 Bluebird 的 Promises,CLS 要求我使用补丁来保持 context/scope 在 Promises 中可用。 https://www.npmjs.com/package/cls-bluebird

3) 将 CLS 与 Promises 结合使用需要时间来弄清楚。这是关于不同图书馆如何使用 CLS 产生不同结果的精彩讨论。 https://github.com/TimBeyer/cls-bluebird/issues/6

4) 这就是我使用 CLS 的方式(释义和简化)–

var cls = require('continuation-local-storage');
var clsbluebird = require('cls-bluebird');
var namespace = cls.createNamespace('ns');
clsbluebird( namespace );

var result;
namespace.run(function() {
  namespace.set('key', 'value');
  result = abc(); // returns 'value'
});

// versus doing –
result = abc(); // returns undefined

function abc() {
  return namespace.get('key');
}

5) Usecase——通过这种方式,我实现了基本的交易跟踪。例如。 NewRelic、Trace 等