Created
February 13, 2023 20:16
-
-
Save JacobCallahan/aa41e34e381af4c9987c21837df63f8d to your computer and use it in GitHub Desktop.
Point at a foreman production.log file and see the most frequently used foreman/katello api endpoints
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"""Some utilities for scraping Satellite production logs""" | |
import argparse | |
from pathlib import Path | |
def log_to_dicts(log_path): | |
"""Convert a Satellite log file to a list of dict log entries""" | |
dict_list = [] | |
log_entry = {} | |
current_group = "" | |
with log_path.open() as log_file: | |
for line in log_file: | |
if " Started " in line: | |
current_group = "Started" | |
elif " Processing " in line: | |
current_group = "Processing" | |
elif " Parameters:" in line: | |
current_group = "Parameters" | |
elif " Completed " in line: | |
log_entry["Completed"] = line | |
current_group = "" | |
if "/api/" in log_entry["Started"]: | |
dict_list.append(log_entry) | |
log_entry = {} | |
if current_group: | |
if current_group in log_entry: | |
log_entry[current_group] += line | |
else: | |
log_entry[current_group] = line | |
return dict_list | |
def path_sanitizer(api_path): | |
"""Remove numerical ids from the api path""" | |
path_list = api_path.split("/") | |
for index, path in enumerate(path_list): | |
if path.isdigit(): | |
path_list[index] = "<id>" | |
return "/".join(path_list) | |
def endpoint_counter(dict_list): | |
"""Count the number of times each endpoint is called""" | |
endpoint_dict = {} | |
for log_entry in dict_list: | |
endpoint = path_sanitizer((split_path := log_entry["Started"].split())[4]) | |
endpoint = f"{split_path[3]} {endpoint}" | |
if endpoint in endpoint_dict: | |
endpoint_dict[endpoint] += 1 | |
else: | |
endpoint_dict[endpoint] = 1 | |
return endpoint_dict | |
def sorted_endpoints(endpoint_dict): | |
"""Sort the endpoint dictionary by number of calls""" | |
return sorted(endpoint_dict.items(), key=lambda item: item[1], reverse=True) | |
if __name__ == "__main__": | |
parser = argparse.ArgumentParser() | |
parser.add_argument("log_path", help="Path to the production.log file") | |
args = parser.parse_args() | |
log_path = args.log_path | |
if not (log_path := Path(log_path)).is_file(): | |
raise FileNotFoundError(f"{log_path} is not a file") | |
dict_list = log_to_dicts(log_path) | |
endpoint_dict = endpoint_counter(dict_list) | |
sorted_endpoints = sorted_endpoints(endpoint_dict) | |
for endpoint, count in sorted_endpoints: | |
print(f"{endpoint}: {count}") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment