关于python代码结构、函数和调用函数的问题



我尝试创建一个函数来做以下事情。(不知道是否值得一提,但这个函数是由另一个函数调用的)

  1. 使用boto3连接aws资源
  2. 获取sqs队列中可用的消息数
  3. 计算ec2实例的数量
  4. 基于sqs队列和ec2实例计算一组条件,要么不做任何事情,要么写入sns主题。

基本上我想在每次sqs队列高且消化这些的ec2实例数量低时向sns主题发布消息。

import os
import boto3
import logging
import types
logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)
# Create session and clients
sts_client = boto3.client('sts')
sqs_client = boto3.client('sqs')
ec2_client = boto3.client('ec2')
sns_client = boto3.client('sns')
# Call the assume_role method of the STSConnection object and pass the role ARN and a role session name.
assumed_role_object = sts_client.assume_role(
RoleArn=os.environ['ROLE_ARN'],
RoleSessionName="AssumeRoleFromCloudOperations"
)
# From the response that contains the assumed role, get the temporary credentials
credentials = assumed_role_object['Credentials']
assumed_role_session = boto3.Session(
aws_access_key_id=credentials['AccessKeyId'],
aws_secret_access_key=credentials['SecretAccessKey'],
aws_session_token=credentials['SessionToken']
)

# Check the queue size
def sqs():
queue_size = sqs_client.get_queue_attributes(
QueueUrl=os.environ['SQS_QUEUE_URL'],
AttributeNames=['ApproximateNumberOfMessages']
)
messages = int(queue_size["Attributes"]["ApproximateNumberOfMessages"])
return messages

# Count the number of active ec2 instances
def count_instances(ec2):
total_instances = 0
instances = ec2.instances.filter(Filters=[
{
'Instance State': 'instance-state-name',
'Values': ['running'],
'Name': 'tag:Name',
'Values': ['NameOfInstance']
},
])
for _ in instances:
total_instances += 1
return total_instances
print(f"Total number of active scan servers is: {total_instances}")

# Define the SNS Topic which will be integrated with OpsGenie
def sns():
topicArn = os.environ['SNS_ARN']

# Evaluate the set of conditions
def evaluate_conditions(context, event):
sqs()
if messages > int(os.environ['AVG_QUEUE_SIZE']) and count_instances.total_instances > int(os.environ['AVG_NR_OF_EC2_SCAN_SERVERS']):
print('False alert')
logger.info()
elif messages < int(os.environ['AVG_QUEUE_SIZE']) and count_instances.total_instances < int(os.environ['AVG_NR_OF_EC2_SCAN_SERVERS']):
print('False alert')
logger.info()
elif messages < int(os.environ['AVG_QUEUE_SIZE']) and count_instances.total_instances > int(os.environ['AVG_NR_OF_EC2_SCAN_SERVERS']):
print('False alert')
logger.info()
else:
sns.publish(TopicArn=os.environ['SNS_ARN'],
Message='sameple message',
Subject='sample subject')
print("Published to SNS Topic")

处理程序为handler.evaluate_conditions

我的问题是我怎么能有一些结构在这个lambda函数?当我运行这个函数时,我得到一个命名错误:

{
"errorMessage": "name 'messages' is not defined",
"errorType": "NameError",
"stackTrace": [
"  File "/var/task/mdc_alert/handler.py", line 67, in evaluate_conditionsn    if messages > int(os.environ['AVG_QUEUE_SIZE']) and count_instances.total_instances > int(n"
]
}

因此,我似乎不能在evaluate_conditions()函数中使用消息变量。我该如何制作"信息"呢?和";total_instances"在evaluate_conditions()函数可用的变量?

我已经写了这个函数完全基于谷歌搜索,stackoverflow和boto3文档,因为我没有任何编程经验。

这个结构好吗,还是需要彻底检修?我需要改变函数的顺序,或者创建一个类吗?

直接的问题是没有定义messages变量。你的sqs函数返回一个值,但因为你在一个void上下文中调用它,你实际上并没有做任何与该值。您可以通过修改这一行来修复这个问题:

sqs()

:

messages = sqs()

我还看到count_instances函数的一些问题。它期望接收一个ec2变量,但是您从evaluate_conditions错误地调用了它。您可以将ec2_client变量传递给它,也可以直接从函数中使用ec2_client变量。

我建议重命名你的函数,以更准确地反映它们的返回值:

sqs -> sqs_msg_count
count_instances -> running_ec2_count

进行这些更改将允许您重构evaluate_conditions以缩短if-then行,使您的代码总体上更易于阅读和遵循。如果您考虑了所有这些建议,您的代码可能看起来像这样:

# Check the queue size
def sqs_msg_count():
messages = sqs_client.get_queue_attributes(
QueueUrl=os.environ['SQS_QUEUE_URL'],
AttributeNames=['ApproximateNumberOfMessages']
)
return int(messages["Attributes"]["ApproximateNumberOfMessages"])
# Count the number of active ec2 instances
def running_instance_count():
running_instances = ec2_client.instances.filter(Filters=[
{
'Instance State': 'instance-state-name',
'Values': ['running'],
'Name': 'tag:Name',
'Values': ['NameOfInstance']
},
])
return len(running_instances)
# Evaluate the set of conditions
def evaluate_conditions(context, event):
sqs_count = sqs_msg_count()
sqs_average = int(os.environ['AVG_QUEUE_SIZE'])
ec2_count = running_instance_count()
ec2_average = int(os.environ['AVG_NR_OF_EC2_SCAN_SERVERS'])

if sqs_count > sqs_average and ec2_count > ec2_average:
print('False alert')
logger.info()
elif sqs_count < sqs_average and ec2_count < ec2_average:
print('False alert')
logger.info()
elif sqs_count < sqs_average and ec2_count > ec2_average:
print('False alert')
logger.info()
else:
sns_client.publish(
TopicArn=os.environ['SNS_ARN'],
Message='sameple message',
Subject='sample subject'
)
print("Published to SNS Topic")

最新更新