![](/img/trans.png)
[英]Python's fromtimestamp returns inconsistent results on different machines
[英]Python function returns inconsistent results
我编写了一个脚本来列出 Amazon Web Services 中的 EC2 实例。 它将结果写入汇合。 但它的行为很奇怪。
我在 Windows 10 上。第一次打开 powershell 终端并运行它时,它会报告 AWS 帐户中正确的服务器数量。
下次我运行它时(根本不改变任何东西)它会使结果翻倍。 每次使用相同的参数再次运行它时,它都会报告相同的错误(加倍)数量。
这是列出实例的函数,这是我认为问题所在,但我很难找到它:
def list_instances(aws_account, aws_account_number, interactive, regions, fieldnames, show_details):
today, aws_env_list, output_file, output_file_name, fieldnames = initialize(interactive, aws_account) options = arguments() instance_list = '' session = '' ec2 = '' account_found = '' PrivateDNS = None block_device_list = None instance_count = 0 account_type_message = '' profile_missing_message = '' region = ''
# Set the ec2 dictionary
ec2info = {}
# Write the file headers
if interactive == 1:
with open(output_file, mode='w+') as csv_file:
writer = csv.DictWriter(csv_file, fieldnames=fieldnames, delimiter=',', lineterminator='\n')
writer.writeheader()
if 'gov' in aws_account and not 'admin' in aws_account:
try:
session = boto3.Session(profile_name=aws_account,region_name=region)
account_found = 'yes'
except botocore.exceptions.ProfileNotFound as e:
message = f"An exception has occurred: {e}"
account_found = 'no'
banner(message)
else:
try:
session = boto3.Session(profile_name=aws_account,region_name=region)
account_found = 'yes'
except botocore.exceptions.ProfileNotFound as e:
message = f"An exception has occurred: {e}"
account_found = 'no'
banner(message)
print(Fore.CYAN)
report_gov_or_comm(aws_account, account_found)
print(Fore.RESET)
for region in regions:
if 'gov' in aws_account and not 'admin' in aws_account:
try:
session = boto3.Session(profile_name=aws_account,region_name=region)
except botocore.exceptions.ProfileNotFound as e:
profile_missing_message = f"An exception has occurred: {e}" account_found = 'no' pass else: try: session = boto3.Session(profile_name=aws_account,region_name=region) account_found = 'yes' except botocore.exceptions.ProfileNotFound as e: profile_missing_message = f"An exception has occurred: {e}" pass try: ec2 = session.client("ec2") except Exception as e: pass
# Loop through the instances
try:
instance_list = ec2.describe_instances()
except Exception as e:
pass
try:
for reservation in instance_list["Reservations"]:
for instance in reservation.get("Instances", []):
instance_count = instance_count + 1
launch_time = instance["LaunchTime"]
launch_time_friendly = launch_time.strftime("%B %d %Y")
tree = objectpath.Tree(block_devices = set(tree.execute('$..BlockDeviceMappings['Ebs']['VolumeId']'))
if block_devices:
block_devices = list(block_devices)
block_devices = str(block_devices).replace('[','').replace(']','').replace("'",'')
else:
block_devices = None
private_ips = set(tree.execute('$..PrivateIpAddress'))
if private_ips:
private_ips_list = list(private_ips) private_ips_list = str(private_ips_list).replace('[','').replace(']','').replace(''','')
else:
private_ips_list = None
type(private_ips_list)
public_ips = set(tree.execute('$..PublicIp'))
if len(public_ips) == 0:
public_ips = None
if public_ips:
public_ips_list = list(public_ips)
public_ips_list = str(public_ips_list).replace('[','').replace(']','').replace("'",'')
else:
public_ips_list = None
if 'KeyName' in instance:
key_name = instance['KeyName']
else:
key_name = None
name = None
if 'Tags' in instance:
try:
tags = instance['Tags']
name = None
for tag in tags:
if tag["Key"] == "Name":
name = tag["Value"]
if tag["Key"] == "Engagement" or tag["Key"] == "Engagement Code":
engagement = tag["Value"]
except ValueError:
print("Instance: %s has no tags" % instance_id
pass
if 'VpcId' in instance:
vpc_id = instance['VpcId'] else: vpc_id = None if 'PrivateDnsName' in instance: private_dns = instance['PrivateDnsName'] else: private_dns = None if 'Platform' in instance: platform = instance['Platform'] else: platform = None print(f"Platform: {platform}") ec2info[instance['InstanceId']] = { 'AWS Account': aws_account, 'Account Number': aws_account_number, 'Name': name, 'Instance ID': instance['InstanceId'], 'Volumes': block_devices, 'Private IP': private_ips_list, 'Public IP': public_ips_list, 'Private DNS': private_dns, 'Availability Zone': instance['Placement']['AvailabilityZone'], 'VPC ID': vpc_id, 'Type': instance['InstanceType'], 'Platform': platform, 'Key Pair Name': key_name, 'State': instance['State']['Name'], 'Launch Date': launch_time_friendly } with open(output_file,'a') as csv_file: writer = csv.DictWriter(csv_file, fieldnames=fieldnames, delimiter=',', lineterminator='\n') writer.writerow({'AWS Account': aws_account, "Account Number": aws_account_number, 'Name': name, 'Instance ID': instance["InstanceId"], 'Volumes': block_devices, 'Private IP': private_ips_list, 'Public IP': public_ips_list, 'Private DNS': private_dns, 'Availability Zone': instance['Placement']['AvailabilityZone'], 'VPC ID': vpc_id, 'Type': instance["InstanceType"], 'Platform': platform, 'Key Pair Name': key_name, 'State': instance["State"]["Name"], 'Launch Date': launch_time_friendly})
if show_details == 'y' or show_details == 'yes': for instance_id, instance in ec2info.items(): if account_found == 'yes': print(Fore.RESET + "-------------------------------------") for key in [ 'AWS Account', 'Account Number', 'Name', 'Instance ID', 'Volumes', 'Private IP', 'Public IP', 'Private DNS', 'Availability Zone', 'VPC ID', 'Type', 'Platform', 'Key Pair Name', 'State', 'Launch Date' ]: print(Fore.GREEN + f"{key}: {instance.get(key)}") print(Fore.RESET + "-------------------------------------") else: pass ec2info = {} with open(output_file,'a') as csv_file: csv_file.close() except Exception as e: pass if profile_missing_message == '*': banner(profile_missing_message) print(Fore.GREEN) report_instance_stats(instance_count, aws_account, account_found) print(Fore.RESET + '\n') return output_file
这是上下文的整个代码的粘贴: aws_ec2_list_instances.py
第一次从命令行运行它时,它会报告 EC2 中正确的服务器总数(可以在 AWS 控制台中验证):
----------------------------------------------------------
There are: 51 EC2 instances in AWS Account: company-lab.
----------------------------------------------------------
下一次它以绝对没有改变的情况运行时,它会报告这个总数:
----------------------------------------------------------
There are: 102 EC2 instances in AWS Account: company-lab.
----------------------------------------------------------
您实际上只是向上箭头命令,它会使结果加倍。 当它写入 confluence 时,您可以看到列出了重复的服务器。 每次向上箭头再次运行它时,它都会这样做,但总数不正确(102 个服务器)。
如果您关闭 powershell 命令行并再次打开,它将返回报告正确结果(51 个服务器),这与您在 AWS 控制台中看到的内容相对应。 这到底是怎么回事? 为什么要这样做,我该如何解决问题?
这相当神秘! 我认为如果不访问您的环境,我将无法对其进行调试。 我的建议是您使用pdb来尝试弄清楚instance_count
如何增加超过 51。我建议添加import pdb; pdb.set_trace()
import pdb; pdb.set_trace()
在第 210 行,即for reservation in instance_list["Reservations"]:
。 然后,您可以每次通过循环检查instance_count
的值,查看instance_list["Reservations"]
是否实际上以某种方式具有重复数据等。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.