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はコマンドラインと同等ですか?それらがそうであると仮定すると、何が欠けている可能性がありますか?
エラーはあなたのコマンド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)
コードに明らかに問題はないので、この地域はここでは主な容疑者のように見えます。
次の方法でクライアントを作成するときに設定できます。
cloudwatch = boto3.client('cloudwatch', region_name='us-west-2')
これが設定されていない場合、botoは最初にAWS_DEFAULT_REGION
env変数から領域を取得しようとし、次に~/.aws/config
構成ファイルを取得しようとします。それらをチェックして、デフォルトのリージョンセットが何であるかを確認してください。
私はこれを解決することができました。 boto3呼び出しでDimensionsパラメーターを指定する必要があります。
他の誰かがこれを必要とする場合に備えて、実行可能な回避策がありますが、それでも、わかりにくい答えが存在する場合はそれを見つけたいと思います。そうではないかもしれません。コマンドラインを生成し、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'])
これは、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