summaryrefslogtreecommitdiff
path: root/searx/webapp.py
diff options
context:
space:
mode:
authorAlexandre Flament <alex@al-f.net>2021-04-14 17:23:15 +0200
committerAlexandre Flament <alex@al-f.net>2021-04-21 16:24:46 +0200
commit7acd7ffc02d14d175ec2a99ba984e47d8cb65d7d (patch)
tree000b6e4b0038ed627bb114f8a2de83681bbf7ad4 /searx/webapp.py
parentaae7830d14242ac1f98232f428654c5d2c9c5eb2 (diff)
[enh] rewrite and enhance metrics
Diffstat (limited to 'searx/webapp.py')
-rwxr-xr-xsearx/webapp.py77
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)