【问题标题】:How to enable NODE_DEBUG without environment variables?如何在没有环境变量的情况下启用 NODE_DEBUG?
【发布时间】:2016-08-25 01:46:31
【问题描述】:

我正在尝试调试在 AWS Lambda 环境(Node.js 4.3)中运行时在 node.js https 库环境中出现的套接字错误。此问题仅在高度间歇性且仅在重负载下发生。我的团队已经能够通过负载测试一致地重现该问题,我们希望从 https 模块启用调试日志记录。

我在节点文档中发现,我可以通过设置NODE_DEBUG=https 环境变量来启用调试日志记录。但是,我不相信我可以设置环境变量:How can I use environmental variables on AWS Lambda?。此外,我无法更改 Lambda 用来调用我的函数的命令行。

是否有另一种方法可以创建与设置 NODE_DEBUG 相同的调试日志记录?

【问题讨论】:

    标签: node.js aws-lambda node-debugger


    【解决方案1】:

    这是一个猴子补丁:

    const util    = require('util');
    let debuglog  = util.debuglog;
    util.debuglog = set => {
      if (set === 'https') {
        let pid = process.pid;
        return function() {
          let msg = util.format.apply(util, arguments);
          console.error('%s %d: %s', set, pid, msg);
        }
      }
      return debuglog(set);
    }
    
    // This has to occur _after_ the code above:
    const https = require('https');
    

    它基本上启用了https 的调试日志记录,而不管$NODE_DEBUG。轻松重写以适用于任何模块,并使用 Node v4 和 v6 进行了测试。

    【讨论】:

    • 请注意,发布此答案后,可以在 AWS Lambda 中设置环境变量(有关在 AWS Lambda 中设置环境变量的问题,请参阅此答案 stackoverflow.com/a/40774215/1024811) .也就是说,能够在不设置环境变量的情况下控制 Node 的调试仍然很有用,例如谷歌云功能。对于除debug 模块之外的任何有此问题的人,请查看:github.com/visionmedia/debug/commit/…
    【解决方案2】:

    我不熟悉 Aws Lambda,但也许您仍然可以在命令中导出变量,如下所示:

    NODE_DEBUG=https node app.js
    

    【讨论】:

    • 在lambda中,我不控制命令行,也无法设置外部环境变量。
    【解决方案3】:

    child_process.fork() 允许一个模块生成具有指定环境变量的新节点环境。两个进程可以通过send()相互发送消息,并通过'message'事件接收这些消息。

    例如,如果您当前的主模块名为 server.js,那么您可以在同一目录中添加一个临时的 start.js 模块(这将是新的 lambda 函数),如下所示:

    // Add NODE_DEBUG to this process's environment variables, which are passed by default to
    // the forked node environment.
    process.env.NODE_DEBUG = 'https';
    
    const cp = require('child_process');
    const n = cp.fork('server.js');
    
    // Cached callback functions, in case client can pass in different callbacks.
    // Use an object instead of array, to avoid memory leaks. 
    const cbs = {};
    var cbIndexCounter = 0; // To make callback indices unique
    
    // Call appropriate callback with response from child process, and delete cached callback.
    n.on('message', (m) => {
      cbs[m.cbIndex](m.error, m.result);
      delete cbs[m.cbIndex];
    });
    
    n.on('error', (err) => {
      console.log('Child node env error: ', err);
    });
    
    // Cache the callback; forward event, context, index to child process; and increment index.
    exports.myHandler = function(event, context, callback) {
      cbs[cbIndexCounter] = callback;
      n.send({
        event: event,
        context: context,
        cbIndex: cbIndexCounter++
      });
    }
    

    server.js 模块可以通过添加一个“消息”事件监听器来稍微修改:

    process.on('message', (m) => {
      exports.myHandler(m.event, m.context, function(error, result) {
        process.send({
          error: error,
          result: result,
          cbIndex: m.cbIndex
        });
      });
    });
    
    // The rest of your original code ...
    exports.myHandler = function (event, context, callback) {
       // Whatever you need here...
    }
    

    【讨论】:

      【解决方案4】:

      运行以下命令:

      node app.js --https-debug
      

      在你的 app.js 中,在脚本的开头有这个

        process.argv.forEach((val, index) => {
          if(val.match(/--https-debug/)) {
            process.env.NODE_DEBUG = "https";
          }
        });
      

      process.env 和任何对象一样是一个对象,但 node 在其上设置了环境变量,您始终可以hack它并覆盖从 node 全局环境设置的任何变量。

      我们使用 process.argv 来捕获发送到终端中节点 js 文件的所有参数。

      【讨论】:

      • 在 lambda 中,我不控制命令行。当你在程序内部设置process.env.NODE_DEBUG时,已经来不及了。
      猜你喜欢
      • 1970-01-01
      • 2019-01-10
      • 1970-01-01
      • 1970-01-01
      • 2015-10-04
      • 1970-01-01
      • 2017-10-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多