web-dev-qa-db-fra.com

Ma facture AWS Cloudwatch est énorme. Comment savoir quel flux de journaux est à l'origine de ce problème?

J'ai reçu une facture de 1 200 $ d'Amazon pour les services Cloudwatch le mois dernier (en particulier pour 2 TB d'ingestion de données de journal dans "AmazonCloudWatch PutLogEvents")), alors que je m'attendais à quelques dizaines de dollars. connecté à la section Cloudwatch de la console AWS, et peut voir que l'un de mes groupes de journaux a utilisé environ 2 To de données, mais il y a des milliers de flux de journaux différents dans ce groupe de journaux, comment puis-je savoir lequel a utilisé cette quantité de données?

17
Sam Critchley

Sur la console CloudWatch, utilisez les métriques IncomingBytes pour trouver la quantité de données ingérées par chaque groupe de journaux pour une période donnée en octets non compressés à l'aide de la page Métriques. Suivez les étapes ci-dessous -

  1. Accédez à la page des métriques CloudWatch et cliquez sur l'espace de noms AWS 'Logs' -> 'Log Group Metrics'.
  2. Sélectionnez les métriques IncomingBytes des groupes de journaux requis et cliquez sur l'onglet 'Graphed metrics' pour voir le graphique.
  3. Modifiez l'heure de début et l'heure de fin de sorte que leur différence soit de 30 jours et modifiez la période à 30 jours. De cette façon, nous n'obtiendrons qu'un seul point de données. A également changé le graphique en nombre et les statistiques en somme.

De cette façon, vous verrez la quantité de données ingérées par chaque groupe de journaux et vous aurez une idée de quel groupe de journaux ingère combien.

enter image description here

Vous pouvez également obtenir le même résultat à l'aide de l'AWS CLI. Un exemple de scénario dans lequel vous souhaitez simplement connaître la quantité totale de données ingérées par les groupes de journaux pendant 30 jours, par exemple, vous pouvez utiliser la commande CLI get-metric-statistics

exemple de commande CLI -

aws cloudwatch get-metric-statistics --metric-name IncomingBytes --start-time 2018-05-01T00:00:00Z --end-time 2018-05-30T23:59:59Z --period 2592000 --namespace AWS/Logs --statistics Sum --region us-east-1

exemple de sortie -

{
    "Datapoints": [
        {
            "Timestamp": "2018-05-01T00:00:00Z", 
            "Sum": 1686361672.0, 
            "Unit": "Bytes"
        }
    ], 
    "Label": "IncomingBytes"
}

Pour trouver la même chose pour un groupe de journaux particulier, vous pouvez modifier la commande pour prendre en charge des dimensions telles que -

aws cloudwatch get-metric-statistics --metric-name IncomingBytes --start-time 2018-05-01T00:00:00Z --end-time 2018-05-30T23:59:59Z --period 2592000 --namespace AWS/Logs --statistics Sum --region us-east-1 --dimensions Name=LogGroupName,Value=test1

Un par un, vous pouvez exécuter cette commande sur tous les groupes de journaux et vérifier quel groupe de journaux est responsable de la majeure partie de la facture des données ingérées et prendre des mesures correctives.

REMARQUE: modifiez les paramètres spécifiques à votre environnement et à vos besoins.

La solution fournie par OP fournit des données pour la quantité de journaux stockés qui sont différents des journaux ingérés.

Quelle est la différence?

Les données ingérées par mois ne sont pas identiques aux octets de stockage de données. Une fois les données ingérées dans CloudWatch, elles sont archivées par CloudWatch qui inclut 26 octets de métadonnées par événement de journal et sont compressées à l'aide de la compression gzip de niveau 6. Ainsi, les octets de stockage se réfèrent à l'espace de stockage utilisé par Cloudwatch pour stocker les journaux après leur ingestion.

Référence: https://docs.aws.Amazon.com/cli/latest/reference/cloudwatch/get-metric-statistics.html

39
Deepak Puthraya

Nous avions un lambda enregistrant Go de données en raison d'un enregistrement accidentel. Voici un script python basé sur boto3 basé sur les informations des réponses ci-dessus qui analyse tous les groupes de journaux et imprime tout groupe avec des journaux supérieurs à 1 Go au cours des 7 derniers jours. Cela m'a aidé plus qu'à essayer pour utiliser le tableau de bord AWS qui était lent à mettre à jour.

#!/usr/bin/env python3

# Outputs all loggroups with > 1GB of incomingBytes in the past 7 days

import boto3
from datetime import datetime as dt
from datetime import timedelta


logs_client = boto3.client('logs')
cloudwatch_client = boto3.client('cloudwatch')

end_date = dt.today().isoformat(timespec='seconds')
start_date = (dt.today() - timedelta(days=7)).isoformat(timespec='seconds')
print("looking from %s to %s" % (start_date, end_date))

paginator = logs_client.get_paginator('describe_log_groups')
pages = paginator.paginate()
for page in pages:
     for json_data in page['logGroups']:
        log_group_name = json_data.get("logGroupName") 

        cw_response = cloudwatch_client.get_metric_statistics(
           Namespace='AWS/Logs',    
           MetricName='IncomingBytes',
           Dimensions=[
            {
                'Name': 'LogGroupName',
                'Value': log_group_name
            },
            ],
            StartTime= start_date,
            EndTime=end_date,
            Period=3600 * 24 * 7,
            Statistics=[
                'Sum'
            ],
            Unit='Bytes'
        )
        if len(cw_response.get("Datapoints")):
            stats_data = cw_response.get("Datapoints")[0]
            stats_sum = stats_data.get("Sum")   
            sum_GB = stats_sum /  (1000 * 1000 * 1000)
            if sum_GB > 1.0:
                print("%s = %.2f GB" % (log_group_name , sum_GB))
        
10
Diego Link

D'accord, je suis répondant à ma propre question ici, mais c'est parti (avec toutes les autres réponses bienvenues):

Vous pouvez utiliser une combinaison d'outils AWS CLI, le package csvfix CSV et une feuille de calcul pour résoudre ce problème.

  • Connectez-vous à AWS Cloudwatch Console et saisissez le nom du groupe de journaux qui a généré toutes les données. Dans mon cas, cela s'appelle "test01-ecs".
  • Malheureusement, dans la console Cloudwatch, vous ne pouvez pas trier les flux par "octets stockés" (qui vous indiqueraient lesquels sont les plus importants). S'il y a trop de flux dans le groupe de journaux à parcourir dans la console, vous devez les vider d'une manière ou d'une autre. Pour cela, vous pouvez utiliser l'outil AWS CLI:

    $ aws logs describe-log-streams --log-group-name test01-ecs

  • La commande ci-dessus vous donnera une sortie JSON (en supposant que votre outil AWS CLI est défini sur la sortie JSON - définissez-le sur output = json dans ~/.aws/config sinon) et cela ressemblera à ceci:

    { "logStreams": [ { "creationTime": 1479218045690, "arn": "arn:aws:logs:eu-west-1:902720333704:log-group:test01-ecs:log-stream:test-spec/test-spec/0307d251-7764-459e-a68c-da47c3d9ecd9", "logStreamName": "test-spec/test-spec/0308d251-7764-4d9f-b68d-da47c3e9ebd8", "storedBytes": 7032 } ] }

  • Dirigez cette sortie vers un fichier JSON - dans mon cas, le fichier avait une taille de 31 Mo:

    $ aws logs describe-log-streams --log-group-name test01-ecs >> ./cloudwatch-output.json

  • Utilisez le package in2csv (partie de csvfix ) pour convertir le fichier JSON en fichier CSV qui peut facilement être importé dans un feuille de calcul, en veillant à définir la clé logStreams à utiliser pour importer sur:

    $ in2csv cloudwatch-output.json --key logStreams >> ./cloudwatch-output.csv

  • Importez le fichier CSV résultant dans une feuille de calcul (j'utilise LibreOffice moi-même car il semble excellent pour traiter le CSV) en vous assurant que les octets stockés est importé sous forme d'entier.

  • Triez la colonne Octets stockés dans la feuille de calcul pour déterminer le ou les flux de journaux générant le plus de données.

Dans mon cas, cela a fonctionné - il s'est avéré que l'un de mes flux de journaux (avec les journaux d'un tube TCP pipe dans une instance de redis) était 4 000 fois la taille de tous les autres flux combinés!

6
Sam Critchley

Bien que l'auteur de la question et d'autres personnes aient répondu à la question dans le bon sens, j'essaierai d'avoir une solution générique qui pourrait être appliquée sans connaître l'exact log-group-name qui cause aussi beaucoup de journaux.

Pour ce faire, nous pouvons pas utiliser la fonction describe-log-streams car cela nécessiterait - log-group-name et comme je l'ai dit plus tôt, je ne connais pas la valeur de mon nom de groupe de journaux.

Nous pouvons utiliser la fonction describe-log-groups car cette fonction ne nécessite aucun paramètre.

Notez que Je suppose que vous avez le drapeau requis (--region) configuré dans le fichier ~/.aws/config et votre instance EC2 a la permission requise pour exécuter ceci commander.

aws logs describe-log-groups

Cette commande répertorierait tous les groupes de journaux de votre compte aws. L'échantillon de sortie de ce serait

 {
    "logGroups": [
        {
            "metricFilterCount": 0,
            "storedBytes": 62299573,
            "arn": "arn:aws:logs:ap-southeast-1:855368385138:log-group:RDSOSMetrics:*",
            "retentionInDays": 30,
            "creationTime": 1566472016743,
            "logGroupName": "/aws/lambda/us-east-1.test"
        }
    ]
}

Si vous êtes intéressé par un modèle de préfixe spécifique uniquement pour le groupe de journaux, vous pouvez utiliser - log-group-name-prefix comme ceci

aws logs describe-log-groups --log-group-name-prefix /aws/lambda

Le JSON de sortie de cette commande serait également similaire à la sortie ci-dessus.

Si vous avez trop de groupes de journaux dans votre compte, l'analyse de la sortie de celui-ci devient difficile et nous avons besoin d'un utilitaire de ligne de commande pour donner un bref aperçu du résultat. Nous utiliserons l'utilitaire de ligne de commande 'jq' pour obtenir la chose souhaitée. L'intention est d'obtenir quel groupe de journaux a produit le plus de journaux et donc de provoquer plus d'argent.

A partir du JSON de sortie, les champs dont nous avons besoin pour notre analyse seraient "logGroupName" et "storedBytes". Donc, en prenant ces 2 champs dans la commande 'jq'.

aws logs describe-log-groups --log-group-name-prefix /aws/ 
| jq -M -r '.logGroups[] | "{\"logGroupName\":\"\(.logGroupName)\",
\"storedBytes\":\(.storedBytes)}"'

Utiliser '\' dans la commande pour faire l'échappement car nous voulons que la sortie soit au format JSON seulement pour utiliser la fonction sort_by de jq. L'exemple de sortie de ceci serait quelque chose comme ci-dessous:

{"logGroupName":"/aws/lambda/test1","storedBytes":3045647212}
{"logGroupName":"/aws/lambda/projectTest","storedBytes":200165401}
{"logGroupName":"/aws/lambda/projectTest2","storedBytes":200}

Notez que le résultat de sortie ne serait pas trié sur storedBytes, nous voulons donc les trier afin d'obtenir quel groupe de journaux est le plus problématique.

nous utiliserons la fonction sort_by de jq pour accomplir cela. L'exemple de commande serait comme ceci

aws logs describe-log-groups --log-group-name-prefix /aws/ 
| jq -M -r '.logGroups[] | "{\"logGroupName\":\"\(.logGroupName)\",
\"storedBytes\":\(.storedBytes)}"' 
|  jq -s -c 'sort_by(.storedBytes) | .[]'

Cela produirait le résultat ci-dessous pour l'échantillon de sortie ci-dessus

{"logGroupName":"/aws/lambda/projectTest2","storedBytes":200}
{"logGroupName":"/aws/lambda/projectTest","storedBytes":200165401}
{"logGroupName":"/aws/lambda/test1","storedBytes":3045647212}

Les éléments du bas de cette liste sont ceux qui ont le plus de journal associé. Vous pouvez définir la propriété Expire Events After sur une période finie, disons 1 mois pour ces groupes de journaux.

Si vous voulez savoir quelle est la somme de tous les octets de journal, vous pouvez utiliser la fonction 'map' et 'add' de jq comme ci-dessous.

 aws logs describe-log-groups --log-group-name-prefix /aws/ 
        | jq -M -r '.logGroups[] | "{\"logGroupName\":\"\(.logGroupName)\",
\"storedBytes\":\(.storedBytes)}"'
        |  jq -s -c 'sort_by(.storedBytes) | .[]' 
        | jq -s 'map(.storedBytes) | add '

La sortie de cette commande pour l'exemple de sortie ci-dessus serait

3245812813

La réponse est devenue longue, mais j'espère que cela aidera à déterminer le groupe de journaux le plus problématique dans cloudwatch.

2
Ajay Kr Choudhary

Vous pouvez également cliquer sur l'engrenage de l'engrenage dans le tableau de bord des journaux de cloudwatch et choisir la colonne d'octets stockés.

J'ai également cliqué sur tout ce qui disait "ne jamais expirer" et changé les journaux pour expirer.

tilisez l'engrenage des journaux cloudwatch et sélectionnez la colonne "Octets stockés"

0
jfo8000