簡體   English   中英

關於python代碼結構、函數和調用函數的問題

[英]Question about python code structure, functions and calling functions

我試圖創建一個執行以下操作的函數。 (不知道是否值得一提,但這個函數是由另一個函數調用的)

  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_conditions\n    if messages > int(os.environ['AVG_QUEUE_SIZE']) and count_instances.total_instances > int(\n"
  ]
}

所以似乎我不能在evaluate_conditions() 函數中使用消息變量。 如何使“message”和“total_instances”變量在evaluate_conditions() 函數中可用?

我完全基於谷歌搜索、stackoverflow 和 boto3 文檔編寫了這個函數,因為我沒有任何編程經驗。

這種結構有什么好處,還是需要徹底檢修? 我是否需要更改函數的順序,或者創建一個類?

直接的問題是沒有定義messages變量。 您的sqs函數返回一個值,但由於您在 void 上下文中調用它,因此您實際上並未對該值執行任何操作。 您可以通過更改此行來解決此問題:

sqs()

對這個:

messages = sqs()

我還看到 count_instances 函數存在一些問題。 它期望收到一個ec2變量,但您從評估條件中錯誤地調用了它。 您可以將 ec2_client 變量傳遞給它,也可以直接從函數內部使用 ec2_client 變量。

我建議重命名您的函數以更准確地反映它們的返回值:

sqs -> sqs_msg_count
count_instances -> running_ec2_count

進行這些更改將允許您重構評估條件以縮短 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_client)
    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")

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM