From c101d0ca5e967b440f65830837056eedaaa27778 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Henrique=20Ivanchechen?= Date: Thu, 31 Aug 2023 18:47:04 -0300 Subject: [PATCH] tentativa de ram e cpu --- scripts/graph.py | 63 ++++++++++++++++++++++++++++++++---- scripts/testes.py | 81 +++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 124 insertions(+), 20 deletions(-) diff --git a/scripts/graph.py b/scripts/graph.py index 0ad4f1c..d53569b 100644 --- a/scripts/graph.py +++ b/scripts/graph.py @@ -1,3 +1,4 @@ +import numpy as np import matplotlib.pyplot as plt def plot_graph(x, y, title, x_label, y_label, filename): @@ -9,7 +10,39 @@ def plot_graph(x, y, title, x_label, y_label, filename): plt.clf() -def getData(filename): +def plot_resource_graph(x, y, title, x_label, y_label, filename): + requests = x + resource = { + 'CPU': (p[0] for p in y), + 'RAM': (p[1] for p in y), + } + + x = np.arange(len(requests)) + width = 0.25 + multiplier = 0 + + fig, ax = plt.subplots(layout='constrained') + + for attribute, measurement in resource.items(): + offset = width * multiplier + + rects = ax.bar(x + offset, measurement, width, label=attribute) + ax.bar_label(rects, padding=3) + multiplier += 1 + + # Add some text for labels, title and custom x-axis tick labels, etc. + ax.set_xlabel(x_label) + ax.set_ylabel(y_label) + ax.set_title(title) + ax.set_xticks(x + width, requests) + ax.legend(loc='upper left', ncols=len(resource.items())) + ax.set_ylim(0, 250) + + plt.savefig(f'resources_{filename}.png') + + plt.clf() + +def get_data(filename): lines = [] with open(filename, 'r') as f: lines = f.readlines() @@ -24,11 +57,29 @@ def getData(filename): return x, y -def generateGraph(filename, framework_name, endpoint_name): - x, y = getData(filename) +def get_resource_data(filename): + lines = [] + with open(filename, 'r') as f: + lines = f.readlines() + + x = [] + y = [] + for line in lines: + line = line.strip().split(',') + if line: + x.append(int(line[0])) # requests + y.append([float(v) for v in line[1:]]) # cpu, ram + + return x, y + +def generate_req_graph(filename, framework_name, endpoint_name): + x, y = get_data(filename) new_filename = filename.replace('.txt', '').replace('.csv', '') - plot_graph(x, y, f'{framework_name} - {endpoint_name}', 'Number of requests', 'Requests per second', new_filename) + plot_graph(x, y, f'{framework_name} - {endpoint_name}', 'Número de requisições', 'Requisições por segundo', new_filename) -if __name__ == '__main__': - generateGraph('data.txt', 'Teste', 'endpoint') +def generate_resource_graph(filename, framework_name, endpoint_name): + x, y = get_resource_data(filename) + + new_filename = filename.replace('.txt', '').replace('.csv', '') + plot_resource_graph(x, y, f'{framework_name} - {endpoint_name}', 'Uso de recursos', 'Uso (%)', new_filename) \ No newline at end of file diff --git a/scripts/testes.py b/scripts/testes.py index 2c085be..fe8010a 100644 --- a/scripts/testes.py +++ b/scripts/testes.py @@ -1,22 +1,27 @@ import requests +import docker import concurrent.futures import time import sys import os -from graph import generateGraph +from graph import generate_req_graph, generate_resource_graph from math import floor -if len(sys.argv) != 2 or sys.argv[1] == '-h' or sys.argv[1] == '--help': - print("Usage: python testes.py ") +if len(sys.argv) != 3 or sys.argv[1] == '-h' or sys.argv[1] == '--help': + print("Usage: python testes.py ") sys.exit(1) THREADS = 10 FRAMEWORK_NAME = sys.argv[1] +CONTAINER_NAME = sys.argv[2] URL_BASE = 'http://172.26.48.1:9080' API_REQUESTS = [ - ('/status/ok', range(0, 50_000, 5000)), - ('/image/load-image', range(0, 50_000, 5000)), - ('/image/load-big-image', range(0, 1_000, 10)), + ('/status/ok', range(0, 30_000, 5000)), + ('/image/load-image', range(0, 30_000, 5000)), + ('/static/simpleimage.png', range(0, 30_000, 5000)), + ('/image/load-big-image', range(0, 1_000, 200)), + ('/static/bigimage.png', range(0, 1_000, 200)), + ('/static/video.mp4', range(0, 10_000, 1_000)), ] def send_request(url): @@ -35,18 +40,29 @@ def send_request(url): responses[floor(response.status_code/100)] += 1 return responses -def getFileName(endpoint): - endpoint = endpoint.replace('/', '_') - return f"{FRAMEWORK_NAME}_{endpoint}.csv" +def getFileNames(endpoint): + endpoint = endpoint.replace('/', '') + + files = [ + f"req_{FRAMEWORK_NAME}_{endpoint}.csv", + f"resource_{FRAMEWORK_NAME}_{endpoint}.csv", + ] + + return files def record(filename, requests, reqpersec): with open(filename, "a") as file: file.write(f"{requests},{reqpersec}\n") +def record_resource(filename, requests, cpu, ram): + with open(filename, "a") as file: + file.write(f"{requests},{cpu},{ram}\n") + def run_tests(endpoint, num_requests): - filename = getFileName(endpoint) - if os.path.exists(filename): - os.remove(filename) + files = getFileNames(endpoint) + for filename in files: + if os.path.exists(filename): + os.remove(filename) for num_request in num_requests: if num_request <= 0: continue @@ -54,6 +70,7 @@ def run_tests(endpoint, num_requests): ok_responses = 0 bad_responses = 0 server_errors = 0 + cpu, ram = 0, 0 with concurrent.futures.ThreadPoolExecutor(max_workers=THREADS) as executor: url = f'{URL_BASE}{endpoint}' @@ -67,6 +84,8 @@ def run_tests(endpoint, num_requests): concurrent.futures.wait(futures) + cpu, ram = get_resource_usage() + elapsed_time = time.time() - start_time for future in futures: @@ -76,11 +95,45 @@ def run_tests(endpoint, num_requests): server_errors += responses[5] print(f"{num_request}: {elapsed_time:.2f} seconds. {elapsed_time/num_request:.4f} seconds per request. {num_request/elapsed_time:.2f} requests per second. [OK: {ok_responses}, Bad Request: {bad_responses}, Server Error: {server_errors}]]") - record(filename, num_request, f"{num_request/elapsed_time:.2f}") - generateGraph(filename, FRAMEWORK_NAME, endpoint) + record(files[0], num_request, f"{num_request/elapsed_time:.2f}") + record_resource(files[1], num_request, cpu, ram) + + generate_req_graph(files[0], FRAMEWORK_NAME, endpoint) + generate_req_graph(files[1], FRAMEWORK_NAME, endpoint) time.sleep(3) +def get_resource_usage(): + try: + client = docker.from_env() + stats = client.containers.get(CONTAINER_NAME).stats(stream=False) + except: + return 0, 0 # unable to get stats + + return get_cpu_usage(stats), get_ram_usage(stats) + +def get_cpu_usage(stats): + UsageDelta = stats['cpu_stats']['cpu_usage']['total_usage'] - stats['precpu_stats']['cpu_usage']['total_usage'] + + SystemDelta = stats['cpu_stats']['cpu_usage']['system_cpu_usage'] - stats['precpu_stats']['cpu_usage']['system_cpu_usage'] + + len_cpu = len(stats['cpu_stats']['cpu_usage']['percpu_usage']) + + percentage = (UsageDelta / SystemDelta) * len_cpu * 100 + + # percent = round(percentage, 2) + return f"{percentage:.2f}" + +def get_ram_usage(stats): + usage = stats['memory_stats']['usage'] + limit = stats['memory_stats']['limit'] + + percentage = (usage / limit) * 100 + + # percent = round(percentage, 2) + return f"{percentage:.2f}" + + for endpoint, num_requests in API_REQUESTS: print(f"# {endpoint}") run_tests(endpoint, num_requests)