def collect_metrics(env, strategy, servers_patched, servers_being_emptied, migrations_data): """ Gather metrics from the current maintenance step. Supported metrics: - Simulation steps - Number of servers being updated - Number of servers being emptied - Number of updated servers - Number of nonupdated servers - Vulnerability Surface (Severo et al. 2020) - Number of VM migrations - Overall migrations duration (amount of time spent with migrations in the current step) - Longer migration - Shorter migration - Average migration duration - Servers occupation rate - Servers consolidation rate Parameters ========== env : SimPy.Environment Used to quantity the amount of simulation time spent by the migration strategy : String Name of the used maintenance strategy servers_patched : List List of servers updated in the current maintenance step servers_being_emptied : List List of servers being emptied in the current maintenance step migrations_data : List Information on each migration performed in the current maintenance step Returns ======= output : Dictionary List of metrics collected during the current maintenance step """ output = {} # Number of simulation steps output['simulation_steps'] = env.now # Name of the used maintenance strategy output['strategy'] = strategy # Other simulation metrics output['metrics'] = {} # Number of updated and nonupdated servers output['metrics']['updated_servers'] = len(Server.updated()) output['metrics']['nonupdated_servers'] = len(Server.nonupdated()) # Vulnerability Surface (Severo et al. 2020) = Number of non-updated servers * Elapsed time output['metrics']['vulnerability_surface'] = env.now * output['metrics'][ 'nonupdated_servers'] # Gathering VM migration metrics output['metrics']['vm_migrations'] = 0 output['metrics']['migrations_duration'] = 0 output['metrics']['longer_migration'] = 0 output['metrics']['shorter_migration'] = 0 output['metrics']['avg_migration_duration'] = 0 if len(migrations_data) > 0: # Number of VM migrations performed in this interval output['metrics']['vm_migrations'] = len(migrations_data) # Time spent performing VM migrations migrations_duration = sum(migr['duration'] for migr in migrations_data) output['metrics']['migrations_duration'] = migrations_duration # Longer migration output['metrics']['longer_migration'] = max( migr['duration'] for migr in migrations_data) # Shorter migration output['metrics']['shorter_migration'] = min( migr['duration'] for migr in migrations_data) # Average migration duration output['metrics'][ 'avg_migration_duration'] = migrations_duration / len( migrations_data) # Gathering server-related metrics # Occupation rate aggregated_occupation_rate = sum(sv.occupation_rate() for sv in Server.all()) output['metrics']['occupation_rate'] = aggregated_occupation_rate / len( Server.used_servers()) # Consolidation rate output['metrics']['consolidation_rate'] = Server.consolidation_rate() # Servers being updated output['metrics']['servers_being_updated'] = len(servers_patched) # Servers being emptied output['metrics']['servers_being_emptied'] = len(servers_being_emptied) return (output)
def show_metrics(dataset, heuristic, output_file=None): """ Presents information and metrics of the performed placement and optionally stores these results into an output CSV file. Currently, this method outputs the following metrics: - Servers occupation rate - Servers consolidation rate Parameters ========== dataset : String Name of the used dataset heuristic : STring Name of the used placement heuristic output_file : String Optional parameters regarding the name of the output CSV file """ # Servers occupation rate occupation_rate = sum(sv.occupation_rate() for sv in Server.all()) / len(Server.used_servers()) # Servers consolidation rate consolidation_rate = Server.consolidation_rate() # Prints out the placement metrics print( '========================\n== SIMULATION RESULTS ==\n========================' ) print(f'Dataset: "{dataset}"') print(f'Placement Strategy: {heuristic}\n') print(f'Consolidation Rate: {consolidation_rate}') print(f'Occupation Rate: {occupation_rate}\n') print('Placement:') for server in Server.all(): vms = [vm.id for vm in server.virtual_machines] print(f'SV_{server.id}. VMs: {vms}') # If the output_file parameter was provided, stores the placement results into a CSV file if output_file: with open(output_file, mode='w') as csv_file: output_writer = csv.writer(csv_file, delimiter='\t', quotechar='"', quoting=csv.QUOTE_MINIMAL) # Creating header output_writer.writerow([ 'Dataset', 'Strategy', 'No. of Servers', 'No. of VMs', 'Occupation Rate', 'Consolidation Rate' ]) # Creating body output_writer.writerow([ dataset, heuristic, Server.count(), VirtualMachine.count(), occupation_rate, consolidation_rate ])