繁体   English   中英

捕获从NodeJS Lambda生成的进程的输出

[英]Capturing output from process spawned from NodeJS Lambda

我正在尝试捕获由用NodeJS编写的AWS Lambda启动的外部程序的输出。 下面是完整的示例代码。 任何测试事件都可以使用,因为它并未真正使用。

exports.handler = async (event) => {
    console.log ("Entering lambda" + JSON.stringify(event))

    var spawn = require('child_process').spawnSync;

    child_process = spawn ('aws', [' --version'], {
        stdio: 'inherit',
        stderr: 'inherit',
        shell: true
    })

    console.log ("done");
    const response = {
        statusCode: 200,
        body: JSON.stringify('done'),
    };
    return response;
};

当我运行它时,我得到以下输出(为简洁起见,我删除了测试事件详细信息,因为它无关紧要)。

没有看到预期的aws --version命令的结果(我正在使用它来测试AWS CLI的正确调用,但是任何Linux命令都可以)。 该代码确实是同步执行的,因为如果我将调用替换为child_process = spawn ('sleep', ['1'], { ,lambda的执行时间会增加到1117.85 ms,所以会发生一秒钟的睡眠。但是,执行日志。

START RequestId: 0c1287e2-d2ee-4436-a577-bc8ec3608120 Version: $LATEST
2019-01-16T19:12:45.130Z    0c1287e2-d2ee-4436-a577-bc8ec3608120    Entering lambda {...}
2019-01-16T19:12:45.143Z    0c1287e2-d2ee-4436-a577-bc8ec3608120    done
END RequestId: 0c1287e2-d2ee-4436-a577-bc8ec3608120
REPORT RequestId: 0c1287e2-d2ee-4436-a577-bc8ec3608120  Duration: 13.29 ms  Billed Duration: 100 ms     Memory Size: 128 MB Max Memory Used: 20 MB  

难道我做错了什么? 还是有其他方法可以捕获用NodeJS编写的Lambda的输出(状态代码,stdio,stderr)?

这对我有用(node.js 8.10运行时)


exports.handler = async (event) => {
    const spawnSync = require('child_process').spawnSync;
    const process = spawnSync('echo', ['hello', 'world'], {
        stdio: 'pipe',
        stderr: 'pipe'
    });
    console.log(process.status);
    console.log(process.stdout.toString());
};

尝试使用aws运行时,将引发ENOENT错误。 换句话说,该命令不可用。 如@jarmod的问题注释中所述,我还认为awscli在Lambda容器中不可用。

可用的是SDK,因此您可以require('aws-sdk'); 而不将其捆绑到您的Lambda部署软件包。

aws-cli是python软件包,未安装在Lambda环境中。
要验证我的说法,您可以在http://www.lambdashell.com/上键入shell命令,并检查您的执行环境中默认安装的内容,或查看官方文档

上面的代码未返回任何输出,因为尝试执行aws返回ENOENT ,这意味着该文件不可用。

如果要在lambda函数中运行aws ,则可以按照以下说明进行操作: 从AWS Lambda调用aws-cli

但是我想问你为什么要这样做? 在AWS-SDK 包含在本地运行环境,你可以直接从你的代码中调用任何AWS API,而不需要生成一个进程和处理标准输入/输出。 我强烈建议不要从您的代码中生成aws cli,而应使用SDK。

但是,如果您确实想从Lambda运行一个进程并捕获stdout和stderr,这就是我的操作方法。

'use strict';

const childProcess = require('child_process');

/*
 * Handle the chile process and returns a Promise
 * that resoved when process finishes executing
 * 
 * The Promise resolves an  exit_code
 */ 
function handleProcess(process) {


    return new Promise((resolve, reject) => {
        process.stdout.on('data', (data) => {
            console.log(`stdout: ${data}`);
            console.log('stdout');
        });

        process.stderr.on('data', (data) => {
            console.log(`stderr: ${data}`);
        });

        process.on('close', (code) => {
            console.log(`child process exited with code ${code}`);
            if (code === 0) {
                resolve(code);
            } else {
                reject(code);
            }
        });
    });
}



exports.handler = (event, context, callback) => {

    // console.log(JSON.stringify(process.env, null, 2));
    // console.log(JSON.stringify(event, null, 2));

    return handleProcess(childProcess.spawn('ls', ['--version']))

        .then((exit_code) => {

            console.log(`exit_code = ${exit_code}`)
            let response = {
                statusCode: (0 == exit_code) ? 200 : 500,
                body: exit_code
            };                
            callback(null, response);

        })

        .catch((error) => {
            console.error(error);
            let response = {
                statusCode: 500,
                body: error
            };
            callback(null, response);
        });

}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM