从 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 毫秒,因此会发生一秒钟的睡眠。但是执行日志中没有捕获任何内容。
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 环境中。
要验证我的说法,您可以在此处输入 shell 命令 http://www.lambdashell.com/ and check what is installed by default in your execution environment or check the official documentation.
你上面的代码 returns 没有输出,因为试图执行 aws
returns ENOENT
,这意味着文件不可用。
如果您想 运行 aws
在您的 lambda 函数中,您可以按照以下说明操作:
不过我会问 为什么 你要这样做? AWS-SDK 包含在本地 运行time 环境中,您可以直接从您的代码调用任何 AWS API,无需生成进程和处理 stdin/stdout。我强烈建议不要从您的代码中生成 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);
});
}
我正在尝试捕获从用 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 毫秒,因此会发生一秒钟的睡眠。但是执行日志中没有捕获任何内容。
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 环境中。
要验证我的说法,您可以在此处输入 shell 命令 http://www.lambdashell.com/ and check what is installed by default in your execution environment or check the official documentation.
你上面的代码 returns 没有输出,因为试图执行 aws
returns ENOENT
,这意味着文件不可用。
如果您想 运行 aws
在您的 lambda 函数中,您可以按照以下说明操作:
不过我会问 为什么 你要这样做? AWS-SDK 包含在本地 运行time 环境中,您可以直接从您的代码调用任何 AWS API,无需生成进程和处理 stdin/stdout。我强烈建议不要从您的代码中生成 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);
});
}