【问题标题】:How to query cloudwatch logs using boto3 in python如何在python中使用boto3查询cloudwatch日志
【发布时间】:2020-04-02 00:55:54
【问题描述】:

我有一个将指标写入 Cloudwatch 的 lambda 函数。在写入指标的同时,它会在日志组中生成一些日志。

INFO:: username: simran+test@abc.com ClinicID: 7667 nodename: MacBook-Pro-2.local

INFO:: username: simran+test2@abc.com ClinicID: 7667 nodename: MacBook-Pro-2.local

INFO:: username: simran+test@abc.com ClinicID: 7668 nodename: MacBook-Pro-2.local

INFO:: username: simran+test3@abc.com ClinicID: 7667 nodename: MacBook-Pro-2.local

我想查询过去 x 小时的 AWS 日志,其中 x 可能是 12 到 24 小时之间的任何时间,基于任何参数。

例如:

  1. 查询 Cloudwatch 过去 5 小时内的日志,其中ClinicID=7667

  1. 查询 Cloudwatch 过去 5 小时内的日志,其中 ClinicID=7667username='simran+test@abc.com'

  1. 查询 Cloudwatch 过去 5 小时内的日志,其中username='simran+test@abc.com'

我在 Python 中使用boto3。请问这个可以指点一下吗?

【问题讨论】:

  • 正是我要找的东西!你节省了我几个小时!谢谢:)

标签: python amazon-web-services aws-lambda boto3 amazon-cloudwatch


【解决方案1】:

我使用了awslogs。如果你安装它,你可以做到。 --watch 将跟踪新日志。

awslogs get /aws/lambda/log-group-1 --start="5h ago" --watch

您可以使用安装它

pip install awslogs

过滤你可以这样做:

awslogs get /aws/lambda/log-group-1  --filter-pattern '"ClinicID=7667"' --start "5h ago" --timestamp

它也支持多种过滤模式。

awslogs get /aws/lambda/log-group-1  --filter-pattern '"ClinicID=7667"' --filter-pattern '" username=simran+test@abc.com"' --start "5h ago" --timestamp

参考资料:

awslogs

awslogs . PyPI

【讨论】:

  • 您是否期待任何其他特定功能
  • 有很多像awslogs 这样的工具,它们几乎都做同样的事情。
  • 我只需要在 Python boto3 中完成。 :) @Arun K
  • 我从 python 代码导入 awslogs 取得了一些成功
  • 链接到您推荐的任何非标准工具的更多信息被认为是一种很好的形式:pypi.org/project/awslogsgithub.com/jorgebastida/awslogs
【解决方案2】:

您可以通过cloudWatchlogs client 和一些编码来实现这一点。您还可以自定义条件或使用 JSON 模块以获得精确的结果。

编辑

您可以使用describe_log_streams 获取流。如果您只想要最新的,只需设置限制 1,或者如果您想要多个,使用 for 循环在过滤时迭代所有流,如下所述。

    import boto3

    client = boto3.client('logs')


    ## For the latest
    stream_response = client.describe_log_streams(
        logGroupName="/aws/lambda/lambdaFnName", # Can be dynamic
        orderBy='LastEventTime',                 # For the latest events
        limit=1                                  # the last latest event, if you just want one
        )

    latestlogStreamName = stream_response["logStreams"]["logStreamName"]


    response = client.get_log_events(
        logGroupName="/aws/lambda/lambdaFnName",
        logStreamName=latestlogStreamName,
        startTime=12345678,
        endTime=12345678,
    )

    for event in response["events"]:
        if event["message"]["ClinicID"] == "7667":
            print(event["message"])
        elif event["message"]["username"] == "simran+test@abc.com":
            print(event["message"])
        #.
        #.
        # more if or else conditions

    ## For more than one Streams, e.g. latest 5
    stream_response = client.describe_log_streams(
        logGroupName="/aws/lambda/lambdaFnName", # Can be dynamic
        orderBy='LastEventTime',                 # For the latest events
        limit=5                                  
        )

    for log_stream in stream_response["logStreams"]:
        latestlogStreamName = log_stream["logStreamName"]

        response = client.get_log_events(
             logGroupName="/aws/lambda/lambdaFnName",
             logStreamName=latestlogStreamName,
             startTime=12345678,
             endTime=12345678,
        )
        ## For example, you want to search "ClinicID=7667", can be dynamic

        for event in response["events"]:
           if event["message"]["ClinicID"] == "7667":
             print(event["message"])
           elif event["message"]["username"] == "simran+test@abc.com":
             print(event["message"])
           #.
           #.
           # more if or else conditions



告诉我进展如何。

【讨论】:

  • 感谢您的回复。日志流名称是由 lambda 函数自动生成的,所以我事先并不知道它们。我该怎么办?
  • @SannyPatel,我的 aws 日志如下,我如何捕获整个 JSON。信息 2020-11-27 10:30:09,510 [[reltiodatagateway-1.0.0-SNAPSHOT].callDnB-Main-Flow.stage1.03] org.mule.api.processor.LoggerMessageProcessor:80916b10-309b-11eb-ab19- 0242ac110002 调用 DnB API 后的 JSON 输出。响应详情 { "jobId": 5754492016394240, "success": "OK", "message": "Scheduled" }
  • 创建您的 Lambda 并明确定义 FunctionName。这将允许您动态创建日志组。另一个(更糟糕的)选项是查询 CloudFormation 的 Lambda 名称,然后基于该名称构建日志组名称。 docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/…
【解决方案3】:

您可以使用 CloudWatch Logs Insights 获得所需的内容。

您将使用 start_queryget_query_results API:https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/logs.html

要开始您将使用的查询(对于您问题中的用例 2,1 和 3 相似):

import boto3
from datetime import datetime, timedelta
import time

client = boto3.client('logs')

query = "fields @timestamp, @message | parse @message \"username: * ClinicID: * nodename: *\" as username, ClinicID, nodename | filter ClinicID = 7667 and username='simran+test@abc.com'"  

log_group = '/aws/lambda/NAME_OF_YOUR_LAMBDA_FUNCTION'

start_query_response = client.start_query(
    logGroupName=log_group,
    startTime=int((datetime.today() - timedelta(hours=5)).timestamp()),
    endTime=int(datetime.now().timestamp()),
    queryString=query,
)

query_id = start_query_response['queryId']

response = None

while response == None or response['status'] == 'Running':
    print('Waiting for query to complete ...')
    time.sleep(1)
    response = client.get_query_results(
        queryId=query_id
    )

响应将包含您的这种格式的数据(加上一些元数据):

{
  'results': [
    [
      {
        'field': '@timestamp',
        'value': '2019-12-09 17:07:24.428'
      },
      {
        'field': '@message',
        'value': 'username: simran+test@abc.com ClinicID: 7667 nodename: MacBook-Pro-2.local\n'
      },
      {
        'field': 'username',
        'value': 'simran+test@abc.com'
      },
      {
        'field': 'ClinicID',
        'value': '7667'
      },
      {
        'field': 'nodename',
        'value': 'MacBook-Pro-2.local\n'
      }
    ]
  ]
}

【讨论】:

  • 完美。谢谢:)
  • 你能在这里看看相关的问题吗,请stackoverflow.com/questions/59314132/…@Unkindness of Datapoints
  • 注意start_query函数(link)的limit参数,默认为1000。如果您使用高密度日志,则可以省略某些事件而无需指定更高的限制。
  • 使用日志洞察进行查询是收费的。请注意时间范围,因此查询将分析的数据量。在 GUI 中运行相同的查询以查看它处理的数据量
  • 请注意,除了Running 之外,response['status'] 也可以是Scheduled,因此请考虑将or response['status'] == 'Scheduled' 添加到while 条件中。完整列表是链接文档中的ScheduledRunningCompleteFailedCancelledTimeoutUnknown
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-12
  • 2021-09-09
  • 1970-01-01
  • 2020-04-25
  • 2022-08-04
  • 1970-01-01
相关资源
最近更新 更多