Захват результатов от процесса, порожденного от NodeJS Lambda - PullRequest
0 голосов
/ 16 января 2019

Я пытаюсь захватить вывод из внешней программы, запущенной с AWS Lambda, написанной на NodeJS. Полный пример кода ниже. Подойдет любое тестовое событие, так как оно на самом деле не используется.

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, но подойдет любая команда Linux) , Код выполняет синхронно, потому что, если я заменю вызов на child_process = spawn ('sleep', ['1'], {, время выполнения лямбды вырастет до 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  

Я что-то не так делаю? Или есть какой-нибудь другой способ записать вывод (код состояния, stdio, stderr) для лямбды, написанной на NodeJS?

Ответы [ 2 ]

0 голосов
/ 17 января 2019

aws-cli - это пакет python, который не устанавливается в среде Lambda.
Чтобы проверить мое утверждение, вы можете ввести здесь команды оболочки http://www.lambdashell.com/ и проверить, что установлено по умолчанию в вашей среде выполнения, или проверить официальную документацию .

.

Ваш код выше не возвращает никакого вывода, потому что попытка выполнить aws возвращает ENOENT, то есть файл недоступен.

Если вы хотите запустить aws внутри своей лямбда-функции, вы можете выполнить следующие инструкции: Вызвать aws-cli из AWS Lambda

Однако я бы спросил почему Вы хотите это сделать? AWS-SDK - это , включенный в локальную среду выполнения, и вы можете вызывать любой API-интерфейс AWS непосредственно из своего кода, без необходимости порождать процесс и работать с 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);
        });

}
0 голосов
/ 17 января 2019

Это работает для меня (время выполнения 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.

...