web-dev-qa-db-fra.com

Comment interroger les journaux cloudwatch en utilisant boto3 dans python

J'ai une fonction lambda qui écrit des métriques dans Cloudwatch. Alors qu'il écrit des métriques, il génère des journaux dans un groupe de journaux.

INFO:: username: [email protected] ClinicID: 7667 nodename: MacBook-Pro-2.local

INFO:: username: [email protected] ClinicID: 7667 nodename: MacBook-Pro-2.local

INFO:: username: [email protected] ClinicID: 7668 nodename: MacBook-Pro-2.local

INFO:: username: [email protected] ClinicID: 7667 nodename: MacBook-Pro-2.local

Je voudrais interroger les journaux AWS au cours des x dernières heures, où x pourrait être compris entre 12 et 24 heures, en fonction de l'un des paramètres.

Par exemple:

  1. Query Cloudwatch se connecte au cours des 5 dernières heures où ClinicID=7667

ou

  1. Query Cloudwatch se connecte au cours des 5 dernières heures où ClinicID=7667 et username='[email protected]'

ou

  1. Query Cloudwatch se connecte au cours des 5 dernières heures où username='[email protected]'

J'utilise boto3 en Python. Puis-je avoir une direction à ce sujet s'il vous plaît?

3
Simran kaur

Vous pouvez obtenir ce que vous voulez en utilisant CloudWatch Logs Insights.

Vous utiliseriez start_query et get_query_results API: https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/logs.html

Pour démarrer une requête que vous utiliseriez (pour le cas d'utilisation 2 de votre question, 1 et 3 sont similaires):

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='[email protected]'"  

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
    )

La réponse contiendra vos données dans ce format (plus quelques métadonnées):

{
  'results': [
    [
      {
        'field': '@timestamp',
        'value': '2019-12-09 17:07:24.428'
      },
      {
        'field': '@message',
        'value': 'username: [email protected] ClinicID: 7667 nodename: MacBook-Pro-2.local\n'
      },
      {
        'field': 'username',
        'value': '[email protected]'
      },
      {
        'field': 'ClinicID',
        'value': '7667'
      },
      {
        'field': 'nodename',
        'value': 'MacBook-Pro-2.local\n'
      }
    ]
  ]
}
5
Dejan Peretin

Vous pouvez y parvenir avec le client cloudWatchlogs et un peu de codage. Vous pouvez également personnaliser les conditions ou utiliser le module JSON pour un résultat précis.

ÉDITER

Vous pouvez utiliser describe_log_streams pour obtenir les flux. Si vous ne voulez que le dernier, mettez simplement la limite 1, ou si vous en voulez plus d'un, utilisez for loop pour itérer tous les flux pendant le filtrage comme mentionné ci-dessous.

    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"] == "[email protected]":
            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"] == "[email protected]":
             print(event["message"])
           #.
           #.
           # more if or else conditions



Dites-moi comment ça se passe.

2
Sanny Patel

j'ai utilisé awslogs. si vous l'installez, vous pouvez le faire. --watch suivra les nouveaux journaux.

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

Vous pouvez l'installer en utilisant pip install awslogs

pour filtrer, vous pouvez faire:

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

il prend également en charge plusieurs modèles de filtre.

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

0
Arun K