Я изучаю Lambda и пытаюсь перенести свое локальное приложение на лямбду AWS. Это очень просто. Просто функция, которая вызывает внешний сервис. Мой метод обработчика вызывает этот метод:
export const addTrack = async (token: string, parameters: any) => {
const url: string = process.env.URL as string
const headers = { ...globalHeaders, "authorization": "Bearer " + token };
try {
console.info("PARAMS:", parameters);
let response = await axios.put(url, parameters, { headers })
console.info('RESPONSE:', response.status + " | " + response.statusText + " | " + parameters.date + " | " + parameters.hours + " | " + parameters.comments)
} catch (e) {
console.error('Error trying to send a record:', parameters)
console.error(e)
throw new Error('Failing to call API: ' + e)
}
}
метод обработчика:
import { addTrack } from "./time-tracker-api-client"
import { DynamoDBClient, GetItemCommand } from "@aws-sdk/client-dynamodb"
const dynamoClient = new DynamoDBClient({})
export const handler = async (message: any) => {
let body = JSON.parse(message.Records[0].body);
let { Item }:any = await //call to dynamoBD...
let token:string = Item.bdToken.S
addTrack(token, body)
}
Обратите внимание на файл console.info до и после вызова axios.put и журнал в блоке catch. У меня здесь периодические журналы. Иногда показывает, иногда нет. Журнал с PARAMS всегда отображается, поэтому все правильно. Но иногда журнал ОТВЕТА не отображается в журналах CloudWatch ни в каких потоках, но также не показывает журнал ошибок. Кажется, что вызов put вызывает некоторую ошибку, но он не входит в блок catch. Странно то, что иногда, когда при вызове put возникает ошибка, это отображается в журнале.
Например, лямбда вызывается 20 раз, у меня есть 20 потоков журнала PARAMS, мои внешние службы отвечают на 17 вызовов. У меня есть только 17 журналов ОТВЕТОВ и 1 журнал ошибок. Кажется, отсутствуют 2 журнала ошибок. Иногда внешний вызов работает, но журнал ОТВЕТА не появляется
Я не понимаю, что здесь происходит. Может кто-нибудь подскажет, что происходит?
Я пытался вызвать, используя .then().catch() в вызове put, но это тоже не работает.
Также в качестве примечания: я бы рекомендовал вам использовать библиотеки журналирования вместо console.info. Вы можете попробовать Pino, Bunyan, Winston и т. д.
@ParmanM.Alizadeh, но отображаются журналы ИНФОРМАЦИИ и ОШИБОК. В конце концов они теряются
Можете ли вы поделиться дополнительной информацией о другом коде, вызывающем эту функцию addTrack? Есть ли у вас какие-либо другие глобальные переменные, которые требуют создания экземпляров вне вашей функции-обработчика? Можете ли вы поделиться своим определением функции IaC, если оно у вас есть (SAM, Terraform, CDK)?
@M.Brandao Когда они потерялись? Сразу после завершения выполнения лямбды? Или когда-нибудь после этого? Вы проверили конфигурацию периода потока журнала retention?
@AllanChua Я добавил код обработчика.
@ParmanM.Alizadeh, возможно, иногда после этого. Сохранение журнала в порядке. Я думаю здесь, возможно ли это из-за асинхронного вызова метода addTrack. Обработчик вызывает addTrack в асинхронном режиме. Затем лямбда-выражение завершается до того, как журнал будет помещен в поток. Является ли это возможным?
@M.Brandao Не совсем, я подозреваю, что это возможный сценарий. Не могли бы вы попробовать использовать библиотеку журналирования, например Pino вместо Console.log?
Ваша функция addTrack является асинхронной, но вы не ожидаете ее и не возвращаете ее результат.
Я предполагаю, что проблема связана с асинхронным вызовом метода addTrack в обработчике. Я просто добавил ожидание к этому вызову, и он начал все записывать. Когда вызов является асинхронным, я считаю, что лямбда-функция завершается до того, как метод addTrack сможет записать журнал.





Кажется, что вы получаете спонтанные ошибки (3 из 20), потому что обработчик кода вашей лямбда-функции не является awaiting функцией addTrack, которую необходимо завершить перед завершением. Чтобы убедиться, что функция addTrack выполняется полностью, измените код обработчика на следующий:
import { addTrack } from "./time-tracker-api-client"
import { DynamoDBClient, GetItemCommand } from "@aws-sdk/client-dynamodb"
const dynamoClient = new DynamoDBClient({})
export const handler = async (message: any) => {
let body = JSON.parse(message.Records[0].body);
let { Item }:any = await //call to dynamoBD...
let token:string = Item.bdToken.S
// Gracefully await the addTrack function to finish.
await addTrack(token, body);
}
Да. Именно это и происходит. Вероятно, лямбда завершает свой экземпляр до того, как метод addTrack завершит выполнение. Это также объясняет, почему обычно последние записи не вызываются во внешнем API.
Это могло быть вызвано тем, что уровень журнала по умолчанию равен
ERROR, и любой другой уровень журналов будет удален. Вы можете попробовать установить уровень журналаINFOи повторить попытку.