Skip to content

Commit

Permalink
Merge ca13b48 into ad76cf9
Browse files Browse the repository at this point in the history
  • Loading branch information
valleedelisle committed Nov 29, 2019
2 parents ad76cf9 + ca13b48 commit d4de909
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 40 deletions.
3 changes: 3 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ CHANGES
- Add `--json` output command line option.
[valleedelisle]

- Add `cmd_requests_per_hour`
[valleedelisle]

3.0.0 (2019-06-10)
------------------

Expand Down
6 changes: 5 additions & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,11 @@ See the ``--help`` (or the section above) to know how to run them.
``requests_per_minute``
Reports on how many requests were made per minute.
It works best when used with ``-s`` and ``-d`` command line arguments,
as the output can be huge.
as the output can be huge. We can also use ``requests_per_hour``
if it's too much data.

``requests_per_hour``
Reports on how many requests were made per hour.

``print``
Prints the raw lines.
Expand Down
69 changes: 36 additions & 33 deletions haproxy/logfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from datetime import timedelta
from haproxy.line import Line

import datetime
import os


Expand Down Expand Up @@ -336,48 +337,50 @@ def cmd_requests_per_minute(self):
.. note::
Try to combine it with time constrains (``-s`` and ``-d``) as this
command output can be huge otherwise.
command output can be huge otherwise. We can also use
``requests_per_hour`` if it's too much data.
"""
if len(self._valid_lines) == 0:
return

current_minute = self._valid_lines[0].accept_date
current_minute_counter = 0
requests = []
one_minute = timedelta(minutes=1)

def format_and_append(append_to, date, counter):
seconds_and_micro = timedelta(
seconds=date.second, microseconds=date.microsecond
)
minute_formatted = date - seconds_and_micro
append_to.append((minute_formatted, counter))

# note that _valid_lines is kept sorted by date
for line in self._valid_lines:
line_date = line.accept_date
if (
line_date - current_minute < one_minute
and line_date.minute == current_minute.minute
):
current_minute_counter += 1

else:
format_and_append(requests, current_minute, current_minute_counter)
current_minute_counter = 1
current_minute = line_date

if current_minute_counter > 0:
format_and_append(requests, current_minute, current_minute_counter)
return self._count_by_time(1)

return requests
def cmd_requests_per_hour(self):
"""Generates statistics on how many requests were made per hour.
"""
return self._count_by_time(60)

def cmd_print(self):
"""Returns the raw lines to be printed."""
if not self._valid_lines:
return ''
return '\n'.join([line.raw_line for line in self._valid_lines]) + '\n'

def _count_by_time(self, aggregate):
"""
Helper function to compile stats by time frame.
Used by requests_per_minute and requests_per_hour
params:
aggregate: Number of minutes to aggregate on
"""
if len(self._valid_lines) == 0:
return

requests = {}

# note that _valid_lines is kept sorted by date
for line in self._valid_lines:
tm = line.accept_date
tm += datetime.timedelta(minutes=aggregate / 2)
tm -= datetime.timedelta(
minutes=tm.minute % aggregate,
seconds=tm.second,
microseconds=tm.microsecond,
)
try:
requests[str(tm)] += 1
except KeyError:
requests[str(tm)] = 1

return sorted(requests)

def _sort_lines(self):
"""Haproxy writes its logs after having gathered all information
related to each specific connection. A simple request can be
Expand Down
21 changes: 15 additions & 6 deletions haproxy/tests/test_log_file.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
# -*- coding: utf-8 -*-
from datetime import datetime
from haproxy import filters
from haproxy.logfile import Log
from haproxy.main import main
Expand Down Expand Up @@ -269,11 +268,21 @@ def test_cmd_requests_per_minute(self):

self.assertEqual(len(requests), 5)

self.assertEqual(requests[0], (datetime(2013, 12, 11, 11, 2), 8))
self.assertEqual(requests[1], (datetime(2013, 12, 11, 11, 3), 3))
self.assertEqual(requests[2], (datetime(2013, 12, 11, 11, 13), 5))
self.assertEqual(requests[3], (datetime(2013, 12, 11, 11, 52), 7))
self.assertEqual(requests[4], (datetime(2013, 12, 11, 12, 2), 9))
self.assertEqual(requests[0], '2013-12-11 11:02:00')
self.assertEqual(requests[1], '2013-12-11 11:03:00')
self.assertEqual(requests[2], '2013-12-11 11:13:00')
self.assertEqual(requests[3], '2013-12-11 11:52:00')
self.assertEqual(requests[4], '2013-12-11 12:02:00')

def test_cmd_requests_per_hour(self):
"""Check that the requests per minute command reports as expected."""
log_file = Log(logfile='haproxy/tests/files/requests_per_minute.log')
requests = log_file.cmd_requests_per_hour()

self.assertEqual(len(requests), 2)

self.assertEqual(requests[0], '2013-12-11 11:00:00')
self.assertEqual(requests[1], '2013-12-11 12:00:00')

def test_cmd_requests_per_minute_empty(self):
"""Check that the requests per minute command reports nothing if
Expand Down

0 comments on commit d4de909

Please sign in to comment.