CloudWatch регистрирует поток на Lambda Python
Я создал фильтр подписки в группе журналов CloudWatch и направил его на мою лямбда-функцию, но получаю ошибку в моей лямбда-функции.
Код:
import boto3
import binascii
import json
import base64
import zlib
def stream_gzip_decompress(stream):
dec = zlib.decompressobj(32 + zlib.MAX_WBITS) # offset 32 to skip the header
foo=''
for chunk in stream:
rv = dec.decompress(chunk)
if rv:
foo += rv
return foo
def lambda_handler(event, context):
# Decode and decompress the AWS Log stream to extract json object
stream=json.dumps(event['awslogs']['data'])
f = base64.b64decode(stream)
payload=json.loads(stream_gzip_decompress(f.decode(f)))
print(payload)
Ошибка:
Отклик:
{
"errorMessage": "decode() argument 1 must be str, not bytes",
"errorType": "TypeError",
"stackTrace": [
[
"/var/task/lambda_function.py",
34,
"lambda_handler",
"payload=json.loads(stream_gzip_decompress(f.decode(f)))"
]
]
}
Любая помощь или подсказка будет принята с благодарностью! Если у вас есть альтернативное решение, пожалуйста, предложите. Мое требование заключается в обработке журналов из CloudWatch с использованием лямбды.
Заранее спасибо!!
2 ответа
В случае, если кто-то еще ищет помощь по этой теме.
Я выбрал немного другой подход, но увидел событие "awslog" в этом событии.
Вот пример, с которым мне удалось. Python 3.6 Lambda. Настройка триггера cloudwatch для вызова лямбды
import gzip
import json
import base64
def lambda_handler(event, context):
print(f'Logging Event: {event}')
print(f"Awslog: {event['awslogs']}")
cw_data = event['awslogs']['data']
print(f'data: {cw_data}')
print(f'type: {type(cw_data)}')
compressed_payload = base64.b64decode(cw_data)
uncompressed_payload = gzip.decompress(compressed_payload)
payload = json.loads(uncompressed_payload)
log_events = payload['logEvents']
for log_event in log_events:
print(f'LogEvent: {log_event}')
Ниже приводится схема, которой я обычно следую при обработке журналов CloudWatch, отправляемых в AWS Lambda.
import gzip
import json
from StringIO import StringIO
def lambda_handler(event, context):
cw_data = str(event['awslogs']['data'])
cw_logs = gzip.GzipFile(fileobj=StringIO(cw_data.decode('base64', 'strict'))).read()
log_events = json.loads(cw_logs)
for log_event in logevents['logEvents']:
# Process Logs
Я вижу, что вы обрабатываете данные, отправленные в AWS Lambda, как объект JSON. Сначала вы хотите декодировать с помощью base64, а затем распаковать данные. После декодирования и распаковки у вас должен быть объект JSON с информацией журнала.
Вот ответ квазара, преобразованный в Python 3.
import gzip
import json
import base64
from io import BytesIO
cw_data = str(event['awslogs']['data'])
cw_logs = gzip.GzipFile(fileobj=BytesIO(base64.b64decode(cw_data, validate=True))).read()
log_events = json.loads(cw_logs)
for log_event in log_events['logEvents']:
# Process Logs
Основное изменение заключается в использовании io.BytesIO и другой функции декодирования base64 для доступа к данным событий журнала.