Могу ли я определить, какой сервис AWS активировал мою функцию Lambda?

У меня есть функция Python Lambda, которая может реагировать как на кнопку IoT, так и на навык Alexa.

Есть ли способ прочитать event или context, переданные функции обработчика, чтобы определить, какая служба активировала функцию (Alexa или IoT)?


person orome    schedule 02.03.2017    source источник
comment
Я не работал ни с Alexa, ни с IoT, но считаю, что схемы их событийных объектов должны быть настолько разными, чтобы спутать одно с другим было бы сложно (если только структура события одного или обоих из них полностью под контролем пользователя, и вы намеренно делаете их неразличимыми, но в этом случае вам просто нужно сделать их различимыми, добавив, например, поле eventSource)   -  person Leon    schedule 02.03.2017
comment
@Леон: я не понимаю. Насколько это актуально?   -  person orome    schedule 02.03.2017
comment
См. этот вопрос, который имеет принятый ответ, основанный на формате шаблон мероприятия.   -  person Khalid T.    schedule 03.03.2017
comment
@KhalidT.: Вау, интересно. Поэтому мне действительно нужно в основном увидеть, какие поля есть, и предположить, основываясь на этом: нет поля, которое просто идентифицирует службу?   -  person orome    schedule 03.03.2017
comment
@KhalidT.: К сожалению, ни один из перечисленных шаблонов событий не предназначен для IoT или ASK.   -  person orome    schedule 03.03.2017
comment
К сожалению, AWS до сих пор не предоставляет источник события как часть самого объекта события. Вот почему я сослался на этот ответ, который в основном основан на догадках (да, я знаю, что это некрасиво). Кроме того, в документации AWS до сих пор не приводится образец события IoT или ASK, но вы можете распечатать его для любого из них; Console или CloudWatch с помощью вашей лямбда-функции.   -  person Khalid T.    schedule 03.03.2017
comment
@KhalidT.: Хорошо — я думаю, это сработает как ответ.   -  person orome    schedule 03.03.2017
comment
Например, если корзина s3 изменяет сработавшую лямбду, имя корзины будет доступно в объекте события как event.Records[0].s3.bucket.name. Даже ключ s3 для объекта, вызвавшего событие, можно найти в event.Records[0].s3.object.key. Следовательно, должны быть похожие объекты событий записей, которые указывают на службу и ее детали, вызвавшие лямбду. Вы можете преобразовать весь объект события в строку и зарегистрировать его, чтобы вы могли просмотреть его в cloudwatch и увидеть, что у вас там есть.   -  person bibek shrestha    schedule 18.03.2017


Ответы (4)


Надеялся, что AWS уже упростил это, но, к сожалению, это не так. Не существует единого параметра, по которому можно было бы определить тип события во всех сервисах AWS.

Тем не менее, нашел эту прекрасную артикуляцию онлайн здесь

function getLambdaEventSource(event) {
if (event.Records && event.Records[0].cf) return 'isCloudfront';

if (event.configRuleId && event.configRuleName && event.configRuleArn) return 'isAwsConfig';

if (event.Records && (event.Records[0].eventSource === 'aws:codecommit')) return 'isCodeCommit';

if (event.authorizationToken === "incoming-client-token") return 'isApiGatewayAuthorizer';

if (event.StackId && event.RequestType && event.ResourceType) return 'isCloudFormation';

if (event.Records && (event.Records[0].eventSource === 'aws:ses')) return 'isSes';

if (event.pathParameters && event.pathParameters.proxy) return 'isApiGatewayAwsProxy';

if (event.source === 'aws.events') return 'isScheduledEvent';

if (event.awslogs && event.awslogs.data) return 'isCloudWatchLogs';

if (event.Records && (event.Records[0].EventSource === 'aws:sns')) return 'isSns';

if (event.Records && (event.Records[0].eventSource === 'aws:dynamodb')) return 'isDynamoDb';

if (event.records && event.records[0].approximateArrivalTimestamp) return 'isKinesisFirehose';

if (event.records && event.deliveryStreamArn && event.deliveryStreamArn.startsWith('arn:aws:kinesis:')) return 'isKinesisFirehose';

if (event.eventType === 'SyncTrigger' && event.identityId && event.identityPoolId) return 'isCognitoSyncTrigger';

if (event.Records && event.Records[0].eventSource === 'aws:kinesis') return 'isKinesis';

if (event.Records && event.Records[0].eventSource === 'aws:s3') return 'isS3';

if (event.operation && event.message) return 'isMobileBackend';

}
person Kdroid    schedule 07.08.2018

Нет надежного способа сделать это. Самое близкое, что вы можете получить, - это ознакомиться с содержимым различных событий, сгенерированных различными службами, и (надеюсь) определить надежно уникальный ключ, присутствующий в каждой из интересующих вас серий, которые вы затем можете проверить в своем коде. , например с

if 'distinctKey' in event.keys():
    # ...

Однако это вряд ли надежный подход, так как он требует, чтобы вы

  1. изучить все возможные структуры событий, созданные каждой потенциальной службой, и
  2. успешно и уверенно определять для каждой интересующей службы ключ или набор ключей, который всегда надежно присутствует в событиях службы и уникален для них.
person orome    schedule 04.03.2017

Для разработчиков Python: вы можете проверить это на https://gist.github.com/Necromancerx/abed07138690d37d170a6cf15b40d749.

def get_lambda_event_source(self, event: dict):
    if 'pathParameters' in event and 'proxy' in event['pathParameters']:
        return 'api_gateway_aws_proxy'
    elif 'Records' in event and len(event['Records']) > 0 and 'eventSource' in event['Records'][0] and event['Records'][0]['eventSource'] == 'aws:s3':
        return 's3'
    elif 'Records' in event and len(event['Records']) > 0 and 'EventSource' in event['Records'][0] and event['Records'][0]['EventSource'] == 'aws:sns':
        return 'sns'
    elif 'Records' in event and len(event['Records']) > 0 and 'eventSource' in event['Records'][0] and event['Records'][0]['eventSource'] == 'aws:dynamodb':
        return 'dynamo_db'
    elif 'Records' in event and len(event['Records']) > 0 and 'cf' in event['Records'][0]:
        return 'cloudfront'
    elif 'source' in event and event['source'] == 'aws.events':
        return 'scheduled_event'
    elif 'awslogs' in event and 'data' in event['awslogs']:
        return 'cloud_watch_logs'
    elif 'authorizationToken' in event and event['authorizationToken'] == "incoming-client-token":
        return 'api_gateway_authorizer'
    elif 'configRuleId' in event and 'configRuleName' in event and 'configRuleArn' in event:
        return 'aws_config'
    elif 'StackId' in event and 'RequestType' in event and 'ResourceType' in event:
        return 'cloud_formation'
    elif 'Records' in event and len(event['Records']) > 0 and 'eventSource' in event['Records'][0] and event['Records'][0]['eventSource'] == 'aws:codecommit':
        return 'code_commit'
    elif 'Records' in event and len(event['Records']) > 0 and 'eventSource' in event['Records'][0] and event['Records'][0]['eventSource'] == 'aws:ses':
        return 'ses'
    elif 'Records' in event and len(event['Records']) > 0 and 'eventSource' in event['Records'][0] and event['Records'][0]['eventSource'] == 'aws:kinesis':
        return 'kinesis'
    elif 'records' in event and len(event['Records']) > 0 and 'approximateArrivalTimestamp' in event['records'][0]:
        return 'kinesis_firehose'
    elif 'records' in event and len(event['Records']) > 0 and 'deliveryStreamArn' in event and event['deliveryStreamArn'] is str and event['deliveryStreamArn'].startswith('arn:aws:kinesis:'):
        return 'kinesis_firehose'
    elif 'eventType' in event and event['eventType'] == 'SyncTrigger' and 'identityId' in event and 'identityPoolId' in event:
        return 'cognito_sync_trigger'
    elif 'operation' in event and 'message' in event:
        return 'is_mobile_backend'

На основе этого javascript gist https://gist.github.com/jeshan/52cb021fd20d871c56ad5ce6d2654d7b

person John Paulo Rodriguez    schedule 07.05.2020

Вы можете прочитать и зарегистрировать событие в Cloudwatch, как показано ниже.

import logging
logger = logging.getLogger()
logger.setLevel(logging.INFO)
def my_logging_handler(event, context):
logger.info('got event{}'.format(event))

Это зарегистрирует данные о событии в облачных часах, которые вы видите, и определит, какое событие вызвало лямбда-выражение.

person Dhanesh H S    schedule 02.03.2017
comment
Вопрос в том, какую часть event или context, к которой у меня есть доступ, я могу использовать, чтобы определить, какой производный (IoT или ASK) вызвал функцию. Или, если (и только если) это невозможно, как я могу изучить какой-то другой источник (например, журналы, возможно), чтобы сделать это. - person orome; 02.03.2017
comment
На самом деле это не дает ответа на вопрос, но показывает, как отладить это, чтобы найти ответ самостоятельно. - person Mark B; 03.03.2017