1*3c7ae9deSAndroid Build Coastguard Worker# Python wrapper script for collecting Canary metrics, setting-up/tearing-down alarms, reporting metrics to Cloudwatch, 2*3c7ae9deSAndroid Build Coastguard Worker# checking the alarms to ensure everything is correct at the end of the run, and pushing the log to S3 if successful. 3*3c7ae9deSAndroid Build Coastguard Worker 4*3c7ae9deSAndroid Build Coastguard Worker# Needs to be installed prior to running 5*3c7ae9deSAndroid Build Coastguard Worker# Part of standard packages in Python 3.4+ 6*3c7ae9deSAndroid Build Coastguard Workerimport argparse 7*3c7ae9deSAndroid Build Coastguard Workerimport time 8*3c7ae9deSAndroid Build Coastguard Workerimport datetime 9*3c7ae9deSAndroid Build Coastguard Worker# Dependencies in project folder 10*3c7ae9deSAndroid Build Coastguard Workerfrom CanaryWrapper_Classes import * 11*3c7ae9deSAndroid Build Coastguard Workerfrom CanaryWrapper_MetricFunctions import * 12*3c7ae9deSAndroid Build Coastguard Worker 13*3c7ae9deSAndroid Build Coastguard Worker# Code for command line argument parsing 14*3c7ae9deSAndroid Build Coastguard Worker# ================================================================================ 15*3c7ae9deSAndroid Build Coastguard Workercommand_parser = argparse.ArgumentParser("CanaryWrapper") 16*3c7ae9deSAndroid Build Coastguard Workercommand_parser.add_argument("--canary_executable", type=str, required=True, 17*3c7ae9deSAndroid Build Coastguard Worker help="The path to the canary executable (or program - like 'python3')") 18*3c7ae9deSAndroid Build Coastguard Workercommand_parser.add_argument("--canary_arguments", type=str, default="", 19*3c7ae9deSAndroid Build Coastguard Worker help="The arguments to pass/launch the canary executable with") 20*3c7ae9deSAndroid Build Coastguard Workercommand_parser.add_argument("--git_hash", type=str, required=True, 21*3c7ae9deSAndroid Build Coastguard Worker help="The Git commit hash that we are running the canary with") 22*3c7ae9deSAndroid Build Coastguard Workercommand_parser.add_argument("--git_repo_name", type=str, required=True, 23*3c7ae9deSAndroid Build Coastguard Worker help="The name of the Git repository") 24*3c7ae9deSAndroid Build Coastguard Workercommand_parser.add_argument("--git_hash_as_namespace", type=bool, default=False, 25*3c7ae9deSAndroid Build Coastguard Worker help="(OPTIONAL, default=False) If true, the git hash will be used as the name of the Cloudwatch namespace") 26*3c7ae9deSAndroid Build Coastguard Workercommand_parser.add_argument("--output_log_filepath", type=str, default="output.log", 27*3c7ae9deSAndroid Build Coastguard Worker help="(OPTIONAL, default=output.log) The file to output log info to. Set to 'None' to disable") 28*3c7ae9deSAndroid Build Coastguard Workercommand_parser.add_argument("--output_to_console", type=bool, default=True, 29*3c7ae9deSAndroid Build Coastguard Worker help="(OPTIONAL, default=True) If true, info will be output to the console") 30*3c7ae9deSAndroid Build Coastguard Workercommand_parser.add_argument("--cloudwatch_region", type=str, default="us-east-1", 31*3c7ae9deSAndroid Build Coastguard Worker help="(OPTIONAL, default=us-east-1) The AWS region for Cloudwatch") 32*3c7ae9deSAndroid Build Coastguard Workercommand_parser.add_argument("--s3_bucket_name", type=str, default="canary-wrapper-folder", 33*3c7ae9deSAndroid Build Coastguard Worker help="(OPTIONAL, default=canary-wrapper-folder) The name of the S3 bucket where success logs will be stored") 34*3c7ae9deSAndroid Build Coastguard Workercommand_parser.add_argument("--snapshot_wait_time", type=int, default=600, 35*3c7ae9deSAndroid Build Coastguard Worker help="(OPTIONAL, default=600) The number of seconds between gathering and sending snapshot reports") 36*3c7ae9deSAndroid Build Coastguard Workercommand_parser.add_argument("--ticket_category", type=str, default="AWS", 37*3c7ae9deSAndroid Build Coastguard Worker help="(OPTIONAL, default=AWS) The category to register the ticket under") 38*3c7ae9deSAndroid Build Coastguard Workercommand_parser.add_argument("--ticket_type", type=str, default="SDKs and Tools", 39*3c7ae9deSAndroid Build Coastguard Worker help="(OPTIONAL, default='SDKs and Tools') The type to register the ticket under") 40*3c7ae9deSAndroid Build Coastguard Workercommand_parser.add_argument("--ticket_item", type=str, default="IoT SDK for CPP", 41*3c7ae9deSAndroid Build Coastguard Worker help="(OPTIONAL, default='IoT SDK for CPP') The item to register the ticket under") 42*3c7ae9deSAndroid Build Coastguard Workercommand_parser.add_argument("--ticket_group", type=str, default="AWS IoT Device SDK", 43*3c7ae9deSAndroid Build Coastguard Worker help="(OPTIONAL, default='AWS IoT Device SDK') The group to register the ticket under") 44*3c7ae9deSAndroid Build Coastguard Workercommand_parser.add_argument("--dependencies", type=str, default="", 45*3c7ae9deSAndroid Build Coastguard Worker help="(OPTIONAL, default='') Any dependencies and their commit hashes. \ 46*3c7ae9deSAndroid Build Coastguard Worker Current expected format is '(name or path);(hash);(next name or path);(hash);(etc...)'.") 47*3c7ae9deSAndroid Build Coastguard Workercommand_parser.add_argument("--lambda_name", type=str, default="iot-send-email-lambda", 48*3c7ae9deSAndroid Build Coastguard Worker help="(OPTIONAL, default='CanarySendEmailLambda') The name of the Lambda used to send emails") 49*3c7ae9deSAndroid Build Coastguard Workercommand_parser.add_argument("--codebuild_log_path", type=str, default="", 50*3c7ae9deSAndroid Build Coastguard Worker help="The CODEBUILD_LOG_PATH environment variable. Leave blank to ignore") 51*3c7ae9deSAndroid Build Coastguard Workercommand_parser_arguments = command_parser.parse_args() 52*3c7ae9deSAndroid Build Coastguard Worker 53*3c7ae9deSAndroid Build Coastguard Workerif (command_parser_arguments.output_log_filepath == "None"): 54*3c7ae9deSAndroid Build Coastguard Worker command_parser_arguments.output_log_filepath = None 55*3c7ae9deSAndroid Build Coastguard Workerif (command_parser_arguments.snapshot_wait_time <= 0): 56*3c7ae9deSAndroid Build Coastguard Worker command_parser_arguments.snapshot_wait_time = 60 57*3c7ae9deSAndroid Build Coastguard Worker 58*3c7ae9deSAndroid Build Coastguard Worker# Deal with possibly empty values in semi-critical commands/arguments 59*3c7ae9deSAndroid Build Coastguard Workerif (command_parser_arguments.canary_executable == ""): 60*3c7ae9deSAndroid Build Coastguard Worker print ("ERROR - required canary_executable is empty!", flush=True) 61*3c7ae9deSAndroid Build Coastguard Worker exit (1) # cannot run without a canary executable 62*3c7ae9deSAndroid Build Coastguard Workerif (command_parser_arguments.git_hash == ""): 63*3c7ae9deSAndroid Build Coastguard Worker print ("ERROR - required git_hash is empty!", flush=True) 64*3c7ae9deSAndroid Build Coastguard Worker exit (1) # cannot run without git hash 65*3c7ae9deSAndroid Build Coastguard Workerif (command_parser_arguments.git_repo_name == ""): 66*3c7ae9deSAndroid Build Coastguard Worker print ("ERROR - required git_repo_name is empty!", flush=True) 67*3c7ae9deSAndroid Build Coastguard Worker exit (1) # cannot run without git repo name 68*3c7ae9deSAndroid Build Coastguard Workerif (command_parser_arguments.git_hash_as_namespace is not True and command_parser_arguments.git_hash_as_namespace is not False): 69*3c7ae9deSAndroid Build Coastguard Worker command_parser_arguments.git_hash_as_namespace = False 70*3c7ae9deSAndroid Build Coastguard Workerif (command_parser_arguments.output_log_filepath == ""): 71*3c7ae9deSAndroid Build Coastguard Worker command_parser_arguments.output_log_filepath = None 72*3c7ae9deSAndroid Build Coastguard Workerif (command_parser_arguments.output_to_console != True and command_parser_arguments.output_to_console != False): 73*3c7ae9deSAndroid Build Coastguard Worker command_parser_arguments.output_to_console = True 74*3c7ae9deSAndroid Build Coastguard Workerif (command_parser_arguments.cloudwatch_region == ""): 75*3c7ae9deSAndroid Build Coastguard Worker command_parser_arguments.cloudwatch_region = "us-east-1" 76*3c7ae9deSAndroid Build Coastguard Workerif (command_parser_arguments.s3_bucket_name == ""): 77*3c7ae9deSAndroid Build Coastguard Worker command_parser_arguments.s3_bucket_name = "canary-wrapper-folder" 78*3c7ae9deSAndroid Build Coastguard Workerif (command_parser_arguments.ticket_category == ""): 79*3c7ae9deSAndroid Build Coastguard Worker command_parser_arguments.ticket_category = "AWS" 80*3c7ae9deSAndroid Build Coastguard Workerif (command_parser_arguments.ticket_type == ""): 81*3c7ae9deSAndroid Build Coastguard Worker command_parser_arguments.ticket_type = "SDKs and Tools" 82*3c7ae9deSAndroid Build Coastguard Workerif (command_parser_arguments.ticket_item == ""): 83*3c7ae9deSAndroid Build Coastguard Worker command_parser_arguments.ticket_item = "IoT SDK for CPP" 84*3c7ae9deSAndroid Build Coastguard Workerif (command_parser_arguments.ticket_group == ""): 85*3c7ae9deSAndroid Build Coastguard Worker command_parser_arguments.ticket_group = "AWS IoT Device SDK" 86*3c7ae9deSAndroid Build Coastguard Worker 87*3c7ae9deSAndroid Build Coastguard Worker 88*3c7ae9deSAndroid Build Coastguard Worker 89*3c7ae9deSAndroid Build Coastguard Worker# ================================================================================ 90*3c7ae9deSAndroid Build Coastguard Worker 91*3c7ae9deSAndroid Build Coastguard Workerdatetime_now = datetime.datetime.now() 92*3c7ae9deSAndroid Build Coastguard Workerdatetime_string = datetime_now.strftime("%d-%m-%Y/%H-%M-%S") 93*3c7ae9deSAndroid Build Coastguard Workerprint("Datetime string is: " + datetime_string, flush=True) 94*3c7ae9deSAndroid Build Coastguard Worker 95*3c7ae9deSAndroid Build Coastguard Worker# Make the snapshot class 96*3c7ae9deSAndroid Build Coastguard Workerdata_snapshot = DataSnapshot( 97*3c7ae9deSAndroid Build Coastguard Worker git_hash=command_parser_arguments.git_hash, 98*3c7ae9deSAndroid Build Coastguard Worker git_repo_name=command_parser_arguments.git_repo_name, 99*3c7ae9deSAndroid Build Coastguard Worker datetime_string=datetime_string, 100*3c7ae9deSAndroid Build Coastguard Worker git_hash_as_namespace=command_parser_arguments.git_hash_as_namespace, 101*3c7ae9deSAndroid Build Coastguard Worker git_fixed_namespace_text="mqtt5_canary", 102*3c7ae9deSAndroid Build Coastguard Worker output_log_filepath="output.txt", 103*3c7ae9deSAndroid Build Coastguard Worker output_to_console=command_parser_arguments.output_to_console, 104*3c7ae9deSAndroid Build Coastguard Worker cloudwatch_region="us-east-1", 105*3c7ae9deSAndroid Build Coastguard Worker cloudwatch_make_dashboard=False, 106*3c7ae9deSAndroid Build Coastguard Worker cloudwatch_teardown_alarms_on_complete=True, 107*3c7ae9deSAndroid Build Coastguard Worker cloudwatch_teardown_dashboard_on_complete=True, 108*3c7ae9deSAndroid Build Coastguard Worker s3_bucket_name=command_parser_arguments.s3_bucket_name, 109*3c7ae9deSAndroid Build Coastguard Worker s3_bucket_upload_on_complete=True, 110*3c7ae9deSAndroid Build Coastguard Worker lambda_name=command_parser_arguments.lambda_name, 111*3c7ae9deSAndroid Build Coastguard Worker metric_frequency=command_parser_arguments.snapshot_wait_time) 112*3c7ae9deSAndroid Build Coastguard Worker 113*3c7ae9deSAndroid Build Coastguard Worker# Make sure nothing failed 114*3c7ae9deSAndroid Build Coastguard Workerif (data_snapshot.abort_due_to_internal_error == True): 115*3c7ae9deSAndroid Build Coastguard Worker print ("INFO - Stopping application due to error caused by credentials") 116*3c7ae9deSAndroid Build Coastguard Worker print ("Please fix your credentials and then restart this application again", flush=True) 117*3c7ae9deSAndroid Build Coastguard Worker exit(0) 118*3c7ae9deSAndroid Build Coastguard Worker 119*3c7ae9deSAndroid Build Coastguard Worker# Register metrics 120*3c7ae9deSAndroid Build Coastguard Workerdata_snapshot.register_metric( 121*3c7ae9deSAndroid Build Coastguard Worker new_metric_name="total_cpu_usage", 122*3c7ae9deSAndroid Build Coastguard Worker new_metric_function=get_metric_total_cpu_usage, 123*3c7ae9deSAndroid Build Coastguard Worker new_metric_unit="Percent", 124*3c7ae9deSAndroid Build Coastguard Worker new_metric_alarm_threshold=70, 125*3c7ae9deSAndroid Build Coastguard Worker new_metric_reports_to_skip=1, 126*3c7ae9deSAndroid Build Coastguard Worker new_metric_alarm_severity=5, 127*3c7ae9deSAndroid Build Coastguard Worker is_percent=True) 128*3c7ae9deSAndroid Build Coastguard Workerdata_snapshot.register_metric( 129*3c7ae9deSAndroid Build Coastguard Worker new_metric_name="total_memory_usage_value", 130*3c7ae9deSAndroid Build Coastguard Worker new_metric_function=get_metric_total_memory_usage_value, 131*3c7ae9deSAndroid Build Coastguard Worker new_metric_unit="Bytes") 132*3c7ae9deSAndroid Build Coastguard Workerdata_snapshot.register_metric( 133*3c7ae9deSAndroid Build Coastguard Worker new_metric_name="total_memory_usage_percent", 134*3c7ae9deSAndroid Build Coastguard Worker new_metric_function=get_metric_total_memory_usage_percent, 135*3c7ae9deSAndroid Build Coastguard Worker new_metric_unit="Percent", 136*3c7ae9deSAndroid Build Coastguard Worker new_metric_alarm_threshold=70, 137*3c7ae9deSAndroid Build Coastguard Worker new_metric_reports_to_skip=0, 138*3c7ae9deSAndroid Build Coastguard Worker new_metric_alarm_severity=5, 139*3c7ae9deSAndroid Build Coastguard Worker is_percent=True) 140*3c7ae9deSAndroid Build Coastguard Worker 141*3c7ae9deSAndroid Build Coastguard Worker# Print diagnosis information 142*3c7ae9deSAndroid Build Coastguard Workerdata_snapshot.output_diagnosis_information(command_parser_arguments.dependencies) 143*3c7ae9deSAndroid Build Coastguard Worker 144*3c7ae9deSAndroid Build Coastguard Worker# Make the snapshot (metrics) monitor 145*3c7ae9deSAndroid Build Coastguard Workersnapshot_monitor = SnapshotMonitor( 146*3c7ae9deSAndroid Build Coastguard Worker wrapper_data_snapshot=data_snapshot, 147*3c7ae9deSAndroid Build Coastguard Worker wrapper_metrics_wait_time=command_parser_arguments.snapshot_wait_time) 148*3c7ae9deSAndroid Build Coastguard Worker 149*3c7ae9deSAndroid Build Coastguard Worker# Make sure nothing failed 150*3c7ae9deSAndroid Build Coastguard Workerif (snapshot_monitor.had_internal_error == True): 151*3c7ae9deSAndroid Build Coastguard Worker print ("INFO - Stopping application due to error caused by credentials") 152*3c7ae9deSAndroid Build Coastguard Worker print ("Please fix your credentials and then restart this application again", flush=True) 153*3c7ae9deSAndroid Build Coastguard Worker exit(0) 154*3c7ae9deSAndroid Build Coastguard Worker 155*3c7ae9deSAndroid Build Coastguard Worker# Make the application monitor 156*3c7ae9deSAndroid Build Coastguard Workerapplication_monitor = ApplicationMonitor( 157*3c7ae9deSAndroid Build Coastguard Worker wrapper_application_path=command_parser_arguments.canary_executable, 158*3c7ae9deSAndroid Build Coastguard Worker wrapper_application_arguments=command_parser_arguments.canary_arguments, 159*3c7ae9deSAndroid Build Coastguard Worker wrapper_application_restart_on_finish=False, 160*3c7ae9deSAndroid Build Coastguard Worker data_snapshot=data_snapshot # pass the data_snapshot for printing to the log 161*3c7ae9deSAndroid Build Coastguard Worker) 162*3c7ae9deSAndroid Build Coastguard Worker 163*3c7ae9deSAndroid Build Coastguard Worker# Make sure nothing failed 164*3c7ae9deSAndroid Build Coastguard Workerif (application_monitor.error_has_occurred == True): 165*3c7ae9deSAndroid Build Coastguard Worker print ("INFO - Stopping application due to error caused by credentials") 166*3c7ae9deSAndroid Build Coastguard Worker print ("Please fix your credentials and then restart this application again", flush=True) 167*3c7ae9deSAndroid Build Coastguard Worker exit(0) 168*3c7ae9deSAndroid Build Coastguard Worker 169*3c7ae9deSAndroid Build Coastguard Worker# For tracking if we stopped due to a metric alarm 170*3c7ae9deSAndroid Build Coastguard Workerstopped_due_to_metric_alarm = False 171*3c7ae9deSAndroid Build Coastguard Worker 172*3c7ae9deSAndroid Build Coastguard Workerexecution_sleep_time = 30 173*3c7ae9deSAndroid Build Coastguard Workerdef execution_loop(): 174*3c7ae9deSAndroid Build Coastguard Worker while True: 175*3c7ae9deSAndroid Build Coastguard Worker snapshot_monitor.monitor_loop_function( 176*3c7ae9deSAndroid Build Coastguard Worker time_passed=execution_sleep_time, psutil_process=application_monitor.application_process_psutil) 177*3c7ae9deSAndroid Build Coastguard Worker application_monitor.monitor_loop_function( 178*3c7ae9deSAndroid Build Coastguard Worker time_passed=execution_sleep_time) 179*3c7ae9deSAndroid Build Coastguard Worker 180*3c7ae9deSAndroid Build Coastguard Worker # Did a metric go into alarm? 181*3c7ae9deSAndroid Build Coastguard Worker if (snapshot_monitor.has_cut_ticket == True): 182*3c7ae9deSAndroid Build Coastguard Worker # Set that we had an 'internal error' so we go down the right code path 183*3c7ae9deSAndroid Build Coastguard Worker snapshot_monitor.had_internal_error = True 184*3c7ae9deSAndroid Build Coastguard Worker break 185*3c7ae9deSAndroid Build Coastguard Worker 186*3c7ae9deSAndroid Build Coastguard Worker # If an error has occurred or otherwise this thread needs to stop, then break the loop 187*3c7ae9deSAndroid Build Coastguard Worker if (application_monitor.error_has_occurred == True or snapshot_monitor.had_internal_error == True): 188*3c7ae9deSAndroid Build Coastguard Worker break 189*3c7ae9deSAndroid Build Coastguard Worker 190*3c7ae9deSAndroid Build Coastguard Worker time.sleep(execution_sleep_time) 191*3c7ae9deSAndroid Build Coastguard Worker 192*3c7ae9deSAndroid Build Coastguard Worker 193*3c7ae9deSAndroid Build Coastguard Workerdef application_thread(): 194*3c7ae9deSAndroid Build Coastguard Worker 195*3c7ae9deSAndroid Build Coastguard Worker start_email_body = "MQTT5 Short Running Canary Wrapper has started for " 196*3c7ae9deSAndroid Build Coastguard Worker start_email_body += "\"" + command_parser_arguments.git_repo_name + "\" commit \"" + command_parser_arguments.git_hash + "\"" 197*3c7ae9deSAndroid Build Coastguard Worker start_email_body += "\nThe wrapper will run for the length the MQTT5 Canary application is set to run for, which is determined by " 198*3c7ae9deSAndroid Build Coastguard Worker start_email_body += "the arguments set. The arguments used for this run are listed below:" 199*3c7ae9deSAndroid Build Coastguard Worker start_email_body += "\n Arguments: " + command_parser_arguments.canary_arguments 200*3c7ae9deSAndroid Build Coastguard Worker snapshot_monitor.send_email(email_body=start_email_body, email_subject_text_append="Started") 201*3c7ae9deSAndroid Build Coastguard Worker 202*3c7ae9deSAndroid Build Coastguard Worker # Start the application going 203*3c7ae9deSAndroid Build Coastguard Worker snapshot_monitor.start_monitoring() 204*3c7ae9deSAndroid Build Coastguard Worker application_monitor.start_monitoring() 205*3c7ae9deSAndroid Build Coastguard Worker # Allow the snapshot monitor to cut tickets 206*3c7ae9deSAndroid Build Coastguard Worker snapshot_monitor.can_cut_ticket = True 207*3c7ae9deSAndroid Build Coastguard Worker 208*3c7ae9deSAndroid Build Coastguard Worker # Start the execution loop 209*3c7ae9deSAndroid Build Coastguard Worker execution_loop() 210*3c7ae9deSAndroid Build Coastguard Worker 211*3c7ae9deSAndroid Build Coastguard Worker # Make sure everything is stopped 212*3c7ae9deSAndroid Build Coastguard Worker snapshot_monitor.stop_monitoring() 213*3c7ae9deSAndroid Build Coastguard Worker application_monitor.stop_monitoring() 214*3c7ae9deSAndroid Build Coastguard Worker 215*3c7ae9deSAndroid Build Coastguard Worker # Track whether this counts as an error (and therefore we should cleanup accordingly) or not 216*3c7ae9deSAndroid Build Coastguard Worker wrapper_error_occurred = False 217*3c7ae9deSAndroid Build Coastguard Worker # Finished Email 218*3c7ae9deSAndroid Build Coastguard Worker send_finished_email = True 219*3c7ae9deSAndroid Build Coastguard Worker finished_email_body = "MQTT5 Short Running Canary Wrapper has stopped." 220*3c7ae9deSAndroid Build Coastguard Worker finished_email_body += "\n\n" 221*3c7ae9deSAndroid Build Coastguard Worker 222*3c7ae9deSAndroid Build Coastguard Worker try: 223*3c7ae9deSAndroid Build Coastguard Worker # Find out why we stopped 224*3c7ae9deSAndroid Build Coastguard Worker if (snapshot_monitor.had_internal_error == True): 225*3c7ae9deSAndroid Build Coastguard Worker if (snapshot_monitor.has_cut_ticket == True): 226*3c7ae9deSAndroid Build Coastguard Worker # We do not need to cut a ticket here - it's cut by the snapshot monitor! 227*3c7ae9deSAndroid Build Coastguard Worker print ("ERROR - Snapshot monitor stopped due to metric in alarm!", flush=True) 228*3c7ae9deSAndroid Build Coastguard Worker finished_email_body += "Failure due to required metrics being in alarm! A new ticket should have been cut!" 229*3c7ae9deSAndroid Build Coastguard Worker finished_email_body += "\nMetrics in Alarm: " + str(snapshot_monitor.cloudwatch_current_alarms_triggered) 230*3c7ae9deSAndroid Build Coastguard Worker wrapper_error_occurred = True 231*3c7ae9deSAndroid Build Coastguard Worker else: 232*3c7ae9deSAndroid Build Coastguard Worker print ("ERROR - Snapshot monitor stopped due to internal error!", flush=True) 233*3c7ae9deSAndroid Build Coastguard Worker cut_ticket_using_cloudwatch( 234*3c7ae9deSAndroid Build Coastguard Worker git_repo_name=command_parser_arguments.git_repo_name, 235*3c7ae9deSAndroid Build Coastguard Worker git_hash=command_parser_arguments.git_hash, 236*3c7ae9deSAndroid Build Coastguard Worker git_hash_as_namespace=command_parser_arguments.git_hash_as_namespace, 237*3c7ae9deSAndroid Build Coastguard Worker git_fixed_namespace_text="mqtt5_canary", 238*3c7ae9deSAndroid Build Coastguard Worker cloudwatch_region="us-east-1", 239*3c7ae9deSAndroid Build Coastguard Worker ticket_description="Snapshot monitor stopped due to internal error! Reason info: " + snapshot_monitor.internal_error_reason, 240*3c7ae9deSAndroid Build Coastguard Worker ticket_reason="Snapshot monitor stopped due to internal error", 241*3c7ae9deSAndroid Build Coastguard Worker ticket_allow_duplicates=True, 242*3c7ae9deSAndroid Build Coastguard Worker ticket_category=command_parser_arguments.ticket_category, 243*3c7ae9deSAndroid Build Coastguard Worker ticket_item=command_parser_arguments.ticket_item, 244*3c7ae9deSAndroid Build Coastguard Worker ticket_group=command_parser_arguments.ticket_group, 245*3c7ae9deSAndroid Build Coastguard Worker ticket_type=command_parser_arguments.ticket_type, 246*3c7ae9deSAndroid Build Coastguard Worker ticket_severity=4) 247*3c7ae9deSAndroid Build Coastguard Worker wrapper_error_occurred = True 248*3c7ae9deSAndroid Build Coastguard Worker finished_email_body += "Failure due to Snapshot monitor stopping due to an internal error." 249*3c7ae9deSAndroid Build Coastguard Worker finished_email_body += " Reason given for error: " + snapshot_monitor.internal_error_reason 250*3c7ae9deSAndroid Build Coastguard Worker 251*3c7ae9deSAndroid Build Coastguard Worker elif (application_monitor.error_has_occurred == True): 252*3c7ae9deSAndroid Build Coastguard Worker if (application_monitor.error_due_to_credentials == True): 253*3c7ae9deSAndroid Build Coastguard Worker print ("INFO - Stopping application due to error caused by credentials") 254*3c7ae9deSAndroid Build Coastguard Worker print ("Please fix your credentials and then restart this application again", flush=True) 255*3c7ae9deSAndroid Build Coastguard Worker wrapper_error_occurred = True 256*3c7ae9deSAndroid Build Coastguard Worker send_finished_email = False 257*3c7ae9deSAndroid Build Coastguard Worker else: 258*3c7ae9deSAndroid Build Coastguard Worker # Is the error something in the canary failed? 259*3c7ae9deSAndroid Build Coastguard Worker if (application_monitor.error_code != 0): 260*3c7ae9deSAndroid Build Coastguard Worker cut_ticket_using_cloudwatch( 261*3c7ae9deSAndroid Build Coastguard Worker git_repo_name=command_parser_arguments.git_repo_name, 262*3c7ae9deSAndroid Build Coastguard Worker git_hash=command_parser_arguments.git_hash, 263*3c7ae9deSAndroid Build Coastguard Worker git_hash_as_namespace=command_parser_arguments.git_hash_as_namespace, 264*3c7ae9deSAndroid Build Coastguard Worker git_fixed_namespace_text="mqtt5_canary", 265*3c7ae9deSAndroid Build Coastguard Worker cloudwatch_region="us-east-1", 266*3c7ae9deSAndroid Build Coastguard Worker ticket_description="The Short Running Canary exited with a non-zero exit code! This likely means something in the canary failed.", 267*3c7ae9deSAndroid Build Coastguard Worker ticket_reason="The Short Running Canary exited with a non-zero exit code", 268*3c7ae9deSAndroid Build Coastguard Worker ticket_allow_duplicates=True, 269*3c7ae9deSAndroid Build Coastguard Worker ticket_category=command_parser_arguments.ticket_category, 270*3c7ae9deSAndroid Build Coastguard Worker ticket_item=command_parser_arguments.ticket_item, 271*3c7ae9deSAndroid Build Coastguard Worker ticket_group=command_parser_arguments.ticket_group, 272*3c7ae9deSAndroid Build Coastguard Worker ticket_type=command_parser_arguments.ticket_type, 273*3c7ae9deSAndroid Build Coastguard Worker ticket_severity=4) 274*3c7ae9deSAndroid Build Coastguard Worker wrapper_error_occurred = True 275*3c7ae9deSAndroid Build Coastguard Worker finished_email_body += "Failure due to MQTT5 application exiting with a non-zero exit code! This means something in the Canary application itself failed" 276*3c7ae9deSAndroid Build Coastguard Worker else: 277*3c7ae9deSAndroid Build Coastguard Worker print ("INFO - Stopping application. No error has occurred, application has stopped normally", flush=True) 278*3c7ae9deSAndroid Build Coastguard Worker application_monitor.print_stdout() 279*3c7ae9deSAndroid Build Coastguard Worker finished_email_body += "Short Running Canary finished successfully and run without errors!" 280*3c7ae9deSAndroid Build Coastguard Worker wrapper_error_occurred = False 281*3c7ae9deSAndroid Build Coastguard Worker else: 282*3c7ae9deSAndroid Build Coastguard Worker print ("ERROR - Short Running Canary stopped due to unknown reason!", flush=True) 283*3c7ae9deSAndroid Build Coastguard Worker cut_ticket_using_cloudwatch( 284*3c7ae9deSAndroid Build Coastguard Worker git_repo_name=command_parser_arguments.git_repo_name, 285*3c7ae9deSAndroid Build Coastguard Worker git_hash=command_parser_arguments.git_hash, 286*3c7ae9deSAndroid Build Coastguard Worker git_hash_as_namespace=command_parser_arguments.git_hash_as_namespace, 287*3c7ae9deSAndroid Build Coastguard Worker git_fixed_namespace_text="mqtt5_canary", 288*3c7ae9deSAndroid Build Coastguard Worker cloudwatch_region="us-east-1", 289*3c7ae9deSAndroid Build Coastguard Worker ticket_description="The Short Running Canary stopped for an unknown reason!", 290*3c7ae9deSAndroid Build Coastguard Worker ticket_reason="The Short Running Canary stopped for unknown reason", 291*3c7ae9deSAndroid Build Coastguard Worker ticket_allow_duplicates=True, 292*3c7ae9deSAndroid Build Coastguard Worker ticket_category=command_parser_arguments.ticket_category, 293*3c7ae9deSAndroid Build Coastguard Worker ticket_item=command_parser_arguments.ticket_item, 294*3c7ae9deSAndroid Build Coastguard Worker ticket_group=command_parser_arguments.ticket_group, 295*3c7ae9deSAndroid Build Coastguard Worker ticket_type=command_parser_arguments.ticket_type, 296*3c7ae9deSAndroid Build Coastguard Worker ticket_severity=4) 297*3c7ae9deSAndroid Build Coastguard Worker wrapper_error_occurred = True 298*3c7ae9deSAndroid Build Coastguard Worker finished_email_body += "Failure due to unknown reason! This shouldn't happen and means something has gone wrong!" 299*3c7ae9deSAndroid Build Coastguard Worker except Exception as e: 300*3c7ae9deSAndroid Build Coastguard Worker print ("ERROR: Could not (possibly) cut ticket due to exception!") 301*3c7ae9deSAndroid Build Coastguard Worker print ("Exception: " + str(e), flush=True) 302*3c7ae9deSAndroid Build Coastguard Worker 303*3c7ae9deSAndroid Build Coastguard Worker # Clean everything up and stop 304*3c7ae9deSAndroid Build Coastguard Worker snapshot_monitor.cleanup_monitor(error_occurred=wrapper_error_occurred) 305*3c7ae9deSAndroid Build Coastguard Worker application_monitor.cleanup_monitor(error_occurred=wrapper_error_occurred) 306*3c7ae9deSAndroid Build Coastguard Worker print ("Short Running Canary finished!", flush=True) 307*3c7ae9deSAndroid Build Coastguard Worker 308*3c7ae9deSAndroid Build Coastguard Worker finished_email_body += "\n\nYou can find the log file for this run at the following S3 location: " 309*3c7ae9deSAndroid Build Coastguard Worker finished_email_body += "https://s3.console.aws.amazon.com/s3/object/" 310*3c7ae9deSAndroid Build Coastguard Worker finished_email_body += command_parser_arguments.s3_bucket_name 311*3c7ae9deSAndroid Build Coastguard Worker finished_email_body += "?region=" + command_parser_arguments.cloudwatch_region 312*3c7ae9deSAndroid Build Coastguard Worker finished_email_body += "&prefix=" + command_parser_arguments.git_repo_name + "/" + datetime_string + "/" 313*3c7ae9deSAndroid Build Coastguard Worker if (wrapper_error_occurred == True): 314*3c7ae9deSAndroid Build Coastguard Worker finished_email_body += "Failed_Logs/" 315*3c7ae9deSAndroid Build Coastguard Worker finished_email_body += command_parser_arguments.git_hash + ".log" 316*3c7ae9deSAndroid Build Coastguard Worker if (command_parser_arguments.codebuild_log_path != ""): 317*3c7ae9deSAndroid Build Coastguard Worker print ("\n Codebuild log path: " + command_parser_arguments.codebuild_log_path + "\n") 318*3c7ae9deSAndroid Build Coastguard Worker 319*3c7ae9deSAndroid Build Coastguard Worker # Send the finish email 320*3c7ae9deSAndroid Build Coastguard Worker if (send_finished_email == True): 321*3c7ae9deSAndroid Build Coastguard Worker if (wrapper_error_occurred == True): 322*3c7ae9deSAndroid Build Coastguard Worker snapshot_monitor.send_email(email_body=finished_email_body, email_subject_text_append="Had an error") 323*3c7ae9deSAndroid Build Coastguard Worker else: 324*3c7ae9deSAndroid Build Coastguard Worker snapshot_monitor.send_email(email_body=finished_email_body, email_subject_text_append="Finished") 325*3c7ae9deSAndroid Build Coastguard Worker 326*3c7ae9deSAndroid Build Coastguard Worker exit (application_monitor.error_code) 327*3c7ae9deSAndroid Build Coastguard Worker 328*3c7ae9deSAndroid Build Coastguard Worker 329*3c7ae9deSAndroid Build Coastguard Worker# Start the application! 330*3c7ae9deSAndroid Build Coastguard Workerapplication_thread() 331