使用python将单元格写入CSV单元格
我写了Python Boto3代码,以获取过去2天的平均EC2 CPU利用率/天。这是代码:
import boto3
import datetime
import csv
accountId = boto3.client('sts').get_caller_identity()['Account']
session = boto3.session.Session()
region = session.region_name
ec2 = session.resource('ec2',region_name=region)
s3 = session.resource('s3')
fields = ['Account' , 'Region' , 'InstanceID' , 'InstanceName']
start = datetime.datetime.today() - datetime.timedelta(days=2)
end = datetime.datetime.today()
instanceId = ''
instanceName = ''
rows = []
filename = 'CPUUtilization.csv'
def get_cpu_utilization(instanceId):
cw = boto3.client('cloudwatch',region_name=region)
res = cw.get_metric_statistics(
Namespace = 'AWS/EC2',
Period = 86400,
StartTime = start,
EndTime = end,
MetricName = 'CPUUtilization',
Statistics = ['Average'],
Unit = 'Percent',
Dimensions = [
{
'Name' : 'InstanceId',
'Value' : instanceId
}
]
)
return res
def lambda_handler(event, context):
for instance in ec2.instances.all():
if instance.tags != None:
for tags in instance.tags:
if tags['Key'] == 'Name':
instanceName = tags['Value']
break
instanceId = str(instance.id)
response = get_cpu_utilization(instanceId)
rows.append([accountId, region, instanceId, instanceName])
for r in response['Datapoints']:
day = r['Timestamp'].date()
week = day.strftime('%a')
avg = r['Average']
day_uti = ' '.join([str(day),week])
fields.append(day_uti)
rows.append([avg])
with open("/tmp/"+filename, 'w+') as csvfile:
csvwriter = csv.writer(csvfile)
csvwriter.writerow(fields)
csvwriter.writerows(rows)
csvfile.close()
s3.Bucket('instances-cmdb').upload_file('/tmp/CPUUtilization.csv', 'CPUUtilization.csv')
写入CSV文件的输出是这样的:
平均CPU利用率值是打印的在A3单元格中,但必须在日期下打印/写入E2单元格。并且所有以下几天要写入第一行,并且相应的值应在其各自的日期下逐个单元格第二行。
我该如何实现?
我还有其他几个与AWS CloudWatch指标有关的问题。
这个特定的实例在整天(2022年4月1日)中停止状态。该lambda功能仍然在当天提供了一些CPU利用率。当我从控制台检查相同的情况时,我看不到任何数据。怎么可能?我是犯任何错误吗?
当我多次运行此功能时,我获得了不同的CPU利用率值。上述图像来自第1个执行(AVG CPU利用率= 0.110935 ...)。以下是第二执行的结果
在同一天相同实例的AVG CPU利用率不同, (0.53698 ..)以前的结果。这是我身边的错误还是什么?
请帮忙。
注意:我的帐户中只有一个实例,它在整天(2022年4月1日)处于停止状态,仅在2022年4月2日左右开始。
I've written a Python boto3 code to get the average EC2 CPU utilization/day for the last 2 days. Here's the code:
import boto3
import datetime
import csv
accountId = boto3.client('sts').get_caller_identity()['Account']
session = boto3.session.Session()
region = session.region_name
ec2 = session.resource('ec2',region_name=region)
s3 = session.resource('s3')
fields = ['Account' , 'Region' , 'InstanceID' , 'InstanceName']
start = datetime.datetime.today() - datetime.timedelta(days=2)
end = datetime.datetime.today()
instanceId = ''
instanceName = ''
rows = []
filename = 'CPUUtilization.csv'
def get_cpu_utilization(instanceId):
cw = boto3.client('cloudwatch',region_name=region)
res = cw.get_metric_statistics(
Namespace = 'AWS/EC2',
Period = 86400,
StartTime = start,
EndTime = end,
MetricName = 'CPUUtilization',
Statistics = ['Average'],
Unit = 'Percent',
Dimensions = [
{
'Name' : 'InstanceId',
'Value' : instanceId
}
]
)
return res
def lambda_handler(event, context):
for instance in ec2.instances.all():
if instance.tags != None:
for tags in instance.tags:
if tags['Key'] == 'Name':
instanceName = tags['Value']
break
instanceId = str(instance.id)
response = get_cpu_utilization(instanceId)
rows.append([accountId, region, instanceId, instanceName])
for r in response['Datapoints']:
day = r['Timestamp'].date()
week = day.strftime('%a')
avg = r['Average']
day_uti = ' '.join([str(day),week])
fields.append(day_uti)
rows.append([avg])
with open("/tmp/"+filename, 'w+') as csvfile:
csvwriter = csv.writer(csvfile)
csvwriter.writerow(fields)
csvwriter.writerows(rows)
csvfile.close()
s3.Bucket('instances-cmdb').upload_file('/tmp/CPUUtilization.csv', 'CPUUtilization.csv')
The output written to the CSV file is like this:
The average CPU utilization value is printed in the A3 cell, but this has to be printed/written to E2 cell under the date. And all the subsequent days to be written to 1st row and the corresponding values should go to 2nd row, cell by cell, under their respective dates.
How can I achieve this?
I have a couple of other questions related to AWS CloudWatch metrics.
This particular instance was in stopped state the whole day (1st April 2022). Still this Lambda function is giving some CPU utilization value on that day. When I checked for the same from the console, I don't see any data. How is this possible? Am I making any mistake?
When I ran this function multiple times, I got different CPU utilization values. The above attached image was from 1st execution (Avg CPU utilization=0.110935...). Below is the result from 2nd execution
Here the avg CPU utilization for the same instance on the same day is different(0.53698..) from previous result. Is this mistake from my side or what?
Please help.
NOTE: There is only one instance in my account and it was in stopped state the whole day (1st April 2022) and started only on 2nd April 2022 at around 8:00PM IST.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您需要重新考虑逻辑以添加返回的每个数据点的列。
行
list 包含每个行的一个条目。从此开始:在 list 中创建一个条目,该列表是一个具有四个值的列表。
稍后,代码尝试添加另一列,
其中以下列以
行
具有的值[[accountId,region,instanceID,instanceName],[avg]]
。这添加了另一个 row ,这就是为什么它以单独的线路出现在CSV文件中的原因。代码不是添加另一行,而是需要在现有行中添加另一个条目。
最简单的方法是将行保存在列表中,而只有一旦您拥有 all 。
因此,您可以替换以下行:
稍后
可以添加到:
然后,之后 for loop已完成添加所有列,可以存储使用:
另外,请注意此行:
它将日期添加到
字段
列表中,但是如果有多个实例,每个实例将添加一个条目。我认为您希望它们是同一日期,因此它不会像您期望的那样奏效。You need to rethink your logic for adding columns for each datapoint returned.
The
row
list contains one entry per row. It starts with this:That creates one entry in the list that is a list with four values.
Later, the code attempts to add another column with:
This results in
rows
having the value of[[accountId, region, instanceId, instanceName], [avg]]
.This is adding another row, which is why it is appearing in the CSV file as a separate line. Rather than adding another row, the code needs to add another entry in the existing row.
The easiest way to do this would be to save the row in a list and only add the 'row' once you have all the information for the row.
So, you could replace this line:
with:
And you could later add to it with:
Then, after the
for
loop has completed adding all the columns, it can be stored with:Also, be careful with this line:
It is adding the date to the
fields
list, but if there is more than one instance, each instance will add an entry. I presume you want them to be the same date, so it won't work out like you expect.