def get_memory_size(fn_log): memory_size_regex = re.compile("Memory Size: \d*") try: if memory_size := re.search(memory_size_regex, fn_log): return int(memory_size.group().replace("Memory Size: ", "").strip()) except TypeError: log("Could not parse Memory Size from lambda invocation log", ERROR)
def parse_logs(test_num): log(f'Parsing logs for test: {test_num}') test_logs_path = get_logs_root_path(test_num) logs_dir = f'{logs_dir_path}/{test_logs_path}/' for log_dir in os.listdir(logs_dir): fn_name = log_dir fn_logs_dir = logs_dir + fn_name image_size_mb = get_fn_image_size(fn_name) csv_results = [] for log_file in os.listdir(fn_logs_dir): log(f'Parsing logs file {log_file} in dir {fn_logs_dir}') fn_log = read_file(fn_logs_dir + '/' + log_file) csv_results.append([ image_size_mb, get_memory_size(fn_log), get_init_duration(fn_log), get_artificial_init_duration(fn_log), get_duration(fn_log), get_available_threads(fn_log) ]) full_path = results_dir_path + test_logs_path + fn_name + '.csv' write_to_csv(csv_results, results_header, full_path) write_average_init_duration(test_num, results_dir_path + test_logs_path)
def get_init_duration(fn_log): init_duration_regex = re.compile("Init Duration: \d*.\d*") try: if init_duration := re.search(init_duration_regex, fn_log): return float(init_duration.group().replace("Init Duration: ", "").strip()) except TypeError: log("Could not parse Init Duration from lambda invocation log", ERROR) return 0
def get_available_threads(fn_log): available_threads_regex = re.compile("Available threads: \d*.\d*") try: if threads := re.search(available_threads_regex, fn_log): return int(threads.group().replace("Available threads: ", "").strip()) except TypeError: log("Could not parse Available threads from lambda invocation log", ERROR) return 1
def get_artificial_init_duration(fn_log): billed_duration_regex = re.compile("Artificial initialization duration took: \d*.\d*") try: if billed_duration := re.search(billed_duration_regex, fn_log): return float(billed_duration.group().replace("Artificial initialization duration took: ", "").strip()) except TypeError: log("Could not parse Artificial Init Duration from lambda invocation log", ERROR) return 0
def is_cold_started(log_str): is_cold_start_log_regex = re.compile("Invoked a cold start function") try: if re.search(is_cold_start_log_regex, log_str): return True else: log("Function was not started cold. Skipping writing log", DEBUG) return False except TypeError: return False
def parse_response_logs(fn_name, invocation_response): log("Parsing function {} invocation response logs".format(fn_name)) log_result_regex = re.compile("\"LogResult\": [^,]*") base64_log = "" try: if log_result := re.search(log_result_regex, invocation_response): base64_log = log_result.group().replace("\"LogResult\": ", "").replace("\"", "") except TypeError: log("Could not parse invocation log") return base64_log return decode_base64(base64_log)
def write_response_logs(fn_name, invocation_response, test_num): log_str = parse_response_logs(fn_name, invocation_response) if not is_cold_started(log_str): return test_num_logs_path = get_logs_root_path(test_num) uuid_regex = re.compile( "[0-9a-f]{8}\\b-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-\\b[0-9a-f]{12}") try: if uuid := re.search(uuid_regex, fn_name): fn_id = uuid.group() now = datetime.now().strftime("%Y-%m-%d-%H:%M:%S") log_dir = f'{logs_dir_path}/{test_num_logs_path}/{fn_name.replace(fn_id, "")}/{now}-{fn_id}' write_to_file(log_str, log_dir) except TypeError: log("Could not parse request id from invocation logs", ERROR)
def get_fn_image_size(fn_name): fn_tag = get_fn_tag(fn_name) image_details = run_executable( executable_path=describe_image_exec_path, args=[REPOSITORY_NAME, fn_tag] ) image_byte_size_regex = re.compile("\"imageSizeInBytes\": \\d*") try: if image_byte_size := re.search(image_byte_size_regex, image_details): image_bytes = int(image_byte_size.group().replace("\"imageSizeInBytes\": ", "")) return round(image_bytes / 1000 / 1000, 2) except TypeError: log("Could not get function image size. This might be because provided image name is wrong", ERROR) return 0