Commit 642766ae authored by Vincent Pelletier's avatar Vincent Pelletier

Fill in missing points.

parent 15b9c556
...@@ -90,3 +90,11 @@ A log file with a site section to ignore. Order does not matter:: ...@@ -90,3 +90,11 @@ A log file with a site section to ignore. Order does not matter::
A mix of both above examples. Order matters !:: A mix of both above examples. Order matters !::
apachedex --skip-base /site1/ignored --base /site1 /site2 apachedex --skip-base /site1/ignored --base /site1 /site2
Notes
=====
When there are no hits for more than a graph period, placeholders are
generated for 0 hit (which is the reality) and 100% apdex (this is
arbitrary). Those placeholders only affect graphs, and do not affect
averages nor table content.
- use some templating system instead of hardcoded html strings - use some templating system instead of hardcoded html strings
- provide some form of raw data output, not just html - provide some form of raw data output, not just html
- allow user to specify min & max dates - allow user to specify min & max dates
- fill blanks in graphhistory with 0 hits & 100% apdex, and remove graph dots
- filter(out ?) by user agent - filter(out ?) by user agent
- automatically select period from log data ? - automatically select period from log data ?
...@@ -388,10 +388,41 @@ def _asHourString(timestamp): ...@@ -388,10 +388,41 @@ def _asHourString(timestamp):
day, month, year = date.split('/') day, month, year = date.split('/')
return '%s/%02i/%s %s' % (year, MONTH_VALUE_DICT[month], day, hour) return '%s/%02i/%s %s' % (year, MONTH_VALUE_DICT[month], day, hour)
# Key: argument (represents table granularity)
# Value:
# - cheap conversion from apache date format to graph granularity
# must be sortable consistently with time flow
# - conversion from gaph granularity to table granularity
# - graph granularity caption
# - format string to parse and generate graph granularity into/from
# datetime.datetime instance
# - period during which a placeholder point will be added if there is no data
# point
period_parser = { period_parser = {
'year': (_asMonthString, lambda x: x.split('/', 1)[0], 'month'), 'year': (
'month': (_asDayString, lambda x: '/'.join(x.split('/', 2)[:2]), 'day'), _asMonthString,
'day': (_asHourString, lambda x: x.split(' ')[0], 'hour'), lambda x: x.split('/', 1)[0],
'month',
'%Y/%m',
# Longest month: 31 days
timedelta(31),
),
'month': (
_asDayString,
lambda x: '/'.join(x.split('/', 2)[:2]),
'day',
'%Y/%m/%d',
# Longest day: 24 hours + 1h DST (never more ?)
timedelta(seconds=3600 * 25),
),
'day': (
_asHourString,
lambda x: x.split(' ')[0],
'hour',
'%Y/%m/%d %H',
# Longest hour: 60 * 60 seconds + 1 leap second.
timedelta(seconds=3601),
),
} }
def main(): def main():
...@@ -476,7 +507,8 @@ def main(): ...@@ -476,7 +507,8 @@ def main():
assert not key, key assert not key, key
matchline = re.compile(line_regex).match matchline = re.compile(line_regex).match
matchrequest = REQUEST_PATTERN.match matchrequest = REQUEST_PATTERN.match
asDate, decimator, graph_period = period_parser[args.period] asDate, decimator, graph_period, date_format, placeholder_delta = \
period_parser[args.period]
site_list = args.path site_list = args.path
default_site = args.default default_site = args.default
if default_site is None: if default_site is None:
...@@ -607,8 +639,19 @@ def main(): ...@@ -607,8 +639,19 @@ def main():
for site_id, data in per_site.iteritems(): for site_id, data in per_site.iteritems():
out.write('<h1>Site: %s</h1>' % site_id) out.write('<h1>Site: %s</h1>' % site_id)
daily_data = data.getApdexData() daily_data = data.getApdexData()
date_list = [int(time.mktime(time.strptime(x[0], '%Y/%m/%d' + { current_date = datetime.strptime(daily_data[0][0], date_format)
'day': ' %H'}.get(args.period, ''))) * 1000) for x in daily_data] new_daily_data = []
append = new_daily_data.append
for measure in daily_data:
measure_date = datetime.strptime(measure[0], date_format)
while current_date < measure_date:
append((current_date.strftime(date_format), 100, 0))
current_date += placeholder_delta
append(measure)
current_date = measure_date + placeholder_delta
daily_data = new_daily_data
date_list = [int(time.mktime(time.strptime(x[0], date_format)) * 1000)
for x in daily_data]
timeformat = '%Y<br/>%m/%d<br/>%H:%M' timeformat = '%Y<br/>%m/%d<br/>%H:%M'
# There is room for about 10 labels on the X axis. # There is room for about 10 labels on the X axis.
minTickSize = (max(1, minTickSize = (max(1,
...@@ -630,7 +673,6 @@ def main(): ...@@ -630,7 +673,6 @@ def main():
'labelWidth': yLabelWidth, 'labelWidth': yLabelWidth,
}, },
'lines': {'show': True}, 'lines': {'show': True},
'points': {'show': True},
}, },
) )
graph('Hits (per %s)' % graph_period, graph('Hits (per %s)' % graph_period,
...@@ -647,7 +689,6 @@ def main(): ...@@ -647,7 +689,6 @@ def main():
'tickDecimals': 0, 'tickDecimals': 0,
}, },
'lines': {'show': True}, 'lines': {'show': True},
'points': {'show': True},
}, },
) )
out.write(data.asHTML(decimator)) out.write(data.asHTML(decimator))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment