forked from zaclys/searxng
Merge pull request #85 from searxng/fix-metrics-offline-engine
Fix metrics offline engine
This commit is contained in:
commit
2398e9a1fe
|
@ -156,57 +156,76 @@ def get_reliabilities(engline_name_list, checker_results):
|
||||||
return reliabilities
|
return reliabilities
|
||||||
|
|
||||||
|
|
||||||
def round_or_none(number, digits):
|
|
||||||
return round(number, digits) if number else number
|
|
||||||
|
|
||||||
|
|
||||||
def get_engines_stats(engine_name_list):
|
def get_engines_stats(engine_name_list):
|
||||||
assert counter_storage is not None
|
assert counter_storage is not None
|
||||||
assert histogram_storage is not None
|
assert histogram_storage is not None
|
||||||
|
|
||||||
list_time = []
|
list_time = []
|
||||||
|
max_time_total = max_result_count = None
|
||||||
|
|
||||||
max_time_total = max_result_count = None # noqa
|
|
||||||
for engine_name in engine_name_list:
|
for engine_name in engine_name_list:
|
||||||
|
|
||||||
sent_count = counter('engine', engine_name, 'search', 'count', 'sent')
|
sent_count = counter('engine', engine_name, 'search', 'count', 'sent')
|
||||||
if sent_count == 0:
|
if sent_count == 0:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
result_count = histogram('engine', engine_name, 'result', 'count').percentage(50)
|
||||||
|
result_count_sum = histogram('engine', engine_name, 'result', 'count').sum
|
||||||
successful_count = counter('engine', engine_name, 'search', 'count', 'successful')
|
successful_count = counter('engine', engine_name, 'search', 'count', 'successful')
|
||||||
|
|
||||||
time_total = histogram('engine', engine_name, 'time', 'total').percentage(50)
|
time_total = histogram('engine', engine_name, 'time', 'total').percentage(50)
|
||||||
time_http = histogram('engine', engine_name, 'time', 'http').percentage(50)
|
|
||||||
time_total_p80 = histogram('engine', engine_name, 'time', 'total').percentage(80)
|
|
||||||
time_http_p80 = histogram('engine', engine_name, 'time', 'http').percentage(80)
|
|
||||||
time_total_p95 = histogram('engine', engine_name, 'time', 'total').percentage(95)
|
|
||||||
time_http_p95 = histogram('engine', engine_name, 'time', 'http').percentage(95)
|
|
||||||
|
|
||||||
result_count = histogram('engine', engine_name, 'result', 'count').percentage(50)
|
|
||||||
result_count_sum = histogram('engine', engine_name, 'result', 'count').sum
|
|
||||||
if successful_count and result_count_sum:
|
|
||||||
score = counter('engine', engine_name, 'score') # noqa
|
|
||||||
score_per_result = score / float(result_count_sum)
|
|
||||||
else:
|
|
||||||
score = score_per_result = 0.0
|
|
||||||
|
|
||||||
max_time_total = max(time_total or 0, max_time_total or 0)
|
max_time_total = max(time_total or 0, max_time_total or 0)
|
||||||
max_result_count = max(result_count or 0, max_result_count or 0)
|
max_result_count = max(result_count or 0, max_result_count or 0)
|
||||||
|
|
||||||
list_time.append({
|
stats = {
|
||||||
'name': engine_name,
|
'name': engine_name,
|
||||||
'total': round_or_none(time_total, 1),
|
'total': None,
|
||||||
'total_p80': round_or_none(time_total_p80, 1),
|
'total_p80': None,
|
||||||
'total_p95': round_or_none(time_total_p95, 1),
|
'total_p95': None,
|
||||||
'http': round_or_none(time_http, 1),
|
'http': None,
|
||||||
'http_p80': round_or_none(time_http_p80, 1),
|
'http_p80': None,
|
||||||
'http_p95': round_or_none(time_http_p95, 1),
|
'http_p95': None,
|
||||||
'processing': round(time_total - time_http, 1) if time_total else None,
|
'processing': None,
|
||||||
'processing_p80': round(time_total_p80 - time_http_p80, 1) if time_total else None,
|
'processing_p80': None,
|
||||||
'processing_p95': round(time_total_p95 - time_http_p95, 1) if time_total else None,
|
'processing_p95': None,
|
||||||
'score': score,
|
'score': 0,
|
||||||
'score_per_result': score_per_result,
|
'score_per_result': 0,
|
||||||
'result_count': result_count,
|
'result_count': result_count,
|
||||||
})
|
}
|
||||||
|
|
||||||
|
if successful_count and result_count_sum:
|
||||||
|
score = counter('engine', engine_name, 'score')
|
||||||
|
|
||||||
|
stats['score'] = score
|
||||||
|
stats['score_per_result'] = score / float(result_count_sum)
|
||||||
|
|
||||||
|
time_http = histogram('engine', engine_name, 'time', 'http').percentage(50)
|
||||||
|
time_http_p80 = time_http_p95 = 0
|
||||||
|
|
||||||
|
if time_http is not None:
|
||||||
|
|
||||||
|
time_http_p80 = histogram('engine', engine_name, 'time', 'http').percentage(80)
|
||||||
|
time_http_p95 = histogram('engine', engine_name, 'time', 'http').percentage(95)
|
||||||
|
|
||||||
|
stats['http'] = round(time_http, 1)
|
||||||
|
stats['http_p80'] = round(time_http_p80, 1)
|
||||||
|
stats['http_p95'] = round(time_http_p95, 1)
|
||||||
|
|
||||||
|
if time_total is not None:
|
||||||
|
|
||||||
|
time_total_p80 = histogram('engine', engine_name, 'time', 'total').percentage(80)
|
||||||
|
time_total_p95 = histogram('engine', engine_name, 'time', 'total').percentage(95)
|
||||||
|
|
||||||
|
stats['total'] = round(time_total, 1)
|
||||||
|
stats['total_p80'] = round(time_total_p80, 1)
|
||||||
|
stats['total_p95'] = round(time_total_p95, 1)
|
||||||
|
|
||||||
|
stats['processing'] = round(time_total - (time_http or 0), 1)
|
||||||
|
stats['processing_p80'] = round(time_total_p80 - time_http_p80, 1)
|
||||||
|
stats['processing_p95'] = round(time_total_p95 - time_http_p95, 1)
|
||||||
|
|
||||||
|
list_time.append(stats)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'time': list_time,
|
'time': list_time,
|
||||||
'max_time': math.ceil(max_time_total or 0),
|
'max_time': math.ceil(max_time_total or 0),
|
||||||
|
|
|
@ -44,7 +44,8 @@ def reset_time_for_thread():
|
||||||
|
|
||||||
|
|
||||||
def get_time_for_thread():
|
def get_time_for_thread():
|
||||||
return THREADLOCAL.total_time
|
"""returns thread's total time or None"""
|
||||||
|
return THREADLOCAL.__dict__.get('total_time')
|
||||||
|
|
||||||
|
|
||||||
def set_timeout_for_thread(timeout, start_time=None):
|
def set_timeout_for_thread(timeout, start_time=None):
|
||||||
|
@ -57,10 +58,11 @@ def set_context_network_name(network_name):
|
||||||
|
|
||||||
|
|
||||||
def get_context_network():
|
def get_context_network():
|
||||||
try:
|
"""If set return thread's network.
|
||||||
return THREADLOCAL.network
|
|
||||||
except AttributeError:
|
If unset, return value from :py:obj:`get_network`.
|
||||||
return get_network()
|
"""
|
||||||
|
return THREADLOCAL.__dict__.get('network') or get_network()
|
||||||
|
|
||||||
|
|
||||||
def request(method, url, **kwargs):
|
def request(method, url, **kwargs):
|
||||||
|
|
|
@ -371,11 +371,12 @@ class ResultContainer:
|
||||||
self.unresponsive_engines.add((engine_name, error_type, error_message, suspended))
|
self.unresponsive_engines.add((engine_name, error_type, error_message, suspended))
|
||||||
|
|
||||||
def add_timing(self, engine_name, engine_time, page_load_time):
|
def add_timing(self, engine_name, engine_time, page_load_time):
|
||||||
self.timings.append({
|
timing = {
|
||||||
'engine': engines[engine_name].shortcut,
|
'engine': engines[engine_name].shortcut,
|
||||||
'total': engine_time,
|
'total': engine_time,
|
||||||
'load': page_load_time
|
'load': page_load_time,
|
||||||
})
|
}
|
||||||
|
self.timings.append(timing)
|
||||||
|
|
||||||
def get_timings(self):
|
def get_timings(self):
|
||||||
return self.timings
|
return self.timings
|
||||||
|
|
|
@ -25,11 +25,13 @@
|
||||||
<td class="{{ label }}" style="padding: 2px">{{- "" -}}
|
<td class="{{ label }}" style="padding: 2px">{{- "" -}}
|
||||||
{%- if stats[engine_name].time != None -%}
|
{%- if stats[engine_name].time != None -%}
|
||||||
<span class="stacked-bar-chart-value">{{- stats[engine_name].time -}}</span>{{- "" -}}
|
<span class="stacked-bar-chart-value">{{- stats[engine_name].time -}}</span>{{- "" -}}
|
||||||
<span class="stacked-bar-chart" aria-labelledby="{{engine_name}}_chart" aria-hidden="true">{{- "" -}}
|
<span class="stacked-bar-chart" aria-labelledby="{{engine_name}}_chart" aria-hidden="true">
|
||||||
|
{%- if max_rate95 is not none and max_rate95 > 0 -%}
|
||||||
<span style="width: calc(max(2px, 100%*{{ (stats[engine_name].time / max_rate95)|round(3) }}))" class="stacked-bar-chart-median"></span>{{- "" -}}
|
<span style="width: calc(max(2px, 100%*{{ (stats[engine_name].time / max_rate95)|round(3) }}))" class="stacked-bar-chart-median"></span>{{- "" -}}
|
||||||
<span style="width: calc(100%*{{ ((stats[engine_name].rate80 - stats[engine_name].time) / max_rate95)|round(3) }})" class="stacked-bar-chart-rate80"></span>{{- "" -}}
|
<span style="width: calc(100%*{{ ((stats[engine_name].rate80 - stats[engine_name].time) / max_rate95)|round(3) }})" class="stacked-bar-chart-rate80"></span>{{- "" -}}
|
||||||
<span style="width: calc(100%*{{ ((stats[engine_name].rate95 - stats[engine_name].rate80) / max_rate95)|round(3) }})" class="stacked-bar-chart-rate95"></span>{{- "" -}}
|
<span style="width: calc(100%*{{ ((stats[engine_name].rate95 - stats[engine_name].rate80) / max_rate95)|round(3) }})" class="stacked-bar-chart-rate95"></span>{{- "" -}}
|
||||||
<span class="stacked-bar-chart-rate100"></span>{{- "" -}}
|
<span class="stacked-bar-chart-rate100"></span>
|
||||||
|
{%- endif -%}
|
||||||
</span>{{- "" -}}
|
</span>{{- "" -}}
|
||||||
<div class="engine-tooltip text-left" role="tooltip" id="{{engine_name}}_graph">{{- "" -}}
|
<div class="engine-tooltip text-left" role="tooltip" id="{{engine_name}}_graph">{{- "" -}}
|
||||||
<p>{{ _('Median') }}: {{ stats[engine_name].time }}</p>{{- "" -}}
|
<p>{{ _('Median') }}: {{ stats[engine_name].time }}</p>{{- "" -}}
|
||||||
|
|
|
@ -52,11 +52,11 @@
|
||||||
{%- endif -%}
|
{%- endif -%}
|
||||||
</td>
|
</td>
|
||||||
<td class="response-time">
|
<td class="response-time">
|
||||||
{%- if engine_stat.total -%}
|
{%- if engine_stat.total is not none -%}
|
||||||
<div class="bar-chart-value">{{- engine_stat.total | round(1) -}}</div>{{- "" -}}
|
<div class="bar-chart-value">{{- engine_stat.total | round(1) -}}</div>{{- "" -}}
|
||||||
<div class="bar-chart-graph" aria-labelledby="{{engine_stat.name}}_time" aria-hidden="true">{{- "" -}}
|
<div class="bar-chart-graph" aria-labelledby="{{engine_stat.name}}_time" aria-hidden="true">{{- "" -}}
|
||||||
<div class="bar-chart-serie1 bar{{ (100 * engine_stat.http / engine_stats.max_time)|round }}"></div>{{- "" -}}
|
{% if engine_stat.http is not none and engine_stats.max_time %}<div class="bar-chart-serie1 bar{{ (100 * engine_stat.http / engine_stats.max_time)|round }}"></div>{%- endif -%}
|
||||||
<div class="bar-chart-serie2 bar{{ (100 * engine_stat.processing / engine_stats.max_time)|round }}"></div>{{- "" -}}
|
{% if engine_stat.processing is not none and engine_stats.max_time %}<div class="bar-chart-serie2 bar{{ (100 * engine_stat.processing / engine_stats.max_time)|round }}"></div>{%- endif -%}
|
||||||
</div>
|
</div>
|
||||||
<div class="engine-tooltip text-left" role="tooltip" id="{{engine_stat.name}}_time">{{- "" -}}
|
<div class="engine-tooltip text-left" role="tooltip" id="{{engine_stat.name}}_time">{{- "" -}}
|
||||||
<table class="table table-striped">
|
<table class="table table-striped">
|
||||||
|
@ -69,19 +69,19 @@
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="col">{{ _('Median') }}</th>
|
<th scope="col">{{ _('Median') }}</th>
|
||||||
<td>{{ engine_stat.total }}</td>
|
<td>{{ engine_stat.total }}</td>
|
||||||
<td>{{ engine_stat.http }}</td>
|
<td>{{ engine_stat.http or '' }}</td>
|
||||||
<td>{{ engine_stat.processing }}</td>
|
<td>{{ engine_stat.processing }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="col">{{ _('P80') }}</th>
|
<th scope="col">{{ _('P80') }}</th>
|
||||||
<td>{{ engine_stat.total_p80 }}</td>
|
<td>{{ engine_stat.total_p80 }}</td>
|
||||||
<td>{{ engine_stat.http_p80 }}</td>
|
<td>{{ engine_stat.http_p80 or '' }}</td>
|
||||||
<td>{{ engine_stat.processing_p80 }}</td>
|
<td>{{ engine_stat.processing_p80 }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="col">{{ _('P95') }}</th>
|
<th scope="col">{{ _('P95') }}</th>
|
||||||
<td>{{ engine_stat.total_p95 }}</td>
|
<td>{{ engine_stat.total_p95 }}</td>
|
||||||
<td>{{ engine_stat.http_p95 }}</td>
|
<td>{{ engine_stat.http_p95 or '' }}</td>
|
||||||
<td>{{ engine_stat.processing_p95 }}</td>
|
<td>{{ engine_stat.processing_p95 }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
|
@ -39,11 +39,13 @@
|
||||||
<td class="{{ label }}" style="padding: 2px; width: 13rem;">{{- "" -}}
|
<td class="{{ label }}" style="padding: 2px; width: 13rem;">{{- "" -}}
|
||||||
{%- if stats[engine_name].time != None -%}
|
{%- if stats[engine_name].time != None -%}
|
||||||
<span class="stacked-bar-chart-value">{{- stats[engine_name].time -}}</span>{{- "" -}}
|
<span class="stacked-bar-chart-value">{{- stats[engine_name].time -}}</span>{{- "" -}}
|
||||||
<span class="stacked-bar-chart" aria-labelledby="{{engine_name}}_chart" aria-hidden="true">{{- "" -}}
|
<span class="stacked-bar-chart" aria-labelledby="{{engine_name}}_chart" aria-hidden="true">
|
||||||
|
{%- if max_rate95 is not none and max_rate95 > 0 -%}
|
||||||
<span style="width: calc(max(2px, 100%*{{ (stats[engine_name].time / max_rate95)|round(3) }}))" class="stacked-bar-chart-median"></span>{{- "" -}}
|
<span style="width: calc(max(2px, 100%*{{ (stats[engine_name].time / max_rate95)|round(3) }}))" class="stacked-bar-chart-median"></span>{{- "" -}}
|
||||||
<span style="width: calc(100%*{{ ((stats[engine_name].rate80 - stats[engine_name].time) / max_rate95)|round(3) }})" class="stacked-bar-chart-rate80"></span>{{- "" -}}
|
<span style="width: calc(100%*{{ ((stats[engine_name].rate80 - stats[engine_name].time) / max_rate95)|round(3) }})" class="stacked-bar-chart-rate80"></span>{{- "" -}}
|
||||||
<span style="width: calc(100%*{{ ((stats[engine_name].rate95 - stats[engine_name].rate80) / max_rate95)|round(3) }})" class="stacked-bar-chart-rate95"></span>{{- "" -}}
|
<span style="width: calc(100%*{{ ((stats[engine_name].rate95 - stats[engine_name].rate80) / max_rate95)|round(3) }})" class="stacked-bar-chart-rate95"></span>{{- "" -}}
|
||||||
<span class="stacked-bar-chart-rate100"></span>{{- "" -}}
|
<span class="stacked-bar-chart-rate100"></span>
|
||||||
|
{%- endif -%}
|
||||||
</span>{{- "" -}}
|
</span>{{- "" -}}
|
||||||
<div class="engine-tooltip text-left" role="tooltip" id="{{engine_name}}_graph">{{- "" -}}
|
<div class="engine-tooltip text-left" role="tooltip" id="{{engine_name}}_graph">{{- "" -}}
|
||||||
<p>{{ _('Median') }}: {{ stats[engine_name].time }}</p>{{- "" -}}
|
<p>{{ _('Median') }}: {{ stats[engine_name].time }}</p>{{- "" -}}
|
||||||
|
|
|
@ -52,12 +52,11 @@
|
||||||
{%- endif -%}
|
{%- endif -%}
|
||||||
</td>
|
</td>
|
||||||
<td class="response-time">
|
<td class="response-time">
|
||||||
{%- if engine_stat.total -%}
|
{%- if engine_stat.total is not none -%}
|
||||||
|
|
||||||
<div class="bar-chart-value">{{- engine_stat.total | round(1) -}}</div>{{- "" -}}
|
<div class="bar-chart-value">{{- engine_stat.total | round(1) -}}</div>{{- "" -}}
|
||||||
<div class="bar-chart-graph" aria-labelledby="{{engine_stat.name}}_time" aria-hidden="true">
|
<div class="bar-chart-graph" aria-labelledby="{{engine_stat.name}}_time" aria-hidden="true">
|
||||||
<div class="bar-chart-serie1 bar{{ (100 * engine_stat.http / engine_stats.max_time)|round }}"></div>{{- "" -}}
|
{% if engine_stat.http is not none and engine_stats.max_time %}<div class="bar-chart-serie1 bar{{ (100 * engine_stat.http / engine_stats.max_time)|round }}"></div>{%- endif -%}
|
||||||
<div class="bar-chart-serie2 bar{{ (100 * engine_stat.processing / engine_stats.max_time)|round }}"></div>{{- "" -}}
|
{% if engine_stat.processing is not none and engine_stats.max_time %}<div class="bar-chart-serie2 bar{{ (100 * engine_stat.processing / engine_stats.max_time)|round }}"></div>{%- endif -%}
|
||||||
</div>
|
</div>
|
||||||
<div class="engine-tooltip" role="tooltip" id="{{engine_stat.name}}_time">{{- "" -}}
|
<div class="engine-tooltip" role="tooltip" id="{{engine_stat.name}}_time">{{- "" -}}
|
||||||
<table>
|
<table>
|
||||||
|
@ -70,19 +69,19 @@
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="col">{{ _('Median') }}</th>
|
<th scope="col">{{ _('Median') }}</th>
|
||||||
<td>{{ engine_stat.total }}</td>
|
<td>{{ engine_stat.total }}</td>
|
||||||
<td>{{ engine_stat.http }}</td>
|
<td>{{ engine_stat.http or ''}}</td>
|
||||||
<td>{{ engine_stat.processing }}</td>
|
<td>{{ engine_stat.processing }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="col">{{ _('P80') }}</th>
|
<th scope="col">{{ _('P80') }}</th>
|
||||||
<td>{{ engine_stat.total_p80 }}</td>
|
<td>{{ engine_stat.total_p80 }}</td>
|
||||||
<td>{{ engine_stat.http_p80 }}</td>
|
<td>{{ engine_stat.http_p80 or '' }}</td>
|
||||||
<td>{{ engine_stat.processing_p80 }}</td>
|
<td>{{ engine_stat.processing_p80 }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="col">{{ _('P95') }}</th>
|
<th scope="col">{{ _('P95') }}</th>
|
||||||
<td>{{ engine_stat.total_p95 }}</td>
|
<td>{{ engine_stat.total_p95 }}</td>
|
||||||
<td>{{ engine_stat.http_p95 }}</td>
|
<td>{{ engine_stat.http_p95 or '' }}</td>
|
||||||
<td>{{ engine_stat.processing_p95 }}</td>
|
<td>{{ engine_stat.processing_p95 }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
|
@ -568,7 +568,7 @@ def post_request(response):
|
||||||
timings_total = ['total_' + str(i) + '_' + v['engine'] +
|
timings_total = ['total_' + str(i) + '_' + v['engine'] +
|
||||||
';dur=' + str(round(v['total'] * 1000, 3)) for i, v in enumerate(timings)]
|
';dur=' + str(round(v['total'] * 1000, 3)) for i, v in enumerate(timings)]
|
||||||
timings_load = ['load_' + str(i) + '_' + v['engine'] +
|
timings_load = ['load_' + str(i) + '_' + v['engine'] +
|
||||||
';dur=' + str(round(v['load'] * 1000, 3)) for i, v in enumerate(timings)]
|
';dur=' + str(round(v['load'] * 1000, 3)) for i, v in enumerate(timings) if v.get('load')]
|
||||||
timings_all = timings_all + timings_total + timings_load
|
timings_all = timings_all + timings_total + timings_load
|
||||||
response.headers.add('Server-Timing', ', '.join(timings_all))
|
response.headers.add('Server-Timing', ', '.join(timings_all))
|
||||||
return response
|
return response
|
||||||
|
@ -923,9 +923,9 @@ def preferences():
|
||||||
result_count = int(result_count_sum / float(successful_count)) if successful_count else 0
|
result_count = int(result_count_sum / float(successful_count)) if successful_count else 0
|
||||||
|
|
||||||
stats[e.name] = {
|
stats[e.name] = {
|
||||||
'time': median if median else None,
|
'time': median,
|
||||||
'rate80': rate80 if rate80 else None,
|
'rate80': rate80,
|
||||||
'rate95': rate95 if rate95 else None,
|
'rate95': rate95,
|
||||||
'warn_timeout': e.timeout > settings['outgoing']['request_timeout'],
|
'warn_timeout': e.timeout > settings['outgoing']['request_timeout'],
|
||||||
'supports_selected_language': _is_selected_language_supported(e, request.preferences),
|
'supports_selected_language': _is_selected_language_supported(e, request.preferences),
|
||||||
'result_count': result_count,
|
'result_count': result_count,
|
||||||
|
|
Loading…
Reference in New Issue