Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add PERCENTILES_TO_CHART param in stats.py to make the Response Time Chart configurable #2313

Merged
merged 13 commits into from Mar 12, 2023
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 4 additions & 1 deletion locust/html.py
Expand Up @@ -8,6 +8,7 @@
from html import escape
from json import dumps
from .runners import MasterRunner, STATE_STOPPED, STATE_STOPPING
from .stats import PERCENTILES_TO_CHART


def render_template(file, **kwargs):
Expand All @@ -19,7 +20,7 @@ def render_template(file, **kwargs):

def get_html_report(environment, show_download_link=True):
stats = environment.runner.stats

options = environment.parsed_options
cyberw marked this conversation as resolved.
Show resolved Hide resolved
start_ts = stats.start_time
start_time = datetime.datetime.utcfromtimestamp(start_ts).strftime("%Y-%m-%d %H:%M:%S")

Expand Down Expand Up @@ -94,6 +95,8 @@ def get_html_report(environment, show_download_link=True):
show_download_link=show_download_link,
locustfile=environment.locustfile,
tasks=dumps(task_data),
percentile1=PERCENTILES_TO_CHART[0],
percentile2=PERCENTILES_TO_CHART[1],
)

return res
20 changes: 19 additions & 1 deletion locust/main.py
Expand Up @@ -100,6 +100,24 @@ def main():
user_classes[key] = value
available_user_classes[key] = value

if len(stats.PERCENTILES_TO_CHART) > 2:
sys.stderr.write("stats.PERCENTILES_TO_CHART parameter can be specified up tp 2 parameters \n")
cyberw marked this conversation as resolved.
Show resolved Hide resolved
sys.exit(1)

def is_valid_percentile(parameter):
try:
if 0 < float(parameter) < 1:
return True
return False
except ValueError:
return False

for percentile in stats.PERCENTILES_TO_CHART:
if not is_valid_percentile(percentile):
sys.stderr.write(
"stats.PERCENTILES_TO_CHART parameter need to be float and value between. 0 <= percentile <= 1 Eg 0.95\n"
)
sys.exit(1)
# parse all command line options
options = parse_options()

Expand Down Expand Up @@ -160,7 +178,6 @@ def main():
user_classes = list(user_classes.values())

if os.name != "nt" and not options.master:

try:
import resource

Expand All @@ -180,6 +197,7 @@ def main():

# create locust Environment
locustfile_path = None if not locustfile else os.path.basename(locustfile)

environment = create_environment(
user_classes,
options,
Expand Down
2 changes: 1 addition & 1 deletion locust/static/locust.js
Expand Up @@ -235,7 +235,7 @@ function update_stats_charts(){

// init charts
var rpsChart = new LocustLineChart($(".charts-container"), "Total Requests per Second", ["RPS", "Failures/s"], "reqs/s", ['#00ca5a', '#ff6d6d']);
var responseTimeChart = new LocustLineChart($(".charts-container"), "Response Times (ms)", ["Median Response Time", "95% percentile"], "ms");
var responseTimeChart = new LocustLineChart($(".charts-container"), "Response Times (ms)", [(percentile2 * 100).toString() + "% percentile" , (percentile1 * 100).toString() + "% percentile"], "ms");
var usersChart = new LocustLineChart($(".charts-container"), "Number of Users", ["Users"], "users");
charts.push(rpsChart, responseTimeChart, usersChart);
echarts.connect([rpsChart.chart,responseTimeChart.chart,usersChart.chart])
Expand Down
8 changes: 6 additions & 2 deletions locust/stats.py
Expand Up @@ -133,6 +133,8 @@ def resize_handler(signum: int, frame: Optional[FrameType]):

PERCENTILES_TO_REPORT = [0.50, 0.66, 0.75, 0.80, 0.90, 0.95, 0.98, 0.99, 0.999, 0.9999, 1.0]

PERCENTILES_TO_CHART = [0.95, 0.50]
cyberw marked this conversation as resolved.
Show resolved Hide resolved


class RequestStatsAdditionError(Exception):
pass
Expand Down Expand Up @@ -888,8 +890,10 @@ def stats_history(runner: "Runner") -> None:
"time": datetime.datetime.now(tz=datetime.timezone.utc).strftime("%H:%M:%S"),
"current_rps": stats.total.current_rps or 0,
"current_fail_per_sec": stats.total.current_fail_per_sec or 0,
"response_time_percentile_95": stats.total.get_current_response_time_percentile(0.95) or 0,
"response_time_percentile_50": stats.total.get_current_response_time_percentile(0.5) or 0,
"response_time_percentile_95": stats.total.get_current_response_time_percentile(PERCENTILES_TO_CHART[0])
cyberw marked this conversation as resolved.
Show resolved Hide resolved
or 0,
"response_time_percentile_50": stats.total.get_current_response_time_percentile(PERCENTILES_TO_CHART[1])
or 0,
"user_count": runner.user_count or 0,
}
stats.history.append(r)
Expand Down
2 changes: 2 additions & 0 deletions locust/templates/index.html
Expand Up @@ -357,6 +357,8 @@ <h2>Version <a href="https://github.com/locustio/locust/releases/tag/{{version}}
]]>
</script>
<script type="text/javascript">
var percentile1 = {{ percentile1|tojson }};
var percentile2 = {{ percentile2|tojson }};
{% include 'stats_data.html' %}
</script>
<script type="text/javascript" src="./static/chart.js?v={{ version }}"></script>
Expand Down
4 changes: 3 additions & 1 deletion locust/templates/report.html
Expand Up @@ -198,8 +198,10 @@ <h2>Final ratio</h2>

<script>
{% include 'stats_data.html' %}
var percentile1 = {{ percentile1|tojson }}
var percentile2 = {{ percentile2|tojson }}
var rpsChart = new LocustLineChart($(".charts-container"), "Total Requests per Second", ["RPS", "Failures/s"], "reqs/s", ['#00ca5a', '#ff6d6d']);
var responseTimeChart = new LocustLineChart($(".charts-container"), "Response Times (ms)", ["Median Response Time", "95% percentile"], "ms");
var responseTimeChart = new LocustLineChart($(".charts-container"), "Response Times (ms)", [(percentile2*100).toString() + "% percentile" , (percentile1*100).toString() + "% percentile"], "ms");
var usersChart = new LocustLineChart($(".charts-container"), "Number of Users", ["Users"], "users");

if(stats_history["time"].length > 0){
Expand Down
9 changes: 6 additions & 3 deletions locust/web.py
Expand Up @@ -3,6 +3,7 @@
import logging
import os.path
from functools import wraps

from html import escape
from io import StringIO
from json import dumps
Expand All @@ -20,7 +21,7 @@
from .log import greenlet_exception_logger
from .stats import StatsCSVFileWriter, StatsErrorDict, sort_stats
from . import stats as stats_module, __version__ as version, argument_parser
from .stats import StatsCSV
from .stats import StatsCSV, PERCENTILES_TO_CHART
from .user.inspectuser import get_ratio
from .util.cache import memoize
from .util.rounding import proper_round
Expand Down Expand Up @@ -389,10 +390,10 @@ def request_stats() -> Response:
report["fail_ratio"] = environment.runner.stats.total.fail_ratio
report[
"current_response_time_percentile_95"
] = environment.runner.stats.total.get_current_response_time_percentile(0.95)
] = environment.runner.stats.total.get_current_response_time_percentile(PERCENTILES_TO_CHART[0])
report[
"current_response_time_percentile_50"
] = environment.runner.stats.total.get_current_response_time_percentile(0.5)
] = environment.runner.stats.total.get_current_response_time_percentile(PERCENTILES_TO_CHART[1])

if isinstance(environment.runner, MasterRunner):
workers = []
Expand Down Expand Up @@ -555,6 +556,8 @@ def update_template_args(self):
"show_userclass_picker": self.userclass_picker_is_active,
"available_user_classes": available_user_classes,
"available_shape_classes": available_shape_classes,
"percentile1": PERCENTILES_TO_CHART[0],
"percentile2": PERCENTILES_TO_CHART[1],
}

def _update_shape_class(self, shape_class_name):
Expand Down