【问题标题】:what format is used for aws logs stored in s3存储在 s3 中的 aws 日志使用什么格式
【发布时间】:2019-10-24 07:52:46
【问题描述】:

我正在尝试使用 aws 中的 lambda 将数据从 s3 移动到 es。我想测试我的功能,但我认为我的文件格式不正确,因此会导致错误。

我的 lambda 函数如下所示:

region = 'ap-northeast-2' # e.g. 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 = 'my-es-domain' # the Amazon ES domain,
index = 'lambda-s3-index'
type = 'lambda-type'
url = host + '/' + index + '/' + type

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

s3 = boto3.client('s3')

# Regular expressions used to parse some simple log lines
ip_pattern = re.compile('(\d+\.\d+\.\d+\.\d+)')
time_pattern = re.compile('\[(\d+\/\w\w\w\/\d\d\d\d:\d\d:\d\d:\d\d\s-\d\d\d\d)\]')
message_pattern = re.compile('\"(.+)\"')

# Lambda execution starts here
def handler(event, context):
    for record in event['Records']:

        # Get the bucket name and key for the new file
        bucket = record['s3']['bucket']['name']
        key = record['s3']['object']['key']

        # Get, read, and split the file into lines
        obj = s3.get_object(Bucket=bucket, Key=key)
        body = obj['Body'].read()
        lines = body.splitlines()

        # Match the regular expressions to each line and index the JSON
        for line in lines:
            ip = ip_pattern.search(line).group(1)
            timestamp = time_pattern.search(line).group(1)
            message = message_pattern.search(line).group(1)

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

我已将测试事件正确配置到存储桶中的文件。当我测试它时输出:

Response:
{
  "errorMessage": "cannot use a string pattern on a bytes-like object",
  "errorType": "TypeError",
  "stackTrace": [
    "  File \"/var/task/lambdaPackage.py\", line 40, in handler\n    ip = ip_pattern.search(line).group(1)\n"
  ]
}

我认为这是我的文件的问题。 我的文件在 sample.log 文件中,如下所示:

12.345.678.90 - [10/Oct/2000:13:55:36 -0700] "PUT /some-file.jpg"
12.345.678.91 - [10/Oct/2000:14:56:14 -0700] "GET /some-file.jpg"

如何格式化它例如:使用 .py、.json 等...这是我第一次使用 aws 和 log Infos。提前致谢!

我已经尝试以这种格式创建另一个文件:

12.345.678.90 - [10/Oct/2000:13:55:36 -0700] "PUT /some-file.jpg"\n
 12.345.678.91 - [10/Oct/2000:14:56:14 -0700] "GET /some-file.jpg"

输出相同的错误。

【问题讨论】:

  • Elasticsearch 输入数据必须是有效的 JSON,你应该格式化你想要转发的文件为 JSON。elastic.co/guide/en/elasticsearch/reference/current/…
  • 顺便说一句,弹性使用的每一行都可以使用批量操作,而不是插入,在一次调用中插入多个对象。
  • 所以在s3日志中必须是json格式?如果不是我需要转换它吗?
  • 没错,我会尽快检查您的 lambda,如果有任何问题会通知您
  • 您可以打印文档变量并与我们分享吗?

标签: amazon-web-services amazon-s3 aws-lambda


【解决方案1】:

这里的问题是因为您尝试发布无效的 JSON。在将数据插入 elasticsearch 之前,您需要使用 json.dumps(document) 将 Python 对象转换为 JSON 对象

用法示例:

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

更多关于Python JSON

更新:

看起来有两个问题:

  1. 使用json.dumps() 修复的无效 JSON
  2. 对象缺少字节和文本字符串。看起来从 s3 文件读取的行是字节而不是字符串。因此,每一行都必须解码成一个文本字符串(unicode),例如data.decode('utf-8')

来自文档:

返回从给定字节解码的字符串。

更多关于bytes.decode

【讨论】:

  • 是的,但我应该如何格式化我的文件?以便该函数可以获取多个日志的 ip、时间戳、消息。
  • 就像你做的那样,尝试添加应该修复错误的json.dumps
  • 并更改为 json.dumps(doc) 仍然给出相同的错误。
  • 谢谢,但是我如何在 for 循环的行前添加 b?
猜你喜欢
  • 2015-08-30
  • 2019-08-23
  • 1970-01-01
  • 2021-12-31
  • 2020-06-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多