Python 2.7 против 3.8 Lambda для отправки файлов журнала с S3 в Elasticsearch - PullRequest
1 голос
/ 26 апреля 2020

Во-первых, я новичок в Python с небольшим опытом написания кода. У меня есть JSON -кодированные журнальные файлы, хранящиеся в S3, и я создал функцию Lambda (на основе AWS sample.py), которая анализирует и отправляет некоторые из этих журналов в Elasticsearch. Это все работает хорошо, когда Lambda Runtime установлен на Python 2.7. Вот код:

import boto3
import re
import requests
from requests_aws4auth import AWS4Auth

region = 'us-west-1'
service = 'es'
credentials = boto3.Session().get_credentials()
awsauth = AWS4Auth(credentials.access_key, credentials.secret_key, region, service, session_token=credentials.token)

host = 'https://search-siem-hds-sec-zsn57erua5fu5gdkdgnxhj5rsi.us-west-1.es.amazonaws.com'
index = 'index1'
type = 'lambda-type'
url = host + '/' + index + '/' + type

headers = { "Content-Type": "application/json" }

s3 = boto3.client('s3')

time_pattern = re.compile('(202\d-\d\d-\d\dT\d\d:\d\d:\d\d\.\d\d\dZ)')
message_pattern = re.compile('(.*)')

def lambda_handler(event, context):
    for record in event['Records']:

        bucket = record['s3']['bucket']['name']
        key = record['s3']['object']['key']

        obj = s3.get_object(Bucket=bucket, Key=key)
        body = obj['Body'].read()
        lines = body.splitlines()

            timestamp = time_pattern.search(line).group(1)
            message = message_pattern.search(line).group(1)

            document = { "timestamp": timestamp, "message": message }
            r = requests.post(url, auth=awsauth, json=document, headers=headers)

При установке времени выполнения на Python 3.8 Lambda не работает с сообщением:

[ERROR] TypeError: cannot use a string pattern on a bytes-like object

После некоторого чтения я добавил 'b' к следующему две строки, чтобы попытаться исправить это:

######################################################
time_pattern = re.compile(b'(202\d-\d\d-\d\dT\d\d:\d\d:\d\d\.\d\d\dZ)')
message_pattern = re.compile(b'(.*)')
######################################################

Однако это привело к следующей ошибке:

[ERROR] TypeError: Object of type bytes is not JSON serializable

Может ли какой-нибудь эксперт Python помочь или дать мне немного? руководство о том, как заставить это работать на Python 3,8?

Большое спасибо, Сера

1 Ответ

1 голос
/ 26 апреля 2020

Если файл, который вы читаете, не является двоичным, что, как я полагаю, не означает, что вы сравниваете его содержимое с текстовыми строками, измените это:

body = obj['Body'].read()

на следующее:

body = obj['Body'].read().decode('utf-8')

Функция read() в Python 3 возвращает байты. Вы хотите строки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...