Skip to content

Commit

Permalink
Add two missing headlines (99.9% and 99.99%) to the response time per…
Browse files Browse the repository at this point in the history
…centiles printed to the console.

Some refactoring around the stats printing.
  • Loading branch information
heyman committed Nov 15, 2019
1 parent cffd751 commit 313182b
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 30 deletions.
4 changes: 2 additions & 2 deletions locust/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -511,8 +511,8 @@ def shutdown(code=0):
runners.locust_runner.quit()
logger.info("Running teardowns...")
events.quitting.fire(reverse=True)
print_stats(runners.locust_runner.request_stats)
print_percentile_stats(runners.locust_runner.request_stats)
print_stats(runners.locust_runner.stats)
print_percentile_stats(runners.locust_runner.stats)
if options.csvfilebase:
write_stat_csvs(options.csvfilebase)
print_error_report()
Expand Down
52 changes: 26 additions & 26 deletions locust/stats.py
Original file line number Diff line number Diff line change
Expand Up @@ -659,40 +659,40 @@ def on_slave_report(client_id, data):
def print_stats(stats):
console_logger.info((" %-" + str(STATS_NAME_WIDTH) + "s %7s %12s %7s %7s %7s | %7s %7s %7s") % ('Name', '# reqs', '# fails', 'Avg', 'Min', 'Max', 'Median', 'req/s', 'failures/s'))
console_logger.info("-" * (80 + STATS_NAME_WIDTH))
total_rps = 0
total_fail_per_sec = 0
total_reqs = 0
total_failures = 0
for key in sorted(six.iterkeys(stats)):
r = stats[key]
total_rps += r.current_rps
total_fail_per_sec += r.current_fail_per_sec
total_reqs += r.num_requests
total_failures += r.num_failures
for key in sorted(six.iterkeys(stats.entries)):
r = stats.entries[key]
console_logger.info(r)
console_logger.info("-" * (80 + STATS_NAME_WIDTH))

try:
fail_percent = (total_failures/float(total_reqs))*100
except ZeroDivisionError:
fail_percent = 0

console_logger.info((" %-" + str(STATS_NAME_WIDTH) + "s %7d %12s %42.2f %7.2f") % ('Aggregated', total_reqs, "%d(%.2f%%)" % (total_failures, fail_percent), total_rps, total_fail_per_sec))
console_logger.info(stats.total)
console_logger.info("")


def print_percentile_stats(stats):
console_logger.info("Percentage of the requests completed within given times")
console_logger.info((" %-" + str(STATS_NAME_WIDTH) + "s %8s %6s %6s %6s %6s %6s %6s %6s %6s %6s") % ('Name', '# reqs', '50%', '66%', '75%', '80%', '90%', '95%', '98%', '99%', '100%'))
console_logger.info("-" * (80 + STATS_NAME_WIDTH))
for key in sorted(six.iterkeys(stats)):
r = stats[key]
console_logger.info((" %-" + str(STATS_NAME_WIDTH) + "s %8s %6s %6s %6s %6s %6s %6s %6s %6s %6s %6s %6s") % (
'Name',
'# reqs',
'50%',
'66%',
'75%',
'80%',
'90%',
'95%',
'98%',
'99%',
'99.9%',
'99.99%',
'100%',
))
console_logger.info("-" * (90 + STATS_NAME_WIDTH))
for key in sorted(six.iterkeys(stats.entries)):
r = stats.entries[key]
if r.response_times:
console_logger.info(r.percentile())
console_logger.info("-" * (80 + STATS_NAME_WIDTH))
console_logger.info("-" * (90 + STATS_NAME_WIDTH))

total_stats = global_stats.total
if total_stats.response_times:
console_logger.info(total_stats.percentile())
if stats.total.response_times:
console_logger.info(stats.total.percentile())
console_logger.info("")

def print_error_report():
Expand All @@ -709,7 +709,7 @@ def print_error_report():
def stats_printer():
from . import runners
while True:
print_stats(runners.locust_runner.request_stats)
print_stats(runners.locust_runner.stats)
gevent.sleep(CONSOLE_STATS_INTERVAL_SEC)

def stats_writer(base_filepath):
Expand Down
20 changes: 18 additions & 2 deletions locust/test/test_stats.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@
import unittest
import re

import locust
from locust.core import HttpLocust, TaskSet, task
from locust.inspectlocust import get_task_ratio_dict
from locust.rpc.protocol import Message
from locust.stats import CachedResponseTimes, RequestStats, StatsEntry, diff_response_time_dicts, global_stats
from locust.test.testcases import LocustTestCase
from six.moves import xrange

from .testcases import WebserverTestCase
Expand Down Expand Up @@ -235,8 +237,22 @@ def test_serialize_through_message(self):
u1 = StatsEntry.unserialize(data)

self.assertEqual(20, u1.median_response_time)




class TestStatsPrinting(LocustTestCase):
def test_print_percentile_stats(self):
stats = RequestStats()
for i in range(100):
stats.log_request("", "test_entry", i, 2000+i)
locust.stats.print_percentile_stats(stats)
info = self.mocked_log.info
self.assertEqual(7, len(info))
# check that headline contains same number of column as the value rows
headlines = info[1].replace("# reqs", "#reqs").split()
self.assertEqual(len(headlines), len(info[3].split()))
self.assertEqual(len(headlines), len(info[5].split()))


class TestStatsEntryResponseTimesCache(unittest.TestCase):
def setUp(self, *args, **kwargs):
super(TestStatsEntryResponseTimesCache, self).setUp(*args, **kwargs)
Expand Down

0 comments on commit 313182b

Please sign in to comment.