AWS Lambda, использующая протоколирование Winston, теряет идентификатор запроса - PullRequest
0 голосов
/ 12 июня 2019

При использовании console.log для добавления строк журнала в AWS CloudWatch идентификатор лямбда-запроса добавляется в каждую строку как , как описано в документации

Упрощенный пример, основанный на вышеупомянутом документе

exports.handler = async function(event, context) {
  console.log("Hello");
  return context.logStreamName
};

Будет производить вывод, такой как

START RequestId: c793869b-ee49-115b-a5b6-4fd21e8dedac Версия: $ LATEST

2019-06-07T19: 11: 20.562Z c793869b-ee49-115b-a5b6-4fd21e8dedac ИНФОРМАЦИЯ Здравствуйте,

END RequestId: c793869b-ee49-115b-a5b6-4fd21e8dedac

ОТЧЕТ RequestId: c793869b-ee49-115b-a5b6-4fd21e8dedac Продолжительность: 170,19 мс Продолжительность счета: 200 мс Размер памяти: 128 МБ Макс. Используемая память: 73 МБ

Соответствующей деталью, касающейся этого вопроса, является идентификатор запроса c793869b-ee49-115b-a5b6-4fd21e8dedac, который добавляется после метки времени в строке со словом «Hello».

Документация AWS гласит

Для вывода журналов из кода функции вы можете использовать методы объекта консоли или любую библиотеку журналов, которая записывает в stdout или stderr.

Среда выполнения Node.js регистрирует строки START, END и REPORT для каждого вызова и добавляет метку времени, идентификатор запроса и уровень журнала к каждой записи, регистрируемой функцией.

При использовании Winston в качестве регистратора идентификатор запроса теряется. Может быть выпущено с форматерами или транспортами. Регистратор создается как

const logger = createLogger({
    level: 'debug',
    format: combine(
      timestamp(),
      printf(
        ({ timestamp, level, message }) => `${timestamp} ${level}: ${message}`
      )
    ),
    transports: [new transports.Console()]
  });

Я также попытался использовать simple() formatter вместо printf(), но это не влияет на то, присутствует ID запроса или нет. Кроме того, при удалении форматирования все равно печатается простой текст, то есть нет метки времени или идентификатора запроса.

Я также проверил исходный код транспорта Winston Console, и он использует либо console._stdout.write, если он присутствует, либо console.log для записи, что, как утверждается в документации AWS, поддерживается.

Есть ли способ настроить Winston для сохранения идентификатора лямбда-запроса AWS как части сообщения?

P.S. Мне известны отдельные Winston Transports для AWS CloudWatch, но они требуют других функций настройки, которых я бы хотел избежать, если это возможно. А поскольку идентификатор запроса доступен, они кажутся излишними.

P.P.S. Идентификатор запроса можно также получить из Lambda Context и инициализировать его с помощью настраиваемого объекта журнала, но я бы также хотел этого избежать, в основном по тем же причинам: дополнительная работа для чего-то, что должно быть легко доступно.

1 Ответ

0 голосов
/ 13 июня 2019

Проблема связана с использованием console._stdout.write() / process._stdout.write(), которое использует встроенный консольный транспорт Winston, когда он присутствует.

По какой-то причине строки, записанные в stdout, отправляются в CloudWatch как есть, и метка времени / идентификатор запроса не добавляются в строки журнала, как при console.log() вызовах.

На Github обсуждается вопрос о том, чтобы сделать эту опцию конструктора , которую можно было бы выбрать при создании транспорта, но она была закрыта как проблема, связанная с конкретными IDE и тем, как они обрабатывают журналы stdout. Проблема с AWS Lambdas упоминается только в качестве дополнительного примечания в обсуждении.

Мое решение состояло в том, чтобы создать пользовательский транспорт для Winston, который всегда использует console.log() для записи сообщений и оставления метки времени и идентификатора запроса для заполнения средой выполнения AWS Lambda Node.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...