Python 2.7 vs 3.8 Lambda用于将日志文件从S3发送到Elasticsearch



首先,我是Python的新手,没有太多的代码编写经验。我在S3中存储了JSON编码的日志文件,并构建了一个Lambda函数(基于AWS sample.py(,该函数解析并将其中一些日志发送到Elasticsearch中。当Lambda运行时设置为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('(202d-dd-ddTdd:dd:dd.dddZ)')
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'(202d-dd-ddTdd:dd:dd.dddZ)')
message_pattern = re.compile(b'(.*)')
######################################################

然而,这导致了以下错误:

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

任何一位Python专家都能为我提供帮助或指导我如何在Python 3.8上实现这一点吗?

非常感谢,Sera

如果您正在读取的文件不是二进制的,我认为这并不是因为您正在将其内容与文本字符串进行比较,那么请更改:

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

到此:

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

Python 3中的read()函数返回字节。你想要字符串。

最新更新