web-dev-qa-db-ja.com

AWS Boto3を使用してCloudwatchメトリック統計を取得するにはどうすればよいですか?

Boto3ライブラリを使用してAWSCloudFrontからS3スペース使用率統計を取得するように設計されたPython 3スクリプトに取り組んでいます。

AWS CLIから始めて、次のようなコマンドで目的の結果を取得できることがわかりました。

aws cloudwatch get-metric-statistics --metric-name BucketSizeBytes --namespace AWS/S3 --start-time 2017-03-06T00:00:00Z --end-time 2017-03-07T00:00:00Z --statistics Average --unit Bytes --region us-west-2 --dimensions Name=BucketName,Value=foo-bar Name=StorageType,Value=StandardStorage --period 86400 --output json

これは私が期待するデータを返します。 Python 3/Boto3で同じことをしたいと思います。これまでの私のコードは次のとおりです。

from datetime import datetime, timedelta
import boto3

seconds_in_one_day = 86400  # used for granularity

cloudwatch = boto3.client('cloudwatch')

response = cloudwatch.get_metric_statistics(
    Namespace='AWS/S3',
    Dimensions=[
        {
            'Name': 'BucketName',
            'Value': 'foo-bar'
        },
        {
            'Name': 'StorageType',
            'Value': 'StandardStorage'
        }
    ],
    MetricName='BucketSizeBytes',
    StartTime=datetime.now() - timedelta(days=7),
    EndTime=datetime.now(),
    Period=seconds_in_one_day,
    Statistics=[
        'Average'
    ],
    Unit='Bytes'
)

print(response)

これを実行すると、有効な応答が得られますが、データポイントは得られません(空の配列です)。 Pythonメソッドには、コマンドラインで必要な領域の場所がないように見えることを除いて、これらは同じように見えます。

私が試したもう1つのことは、私のコードは、最後の日付の日付と、ハードコーディングされているコマンドラインの日付を計算することです。データが返されるかどうかを確認するために、日付をハードコーディングしようとしましたが、結果は同じでした。

だから私の質問はこれらです:

Boto/Pythonはコマンドラインと同等ですか?それらがそうであると仮定すると、何が欠けている可能性がありますか?

5
Bruce Van Horn

エラーはあなたのコマンドcloudwatch = boto3.client('cloudwatch')だと思います。デフォルトのリージョンはeast-1です。したがって、次のようなものを使用できます。

from datetime import datetime, timedelta
import boto3

def credentials_AWS (account):
  
   if (account == 'account1'):
       aws_access_key_id = "key id east"
       aws_secret_access_key = 'east secret_access_key'
       region_name = 'us-east-1'
   Elif (account == 'account2'):
       aws_access_key_id = "key id west"
       aws_secret_access_key = 'west secret_access_key'
       region_name = 'us-west-2'
    
   return aws_access_key_id, aws_secret_access_key, region_name
    

def connect_service_aws (service, aws_access_key_id, aws_secret_access_key, region_name):


     aws_connected = boto3.client (service,
                                  aws_access_key_id = aws_access_key_id,
                                  aws_secret_access_key = aws_secret_access_key,
                                  region_name = region_name)
             
     return aws_connected


def get_metrics(account):

  seconds_in_one_day = 86400  # used for granularity

  #cloudwatch = boto3.client('cloudwatch')

  aws_access_key_id, aws_secret_access_key, region_name = credentials_AWS (account)
    
   
   cloudwatch = connect_service_aws ('cloudwatch', aws_access_key_id, 
                 aws_secret_access_key, region_name)

  response = cloudwatch.get_metric_statistics(
    Namespace='AWS/S3',
    Dimensions=[
        {
            'Name': 'BucketName',
            'Value': 'foo-bar'
        },
        {
            'Name': 'StorageType',
            'Value': 'StandardStorage'
        }
    ],
    MetricName='BucketSizeBytes',
    StartTime=datetime.now() - timedelta(days=7),
    EndTime=datetime.now(),
    Period=seconds_in_one_day,
    Statistics=[
        'Average'
    ],
    Unit='Bytes'
  )

  print(response)
1
Italo Gervasio

コードに明らかに問題はないので、この地域はここでは主な容疑者のように見えます。

次の方法でクライアントを作成するときに設定できます。

cloudwatch = boto3.client('cloudwatch', region_name='us-west-2')

これが設定されていない場合、botoは最初にAWS_DEFAULT_REGION env変数から領域を取得しようとし、次に~/.aws/config構成ファイルを取得しようとします。それらをチェックして、デフォルトのリージョンセットが何であるかを確認してください。

1
Dejan Peretin

私はこれを解決することができました。 boto3呼び出しでDimensionsパラメーターを指定する必要があります。

0
bradnation

他の誰かがこれを必要とする場合に備えて、実行可能な回避策がありますが、それでも、わかりにくい答えが存在する場合はそれを見つけたいと思います。そうではないかもしれません。コマンドラインを生成し、pythonを使用して実行し、jsonの結果(同じ最終結果)を取得することにしました。

s3 = boto3.resource('s3')
s3_client = boto3.client('s3')

command = "aws cloudwatch get-metric-statistics --metric-name BucketSizeBytes --namespace AWS/S3 --start-time {} --end-time {} --statistics Average --unit     Bytes --region {} --dimensions Name=BucketName,Value={}   Name=StorageType,Value=StandardStorage --period 86400 --output json"

for bucket in s3.buckets.all():
    region = s3_client.get_bucket_location(Bucket=bucket.name)
    region_name = region['LocationConstraint']

    start_date = datetime.now() - timedelta(days=7)
    start_date_str = str(start_date.date()) + 'T00:00:00Z'
    end_date = datetime.now()
    end_date_str = str(end_date.date()) + 'T00:00:00Z'
    cmd = command.format(start_date_str, end_date_str, region_name, bucket.name)
    res = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
    bucket_stats = json.loads(res.decode('ascii'))
    if len(bucket_stats['Datapoints']) > 0:
        print(bucket_stats['Datapoints'])
0
Bruce Van Horn

これは、boto3を使用してpythonでcloudwatchからデータを取得するための非常に良い例の1つです。動作させるために数時間を費やす必要がありましたが、今は簡単に参照できるはずです。

def get_req_count(region, lb_name):
    client = boto3.client('cloudwatch', region_name=region)
    count = 0
    response = client.get_metric_statistics(
            Namespace="AWS/ApplicationELB",
            MetricName="RequestCount",
            Dimensions=[
                {
                    "Name": "LoadBalancer",
                    "Value": lb_name
                },
            ],
            StartTime=str_yesterday,
            EndTime=str_today,
            Period=86460,
            Statistics=[
                "Sum",
            ]
    )   

    #print(response2)        
    for r in response['Datapoints']:
        count = (r['Sum'])

    return count    
0
user2570772