繁体   English   中英

如何在从 S3 读取到 ElK 的 Lambda 函数(python 代码)中读取不同格式(异常)的行?

[英]How to read lines with different format(exceptions) in Lambda function (python code) which reads from S3 to ElK?

我的日志文件的示例格式

-------------------------------------------------- -----------日志文件格式的开始------------------- ------

2020-08-14 05:35:48.752 - [INFO] - from [Class:com.webservices.services.impl.DataImpl Method:bData] in 20 - Data Single completed in 1047  mili sec

2020-08-14 05:35:48.752 - [INFO] - from [Class:com.webservices.services.impl.DataImpl Method:bData] in 20 - Data Single completed in 1099  mili sec

2020-08-14 05:35:48.762 - [ERROR] - from [Class:com.webservices.helper.THelper Method:lambda$0] in 20 - Parsing Response from server Failed

org.json.JSONException: No value for dataModel

at org.json.JSONObject.get(JSONObject.java:355) ~[android-json-0.0.20131108.vaadin1.jar:0.0.20131108.vaadin1]

-------------------------------------------------- ---------------------日志文件格式结束 ------------------------ ------

我目前正在处理以上述日志前 3 行中的日期开头的数据(使用糟糕的编码实践)。

问题从第 4 行开始,我的日志文件中有没有日期的异常。 实际上,前一行具有日期及其异常的延续。

随着格式的变化,我不知道如何处理这些行。 我想获取异常行的前一行的日期。

要么我必须将上一行的日期保留在一个临时变量中,并在格式更改或任何其他方式发生时使用它。

我需要 Date 作为强制推送 ELK,它采用日志的时间戳。

另外,如果有关于干净代码的建议,请执行。 我需要 lambda 运行得更快。

目前这是我在 Python 代码中的逻辑(我是 Python 代码的完整初学者)。

import boto3
import botocore
import re
import json
import requests

... 
...

def handler(event, context):
    print("Starting handler function")
    for record in event['Records']:

        # Get the bucket name and key for the new file
        bucket = record['s3']['bucket']['name']
        print("Bucket name - " + bucket)
        print(date_time)
        key = record['s3']['object']['key']
        print("key name - " + 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:
             document = {}
             try:
                 if line[0] == '2':
                     listOfData = line.split(" - ")
                     date = datetime.strptime(listOfData[0], "%Y-%m-%d %H:%M:%S.%f")
                     timestamp = date.isoformat()
                     level = listOfData[1]
                     classname = listOfData[2]
                     message = listOfData[-1]
                     document = { "timestamps": timestamp, "level": level, "classnames": classname, "messages": message }
                     print(document)
                 else:
                     document = {"messages": line}
             except ClientError as e:
                 raise e
             r = requests.post(url, auth=awsauth, json=document, headers=headers)
             print(r)

附加信息:正如 Ben 在回答中所建议的那样,当我打印 this_line 时,我将日志文件中的所有行正确打印在单独的行中,但中间的异常行存在问题。 下面是打印出来的。

{'line content': ['2020-08-14 05:35:48.762 - [ERROR] - from [Class:com.webevics.helpr.Helpr Method:lamda] in 2 - Parsng Respns from servr Failed', 'org.jsn.JSONExcepion: No vlue for dataModel'], 'date string': '2020-08-14 05:35:47.655'}
{'line content': ['2020-08-14 05:35:48.762 - [ERROR] - from [Class:com.webserics.helpr.Helpr Method:lambda] in 2 - Parsing Respnse from servr Faied', 'org.jsn.JSONException: No vlue for dataModel', 'at org.json.JSONObject.get(JSONObject.java:355) ~[android-json-0.0.20131108.vaadin1.jar:0.0.20131108.vaadin1]'], 'date string': '2020-08-14 05:35:47.655'}

在这里,我打印了 2 行,其中第一行没用,第二行更好。 那么我们可以做一些像第一行不应该出现而 this_line 中只有第二行的东西吗?

我首先将您的示例数据放在一个文件中,

2020-08-14 05:35:48.752 - [INFO] - from [Class:com.webservices.services.impl.DataImpl Method:bData] in 20 - Data Single completed in 1047 mili sec

2020-08-14 05:35:48.752 - [INFO] - from [Class:com.webservices.services.impl.DataImpl Method:bData] in 20 - Data Single completed in 1099 mili sec

2020-08-14 05:35:48.762 - [ERROR] - from [Class:com.webservices.helper.THelper Method:lambda$0] in 20 - Parsing Response from server Failed

org.json.JSONException: No value for dataModel

at org.json.JSONObject.get(JSONObject.java:355) ~[android-json-0.0.20131108.vaadin1.jar:0.0.20131108.vaadin1]

2020-08-14 05:35:48.752 - [INFO] - from [Class:com.webservices.services.impl.DataImpl Method:bData] in 20 - Data Single completed in 1099 mili sec

我添加了第四个条目只是为了验证我的方法有效。 下面的 Python 使用针对日期格式定制的正则表达式来检测行的开头

import re
with open('example.txt','r') as file_handle:
    file_content = file_handle.read().split("\n")
    
list_of_lines = []
this_line = {}
for index, line in enumerate(file_content):
    if len(line.strip())>0:
        reslt = re.match('\d{4}-\d\d-\d\d \d\d:\d\d:\d\d\.\d{3}', line)
        if reslt: # line starts with a date
            if len(this_line.keys())>0:
                list_of_lines.append(this_line)
            date_string = reslt.group(0)
            this_line = {'date string':date_string, 'line content': []}
            this_line['line content'].append(line)
        else:
            this_line['line content'].append(line)

产生的数据结构list_of_lines是一个字典列表。 每个字典都是一个错误条目,可能包含一行或多行。 错误字典中的两个键是date stringline content

要查看输出数据结构,请尝试运行

for line in list_of_lines[2]['line content']:
    print(line)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM