diff options
| author | Alexandre Flament <alex@al-f.net> | 2021-04-14 17:23:15 +0200 |
|---|---|---|
| committer | Alexandre Flament <alex@al-f.net> | 2021-04-21 16:24:46 +0200 |
| commit | 7acd7ffc02d14d175ec2a99ba984e47d8cb65d7d (patch) | |
| tree | 000b6e4b0038ed627bb114f8a2de83681bbf7ad4 /searx/webapp.py | |
| parent | aae7830d14242ac1f98232f428654c5d2c9c5eb2 (diff) | |
[enh] rewrite and enhance metrics
Diffstat (limited to 'searx/webapp.py')
| -rwxr-xr-x | searx/webapp.py | 77 |
1 files changed, 28 insertions, 49 deletions
diff --git a/searx/webapp.py b/searx/webapp.py index e248b9d27..245f00a34 100755 --- a/searx/webapp.py +++ b/searx/webapp.py @@ -51,7 +51,7 @@ from searx import logger logger = logger.getChild('webapp') from datetime import datetime, timedelta -from time import time +from timeit import default_timer from html import escape from io import StringIO from urllib.parse import urlencode, urlparse @@ -73,9 +73,7 @@ from flask.json import jsonify from searx import brand, static_path from searx import settings, searx_dir, searx_debug from searx.exceptions import SearxParameterException -from searx.engines import ( - categories, engines, engine_shortcuts, get_engines_stats -) +from searx.engines import categories, engines, engine_shortcuts from searx.webutils import ( UnicodeWriter, highlight_content, get_resources_directory, get_static_files, get_result_templates, get_themes, @@ -95,7 +93,7 @@ from searx.preferences import Preferences, ValidationException, LANGUAGE_CODES from searx.answerers import answerers from searx.network import stream as http_stream from searx.answerers import ask -from searx.metrology.error_recorder import errors_per_engines +from searx.metrics import get_engines_stats, get_engine_errors, histogram # serve pages with HTTP/1.1 from werkzeug.serving import WSGIRequestHandler @@ -463,7 +461,7 @@ def _get_ordered_categories(): @app.before_request def pre_request(): - request.start_time = time() + request.start_time = default_timer() request.timings = [] request.errors = [] @@ -521,7 +519,7 @@ def add_default_headers(response): @app.after_request def post_request(response): - total_time = time() - request.start_time + total_time = default_timer() - request.start_time timings_all = ['total;dur=' + str(round(total_time * 1000, 3))] if len(request.timings) > 0: timings = sorted(request.timings, key=lambda v: v['total']) @@ -852,29 +850,25 @@ def preferences(): allowed_plugins = request.preferences.plugins.get_enabled() # stats for preferences page - stats = {} + filtered_engines = dict(filter(lambda kv: (kv[0], request.preferences.validate_token(kv[1])), engines.items())) engines_by_category = {} for c in categories: - engines_by_category[c] = [] - for e in categories[c]: - if not request.preferences.validate_token(e): - continue - - stats[e.name] = {'time': None, - 'warn_timeout': False, - 'warn_time': False} - if e.timeout > settings['outgoing']['request_timeout']: - stats[e.name]['warn_timeout'] = True - stats[e.name]['supports_selected_language'] = _is_selected_language_supported(e, request.preferences) - engines_by_category[c].append(e) + engines_by_category[c] = [e for e in categories[c] if e.name in filtered_engines] # get first element [0], the engine time, # and then the second element [1] : the time (the first one is the label) - for engine_stat in get_engines_stats(request.preferences)[0][1]: - stats[engine_stat.get('name')]['time'] = round(engine_stat.get('avg'), 3) - if engine_stat.get('avg') > settings['outgoing']['request_timeout']: - stats[engine_stat.get('name')]['warn_time'] = True + stats = {} + for _, e in filtered_engines.items(): + h = histogram('engine', e.name, 'time', 'total') + median = round(h.percentage(50), 1) if h.count > 0 else None + + stats[e.name] = { + 'time': median if median else None, + 'warn_time': median is not None and median > settings['outgoing']['request_timeout'], + 'warn_timeout': e.timeout > settings['outgoing']['request_timeout'], + 'supports_selected_language': _is_selected_language_supported(e, request.preferences) + } # end of stats locked_preferences = list() @@ -976,38 +970,23 @@ def image_proxy(): @app.route('/stats', methods=['GET']) def stats(): """Render engine statistics page.""" - stats = get_engines_stats(request.preferences) + filtered_engines = dict(filter(lambda kv: (kv[0], request.preferences.validate_token(kv[1])), engines.items())) + engine_stats = get_engines_stats(filtered_engines) return render( 'stats.html', - stats=stats, + stats=[(gettext('Engine time (sec)'), engine_stats['time_total']), + (gettext('Page loads (sec)'), engine_stats['time_http']), + (gettext('Number of results'), engine_stats['result_count']), + (gettext('Scores'), engine_stats['scores']), + (gettext('Scores per result'), engine_stats['scores_per_result']), + (gettext('Errors'), engine_stats['error_count'])] ) @app.route('/stats/errors', methods=['GET']) def stats_errors(): - result = {} - engine_names = list(errors_per_engines.keys()) - engine_names.sort() - for engine_name in engine_names: - error_stats = errors_per_engines[engine_name] - sent_search_count = max(engines[engine_name].stats['sent_search_count'], 1) - sorted_context_count_list = sorted(error_stats.items(), key=lambda context_count: context_count[1]) - r = [] - percentage_sum = 0 - for context, count in sorted_context_count_list: - percentage = round(20 * count / sent_search_count) * 5 - percentage_sum += percentage - r.append({ - 'filename': context.filename, - 'function': context.function, - 'line_no': context.line_no, - 'code': context.code, - 'exception_classname': context.exception_classname, - 'log_message': context.log_message, - 'log_parameters': context.log_parameters, - 'percentage': percentage, - }) - result[engine_name] = sorted(r, reverse=True, key=lambda d: d['percentage']) + filtered_engines = dict(filter(lambda kv: (kv[0], request.preferences.validate_token(kv[1])), engines.items())) + result = get_engine_errors(filtered_engines) return jsonify(result) |