Ошибка чтения CloudWatch Logs в формате .gz после create_export_task в S3 - PullRequest
0 голосов
/ 30 апреля 2020

Создан Lambda для экспорта журналов из CloudWatch по расписанию CloudWatch Event, все в порядке.

Таким образом, журналы CloudWatch теперь хранятся в моей корзине S3 в формате .gz (вот что CloudWatch сохраняет их, как в S3 from create_export_task)

Теперь я хочу перевести этот сегмент и прочитать файлы .gz и преобразовать журналы из JSON в CSV (не спрашивайте), но проблема у меня в том, что я пытаюсь чтобы прочитать файлы, я продолжаю получать следующий результат.

{
  "errorMessage": "Not a gzipped file ('Pe')",
  "errorType": "BadGzipFile",
  "stackTrace": [
    "  File \"/var/task/lambda_function.py\", line 28, in lambda_handler\n    content = gzipfile.read()\n",
    "  File \"/var/lang/lib/python3.8/gzip.py\", line 292, in read\n    return self._buffer.read(size)\n",
    "  File \"/var/lang/lib/python3.8/gzip.py\", line 479, in read\n    if not self._read_gzip_header():\n",
    "  File \"/var/lang/lib/python3.8/gzip.py\", line 427, in _read_gzip_header\n    raise BadGzipFile('Not a gzipped file (%r)' % magic)\n"
  ]
}

Ниже приведено то, что я пробовал, все варианты 1, 2 и 3 возвращают тот же результат, что и выше.

from io import BytesIO
import json
import gzip
import csv
import datetime
import base64
import boto3


def lambda_handler(event, context):

    logBucketName = event['s3BucketName']
    logFolderName = event['logFolderName'] + '/'

    s3 = boto3.resource('s3')
    my_bucket = s3.Bucket(logBucketName)
    client = boto3.client('s3')

    for object_summary in my_bucket.objects.filter(Prefix= logFolderName, MaxKeys=1):

        obj = s3.Object(object_summary.bucket_name, object_summary.key)

        # opt 1
        content = gzip.GzipFile(fileobj=obj.get()['Body']).read()
        print(content)

        # opt 2
        with gzip.GzipFile(fileobj=obj.get()["Body"]) as gzipfile:
            content = gzipfile.read()
        print(content)

        # opt3
        bytes = io.BytesIO(obj.get()['Body'].read())
        gzipfile = gzip.GzipFile(fileobj=bytes)
        content = gzipfile.read()        
        print(content)

В документ AWS в фильтрах подписки гласит, что

Атрибут Данные в лямбда-записи кодируется в Base64 и сжимается в формате gzip. Фактическая полезная нагрузка, которую получает Lambda, имеет следующий формат {"awslogs": {"data": "BASE64ENCODED_GZIP_COMPRESSED_DATA"}}

https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/SubscriptionFilters.html#LambdaFunctionExample

Однако я не верю, что это имеет место в журналах CloudWatch, которые были экспортированы в S3 с использованием create_export_task, так как в S3 есть много файлов .gz, и если вы загружаете и распаковываете файл журнала, можно читать без него и декодировать Base64, так что Похоже, что это только для потоковых журналов.

Кто-нибудь уже решил эту проблему и поделиться своим советом?

...