Commit 57731c74 authored by Vincent Pelletier's avatar Vincent Pelletier

Make user agent section optional.

parent 35aaa2c9
...@@ -361,7 +361,8 @@ _APDEXDateDictAsJSONState = lambda date_dict: dict(((y, z.asJSONState()) ...@@ -361,7 +361,8 @@ _APDEXDateDictAsJSONState = lambda date_dict: dict(((y, z.asJSONState())
for y, z in date_dict.iteritems())) for y, z in date_dict.iteritems()))
class GenericSiteStats(object): class GenericSiteStats(object):
def __init__(self, threshold, getDuration, suffix, error_detail=False): def __init__(self, threshold, getDuration, suffix, error_detail=False,
user_agent_detail=False):
self.threshold = threshold self.threshold = threshold
self.suffix = suffix self.suffix = suffix
self.error_detail = error_detail self.error_detail = error_detail
...@@ -371,6 +372,7 @@ class GenericSiteStats(object): ...@@ -371,6 +372,7 @@ class GenericSiteStats(object):
self.error_url_count = defaultdict(partial(defaultdict, Counter)) self.error_url_count = defaultdict(partial(defaultdict, Counter))
self.url_apdex = defaultdict(partial(APDEXStats, threshold, getDuration)) self.url_apdex = defaultdict(partial(APDEXStats, threshold, getDuration))
self.apdex = defaultdict(partial(APDEXStats, threshold, getDuration)) self.apdex = defaultdict(partial(APDEXStats, threshold, getDuration))
self.user_agent_detail = user_agent_detail
self.user_agent_counter = Counter() self.user_agent_counter = Counter()
def rescale(self, convert, getDuration): def rescale(self, convert, getDuration):
...@@ -397,7 +399,8 @@ class GenericSiteStats(object): ...@@ -397,7 +399,8 @@ class GenericSiteStats(object):
if self.error_detail and statusIsError(status): if self.error_detail and statusIsError(status):
# XXX: can eat memory if there are many errors on many different urls # XXX: can eat memory if there are many errors on many different urls
self.error_url_count[status][url][match.group('referer')] += 1 self.error_url_count[status][url][match.group('referer')] += 1
self.user_agent_counter[match.group('agent')] += 1 if self.user_agent_detail:
self.user_agent_counter[match.group('agent')] += 1
def getApdexData(self): def getApdexData(self):
return getDataPoints(self.apdex, self.status) return getDataPoints(self.apdex, self.status)
...@@ -426,12 +429,13 @@ class GenericSiteStats(object): ...@@ -426,12 +429,13 @@ class GenericSiteStats(object):
append(data.asHTML(self.threshold)) append(data.asHTML(self.threshold))
append('<td class="text">%s</td></tr>' % unquoteToHtml(url)) append('<td class="text">%s</td></tr>' % unquoteToHtml(url))
append('</table>') append('</table>')
append('<h2>User agents</h2><table class="stats"><tr><th>hits</th>' if self.user_agent_detail:
'<th>user agent</th></tr>') append('<h2>User agents</h2><table class="stats"><tr><th>hits</th>'
for user_agent, hit in self.user_agent_counter.most_common(N_USER_AGENT): '<th>user agent</th></tr>')
# XXX: s/escape/unquoteToHtml/ ? for user_agent, hit in self.user_agent_counter.most_common(N_USER_AGENT):
append('<tr><td>%s</td><td class="text">%s</td></tr>' % (hit, escape(user_agent))) # XXX: s/escape/unquoteToHtml/ ?
append('</table>') append('<tr><td>%s</td><td class="text">%s</td></tr>' % (hit, escape(user_agent)))
append('</table>')
column_set = set() column_set = set()
filtered_status = defaultdict(partial(defaultdict, int)) filtered_status = defaultdict(partial(defaultdict, int))
for status, date_dict in self.status.iteritems(): for status, date_dict in self.status.iteritems():
...@@ -498,7 +502,8 @@ class GenericSiteStats(object): ...@@ -498,7 +502,8 @@ class GenericSiteStats(object):
@classmethod @classmethod
def fromJSONState(cls, state, getDuration, suffix): def fromJSONState(cls, state, getDuration, suffix):
error_detail = state['error_detail'] error_detail = state['error_detail']
result = cls(state['threshold'], getDuration, suffix, error_detail) result = cls(state['threshold'], getDuration, suffix, error_detail,
state.get('user_agent_detail', True))
if error_detail: if error_detail:
error_url_count = result.error_url_count error_url_count = result.error_url_count
for state_status, state_url_dict in state['error_url_count'].iteritems(): for state_status, state_url_dict in state['error_url_count'].iteritems():
...@@ -524,10 +529,12 @@ class GenericSiteStats(object): ...@@ -524,10 +529,12 @@ class GenericSiteStats(object):
'apdex': _APDEXDateDictAsJSONState(self.apdex), 'apdex': _APDEXDateDictAsJSONState(self.apdex),
'status': self.status, 'status': self.status,
'user_agent_counter': self.user_agent_counter, 'user_agent_counter': self.user_agent_counter,
'user_agent_detail': self.user_agent_detail,
} }
def accumulateFrom(self, other): def accumulateFrom(self, other):
# XXX: ignoring: threshold, getDuration, suffix, error_detail. # XXX: ignoring: threshold, getDuration, suffix, error_detail,
# user_agent_detail.
# Assuming they are consistently set. # Assuming they are consistently set.
if self.error_detail: if self.error_detail:
for status, other_url_dict in other.error_url_count.iteritems(): for status, other_url_dict in other.error_url_count.iteritems():
...@@ -554,9 +561,10 @@ class ERP5SiteStats(GenericSiteStats): ...@@ -554,9 +561,10 @@ class ERP5SiteStats(GenericSiteStats):
- If a line belongs to a module and has at least 2 slashes after module, - If a line belongs to a module and has at least 2 slashes after module,
count line as belonging to a document of that module count line as belonging to a document of that module
""" """
def __init__(self, threshold, getDuration, suffix, error_detail=False): def __init__(self, threshold, getDuration, suffix, error_detail=False,
user_agent_detail=False):
super(ERP5SiteStats, self).__init__(threshold, getDuration, suffix, super(ERP5SiteStats, self).__init__(threshold, getDuration, suffix,
error_detail=error_detail) error_detail=error_detail, user_agent_detail=user_agent_detail)
# Key levels: # Key levels:
# - module id (string) # - module id (string)
# - is document (bool) # - is document (bool)
...@@ -1188,6 +1196,9 @@ def main(): ...@@ -1188,6 +1196,9 @@ def main():
'Default: %(default).2fs') 'Default: %(default).2fs')
group.add_argument('-e', '--error-detail', action='store_true', group.add_argument('-e', '--error-detail', action='store_true',
help='Include detailed report (url & referers) for error statuses.') help='Include detailed report (url & referers) for error statuses.')
group.add_argument('-u', '--user-agent-detail', action='store_true',
help='Include report of most frequent user agents.')
group.add_argument('-f', '--format', choices=format_generator, group.add_argument('-f', '--format', choices=format_generator,
default='html', help='Format in which output should be generated.') default='html', help='Format in which output should be generated.')
group.add_argument('-p', '--period', choices=period_parser, group.add_argument('-p', '--period', choices=period_parser,
...@@ -1307,6 +1318,7 @@ def main(): ...@@ -1307,6 +1318,7 @@ def main():
quiet = args.quiet quiet = args.quiet
threshold = args.apdex threshold = args.apdex
error_detail = args.error_detail error_detail = args.error_detail
user_agent_detail = args.user_agent_detail
file_count = len(infile_list) file_count = len(infile_list)
per_site = {} per_site = {}
if '-' in args.state_file and '-' in infile_list: if '-' in args.state_file and '-' in infile_list:
...@@ -1437,7 +1449,7 @@ def main(): ...@@ -1437,7 +1449,7 @@ def main():
site_data = per_site[site] site_data = per_site[site]
except KeyError: except KeyError:
site_data = per_site[site] = action(threshold, getDuration, site_data = per_site[site] = action(threshold, getDuration,
error_detail=error_detail) error_detail=error_detail, user_agent_detail=user_agent_detail)
try: try:
site_data.accumulate(match, url_match, hit_date) site_data.accumulate(match, url_match, hit_date)
except Exception: except Exception:
......
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