web-dev-qa-db-fra.com

CloudWatch enregistre le flux vers Lambda python

J'ai créé un filtre d'abonnement dans le groupe de journaux CloudWatch et l'ai fait diffuser vers ma fonction lambda, mais je reçois une erreur dans ma fonction lambda.

Code:

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)

Erreur:

Réponse:

{
  "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)))"
    ]
  ]
}

Toute aide ou indice serait grandement apprécié! Si vous avez une solution alternative, veuillez suggérer. Mon exigence est de gérer les journaux de CloudWatch en utilisant lambda.

Merci d'avance !!

7
Salam

Au cas où quelqu'un d'autre chercherait de l'aide sur ce sujet.

J'ai adopté une approche légèrement différente, mais j'ai vu une clé "awslog" dans l'événement.

Voici un échantillon avec lequel j'ai réussi. Python 3.6 Lambda. Configurez le déclencheur cloudwatch pour appeler le lambda

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}')
16
P. Ryan

Vous trouverez ci-dessous le schéma que je respecte normalement lors du traitement des journaux CloudWatch envoyés à 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

Je constate que vous traitez les données envoyées à AWS Lambda comme un objet JSON. Vous voulez d'abord décoder en base64 puis décompresser les données. Après le décodage et la décompression, vous devriez avoir l'objet JSON avec les informations du journal.

4
quasar