Merge pull request #23 from searxng/metrics-stats-engines
Metrics stats engines
This commit is contained in:
		
						commit
						51494849fc
					
				| @ -88,6 +88,10 @@ class _brand_namespace: | ||||
|     def ISSUE_URL(self): | ||||
|         return self.get_val('brand', 'issue_url') | ||||
| 
 | ||||
|     @property | ||||
|     def NEW_ISSUE_URL(self): | ||||
|         return self.get_val('brand', 'new_issue_url') | ||||
| 
 | ||||
|     @property | ||||
|     def DOCS_URL(self): | ||||
|         return self.get_val('brand', 'docs_url') | ||||
|  | ||||
| @ -150,7 +150,7 @@ def get_reliabilities(engline_name_list, checker_results): | ||||
|         reliabilities[engine_name] = { | ||||
|             'reliablity': reliablity, | ||||
|             'errors': errors, | ||||
|             'checker': checker_results.get(engine_name, {}).get('errors', {}).keys(), | ||||
|             'checker': checker_results.get(engine_name, {}).get('errors', {}), | ||||
|         } | ||||
|     return reliabilities | ||||
| 
 | ||||
|  | ||||
| @ -7,6 +7,7 @@ brand: | ||||
|     git_url: https://github.com/searxng/searxng | ||||
|     git_branch: master | ||||
|     issue_url: https://github.com/searxng/searxng/issues | ||||
|     new_issue_url: https://github.com/searxng/searxng/issues/new | ||||
|     docs_url: https://searxng.github.io/searxng | ||||
|     public_instances: https://searx.space | ||||
|     wiki_url: https://github.com/searxng/searxng/wiki | ||||
|  | ||||
							
								
								
									
										74
									
								
								searx/templates/__common__/new_issue.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										74
									
								
								searx/templates/__common__/new_issue.html
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,74 @@ | ||||
| {% macro new_issue(new_issue_url, engine_name, engine_reliability) %} | ||||
| <form action="{{ new_issue_url }}" method="GET"> | ||||
|     <input name="title" type="hidden" value="Bug: {{ engine_name }} engine"> | ||||
|     <input name="labels" type="hidden" value="bug"> | ||||
|     <input name="template" type="hidden" value="bug-report.md"> | ||||
|     <textarea name="body" style="display: none;">{{- '' -}} | ||||
| 
 | ||||
| **Version of SearXNG, commit number if you are using on master branch and stipulate if you forked SearXNG** | ||||
| <!-- If you are running on master branch using git execute this command | ||||
| in order to fetch the latest commit ID: | ||||
| ``` | ||||
| git log -1 | ||||
| ```  | ||||
| If you are using searx-docker then look at the bottom of the SearXNG page | ||||
| and check for the version after "Powered by SearXNG" | ||||
| 
 | ||||
| Please also stipulate if you are using a forked version of SearxNG and | ||||
| include a link to the fork source code. | ||||
| --> | ||||
| **How did you install SearXNG?** | ||||
| <!-- Did you install SearXNG using the official wiki or using searx-docker | ||||
| or manually by executing the searx/webapp.py file? --> | ||||
| **What happened?** | ||||
| <!-- A clear and concise description of what the bug is. --> | ||||
| 
 | ||||
| **How To Reproduce** | ||||
| <!-- How can we reproduce this issue? (as minimally and as precisely as possible) --> | ||||
| 
 | ||||
| **Expected behavior** | ||||
| <!-- A clear and concise description of what you expected to happen. --> | ||||
| 
 | ||||
| **Screenshots & Logs** | ||||
| <!-- If applicable, add screenshots, logs to help explain your problem. --> | ||||
| 
 | ||||
| **Additional context** | ||||
| <!-- Add any other context about the problem here. --> | ||||
| 
 | ||||
| **Technical report** | ||||
| 
 | ||||
| {% for error in engine_reliability.errors %} | ||||
| {% if secondary %}Warning{% else %}Error{% endif %} | ||||
| {{'\n  '}}* Error: {{ error.exception_classname or error.log_message }} | ||||
| {{'  '}}* Percentage: {{ error.percentage }} | ||||
| {{'  '}}* Parameters: `{{ error.log_parameters }}` | ||||
| {{'  '}}* File name: `{{ error.filename }}:{{ error.line_no }}` | ||||
| {{'  '}}* Function: `{{ error.function }}` | ||||
| {{'  '}}* Code: `{{ error.code }}` | ||||
| {{'\n'-}} | ||||
| {%- endfor -%} | ||||
| {%- for test_name, results in engine_reliability.checker.items() -%} | ||||
| {%- if loop.first %}Checker{% endif -%} | ||||
| {{-'\n  '}}* {{ test_name }}: {% for result in results%}`{{ result }}`,{% endfor -%} | ||||
| {%- endfor -%} | ||||
|     </textarea> | ||||
|     <style> | ||||
|         .github-issue-button {  | ||||
|             display: block; | ||||
|             padding: 8px 16px; | ||||
|             font-family: sans-serif; | ||||
|             font-size: 16px; | ||||
|             color: white; | ||||
|             background-color: rgb(35, 134, 54); | ||||
|             border: rgb(46, 160, 67); | ||||
|             border-radius: 10px !important; | ||||
|             box-shadow: rgba(0, 0, 0, 0) 0px 0px 0px 0px; | ||||
|         } | ||||
| 
 | ||||
|         .github-issue-button:hover { | ||||
|             background-color: rgb(46, 160, 67); | ||||
|         } | ||||
|     </style> | ||||
|     <button type="submit" class="github-issue-button" title="{{ new_issue_url }}">{{ _('Submit a new issue on Github including the above information') }}</button> | ||||
| </form> | ||||
| {% endmacro %} | ||||
| @ -1,18 +1,21 @@ | ||||
| {% extends "oscar/base.html" %} | ||||
| {% extends 'oscar/base.html' %} | ||||
| {% from '__common__/new_issue.html' import new_issue %} | ||||
| 
 | ||||
| {% block title %}{{ _('stats') }} - {% endblock %} | ||||
| {% block title %}{{ _('stats') }} - {% if selected_engine_name %} {{ selected_engine_name }} - {% endif %}{% endblock %} | ||||
| 
 | ||||
| {%- macro th_sort(column_order, column_name) -%} | ||||
|     {% if column_order==sort_order %} | ||||
|         {{ column_name }} {{ icon('chevron-down') }} | ||||
|     {% else %} | ||||
|         <a href="{{ url_for('stats', sort=column_order) }}">{{ column_name }} | ||||
|     {% endif %} | ||||
|     {%- if selected_engine_name -%} | ||||
|         {{ column_name }} | ||||
|     {%- elif column_order==sort_order -%} | ||||
|         {{ column_name }} {{ icon('arrow-dropdown') }} | ||||
|     {%- else -%} | ||||
|         <a href="{{ url_for('stats', sort=column_order) }}">{{ column_name }}</a> | ||||
|     {%- endif -%} | ||||
| {%- endmacro -%} | ||||
| 
 | ||||
| {% block content %} | ||||
| <div class="container-fluid"> | ||||
|     <h1>{{ _('Engine stats') }}</h1> | ||||
|     <h1>{{ _('Engine stats') }}{% if selected_engine_name %} - {{ selected_engine_name }}{% endif %}</h1> | ||||
|     <div class="row"> | ||||
|         <div class="col-xs-12 col-sm-12 col-md-12"> | ||||
|             <div class="table-responsive"> | ||||
| @ -31,14 +34,14 @@ | ||||
|                         </tr> | ||||
|                         {% for engine_stat in engine_stats.get('time', []) %} | ||||
|                         <tr> | ||||
|                             <td>{{ engine_stat.name }}</td> | ||||
|                             <td><a href="{{ url_for('stats', engine=engine_stat.name|e) }}">{{ engine_stat.name }}</a></td> | ||||
|                             <td style="text-align: right;"> | ||||
|                                 {% if engine_stat.score %} | ||||
|                                 {%- if engine_stat.score -%} | ||||
|                                 <span aria-labelledby="{{engine_stat.name}}_score" >{{ engine_stat.score|round(1) }}</span> | ||||
|                                 <div class="engine-tooltip text-left" role="tooltip" id="{{engine_stat.name}}_score">{{- "" -}} | ||||
|                                     <p>{{ _('Scores per result') }}: {{ engine_stat.score_per_result | round(3) }}</p> | ||||
|                                 </div> | ||||
|                                 {% endif %} | ||||
|                                 {%- endif -%} | ||||
|                             </td> | ||||
|                             <td> | ||||
|                                 {%- if engine_stat.result_count -%} | ||||
| @ -92,6 +95,63 @@ | ||||
|                 {% endif %} | ||||
|             </div> | ||||
|         </div> | ||||
|         <div class="col-xs-12 col-sm-12 col-md-12"> | ||||
|         {% if selected_engine_name %} | ||||
|             {% for secondary in [False, True] %} | ||||
|                 {% set ns = namespace(first=true) %} | ||||
|                 {% for error in engine_reliabilities[selected_engine_name].errors %} | ||||
|                     {% if secondary == error.secondary %} | ||||
|                         {% if ns.first %} | ||||
|                             {% set ns.first = false %} | ||||
|                             <h3>{% if secondary %}{{ _('Warnings') }}{% else %}{{ _('Errors and exceptions') }}{% endif %}</h3> | ||||
|                         {% endif %} | ||||
|                         <table class="table table-striped table-bordered"> | ||||
|                             <tbody style="padding-top: 1rem;"> | ||||
|                                 <tr> | ||||
|                                     {%- if error.exception_classname -%} | ||||
|                                         <th scope="row" style="width: 10rem">{{ _('Exception') }}</th><td>{{ error.exception_classname }}</td> | ||||
|                                     {%- elif error.log_message -%} | ||||
|                                         <th scope="row" style="width: 10rem">{{ _('Message') }}</th><td>{{ error.log_message }}</td> | ||||
|                                     {%- endif -%} | ||||
|                                     <th scope="row" style="width: 10rem">{{ _('Percentage') }}</th><td style="width: 10rem">{{ error.percentage }}</td> | ||||
|                                 </tr> | ||||
|                                 {% if error.log_parameters and error.log_parameters != (None, None, None) %}<tr><th scope="row">{{ _('Parameter') }}</th>{{- '' -}} | ||||
|                                     <td colspan="3"> | ||||
|                                         {%- for param in error.log_parameters -%} | ||||
|                                             <span style="border-right: 1px solid gray; padding: 0 1rem 0 0; margin: 0 0 0 0.5rem;">{{ param }}</span> | ||||
|                                         {%- endfor -%} | ||||
|                                     </td> | ||||
|                                 </tr> | ||||
|                                 {% endif %} | ||||
|                                 <tr><th scope="row">{{ _('Filename') }}</th><td colspan="3">{{ error.filename }}:{{ error.line_no }}</td></tr> | ||||
|                                 <tr><th scope="row">{{ _('Function') }}</th><td colspan="3">{{ error.function }}</td></tr> | ||||
|                                 <tr><th scope="row">{{ _('Code') }}</th><td colspan="3">{{ error.code }}</td></tr> | ||||
|                             </tbody> | ||||
|                         </table> | ||||
|                     {% endif %} | ||||
|                 {% endfor %} | ||||
|             {% endfor %} | ||||
|             {% if engine_reliabilities[selected_engine_name].checker %} | ||||
|                 <h3>{{ _('Checker') }}</h3> | ||||
|                 <table class="table table-striped table-bordered"> | ||||
|                     <tr> | ||||
|                         <th scope="col" style="width: 10rem">{{ _('Failed test') }}</th> | ||||
|                         <th scope="col">{{ _('Comment(s)') }}</th> | ||||
|                     </tr> | ||||
|                     {% for test_name, results in engine_reliabilities[selected_engine_name].checker.items() %} | ||||
|                     <tr> | ||||
|                         <td>{{ test_name }}</td> | ||||
|                         <td> | ||||
|                             {% for r in results %}<p>{{ r }}</p>{% endfor %} | ||||
|                         </td> | ||||
|                     </tr> | ||||
|                     {% endfor %} | ||||
|                 </table> | ||||
|             {% endif %} | ||||
|             {{ new_issue(brand.NEW_ISSUE_URL, selected_engine_name, engine_reliabilities[selected_engine_name]) }} | ||||
|         {% endif %} | ||||
|         </div> | ||||
|     </div> | ||||
| </div> | ||||
| 
 | ||||
| {% endblock %} | ||||
|  | ||||
| @ -1,12 +1,15 @@ | ||||
| {% from 'simple/macros.html' import icon %} | ||||
| {% from '__common__/new_issue.html' import new_issue %} | ||||
| 
 | ||||
| {% extends "simple/base.html" %} | ||||
| 
 | ||||
| {%- macro th_sort(column_order, column_name) -%} | ||||
|     {% if column_order==sort_order %} | ||||
|     {% if selected_engine_name %} | ||||
|         {{ column_name }} | ||||
|     {% elif column_order==sort_order %} | ||||
|         {{ column_name }} {{ icon('arrow-dropdown') }} | ||||
|     {% else %} | ||||
|         <a href="{{ url_for('stats', sort=column_order) }}">{{ column_name }} | ||||
|         <a href="{{ url_for('stats', sort=column_order) }}">{{ column_name }}</a> | ||||
|     {% endif %} | ||||
| {%- endmacro -%} | ||||
| 
 | ||||
| @ -15,12 +18,12 @@ | ||||
| 
 | ||||
| <a href="{{ url_for('index') }}"><h1><span>searx</span></h1></a> | ||||
| 
 | ||||
| <h2>{{ _('Engine stats') }}</h2> | ||||
| <h2>{{ _('Engine stats') }}{% if selected_engine_name %} - {{ selected_engine_name }}{% endif %}</h2> | ||||
| 
 | ||||
| {% if not engine_stats.get('time') %} | ||||
| {{ _('There is currently no data available. ') }} | ||||
| {% else %} | ||||
| <table style="max-width: 1280px; margin: 0 auto;"> | ||||
| <table style="max-width: 1280px; margin: 0 auto 0 0;"> | ||||
|     <tr> | ||||
|         <th scope="col" style="width:20rem;">{{ th_sort('name', _("Engine name")) }}</th> | ||||
|         <th scope="col" style="width:7rem; text-align: right;">{{ th_sort('score', _('Scores')) }}</th> | ||||
| @ -30,7 +33,7 @@ | ||||
|     </tr> | ||||
|     {% for engine_stat in engine_stats.get('time', []) %} | ||||
|     <tr> | ||||
|         <td>{{ engine_stat.name }}</td> | ||||
|         <td><a href="{{ url_for('stats', engine=engine_stat.name|e) }}">{{ engine_stat.name }}</a></td> | ||||
|         <td style="text-align: right;"> | ||||
|             {% if engine_stat.score %} | ||||
|             <span aria-labelledby="{{engine_stat.name}}_score" >{{ engine_stat.score|round(1) }}</span> | ||||
| @ -90,4 +93,61 @@ | ||||
| </table> | ||||
| {% endif %} | ||||
| 
 | ||||
| <div> | ||||
|     {% if selected_engine_name %} | ||||
|         {% for secondary in [False, True] %} | ||||
|             {% set ns = namespace(first=true) %} | ||||
|             {% for error in engine_reliabilities[selected_engine_name].errors %} | ||||
|                 {% if secondary == error.secondary %} | ||||
|                     {% if ns.first %} | ||||
|                         {% set ns.first = false %} | ||||
|                         <h3>{% if secondary %}{{ _('Warnings') }}{% else %}{{ _('Errors and exceptions') }}{% endif %}</h3> | ||||
|                     {% endif %} | ||||
|                     <table style="max-width: 1280px; margin: 1rem; border: 1px solid gray;"> | ||||
|                         <tbody style="padding-top: 1rem;"> | ||||
|                             <tr> | ||||
|                                 {%- if error.exception_classname -%} | ||||
|                                     <th scope="row" style="width: 10rem">{{ _('Exception') }}</th><td>{{ error.exception_classname }}</td> | ||||
|                                 {%- elif error.log_message -%} | ||||
|                                     <th scope="row" style="width: 10rem">{{ _('Message') }}</th><td>{{ error.log_message }}</td> | ||||
|                                 {%- endif -%} | ||||
|                                 <th scope="row" style="width: 10rem">{{ _('Percentage') }}</th><td style="width: 10rem">{{ error.percentage }}</td> | ||||
|                             </tr> | ||||
|                             {% if error.log_parameters and error.log_parameters != (None, None, None) %}<tr><th scope="row">{{ _('Parameter') }}</th>{{- '' -}} | ||||
|                                 <td colspan="3"> | ||||
|                                     {%- for param in error.log_parameters -%} | ||||
|                                         <span style="border-right: 1px solid gray; padding: 0 1rem 0 0; margin: 0 0 0 0.5rem;">{{ param }}</span> | ||||
|                                     {%- endfor -%} | ||||
|                                 </td> | ||||
|                             </tr> | ||||
|                             {% endif %} | ||||
|                             <tr><th scope="row">{{ _('Filename') }}</th><td colspan="3">{{ error.filename }}:{{ error.line_no }}</td></tr> | ||||
|                             <tr><th scope="row">{{ _('Function') }}</th><td colspan="3">{{ error.function }}</td></tr> | ||||
|                             <tr><th scope="row">{{ _('Code') }}</th><td colspan="3">{{ error.code }}</td></tr> | ||||
|                         </tbody> | ||||
|                     </table> | ||||
|                 {% endif %} | ||||
|             {% endfor %} | ||||
|         {% endfor %} | ||||
|         {% if engine_reliabilities[selected_engine_name].checker %} | ||||
|             <h3>{{ _('Checker') }}</h3> | ||||
|             <table> | ||||
|                 <tr> | ||||
|                     <th scope="col" style="width: 10rem">{{ _('Failed test') }}</th> | ||||
|                     <th scope="col">{{ _('Comment(s)') }}</th> | ||||
|                 </tr> | ||||
|                 {% for test_name, results in engine_reliabilities[selected_engine_name].checker.items() %} | ||||
|                 <tr> | ||||
|                     <td>{{ test_name }}</td> | ||||
|                     <td> | ||||
|                         {% for r in results %}<p>{{ r }}</p>{% endfor %} | ||||
|                     </td> | ||||
|                 </tr> | ||||
|                 {% endfor %} | ||||
|             </table> | ||||
|         {% endif %} | ||||
|         {{ new_issue(brand.NEW_ISSUE_URL, selected_engine_name, engine_reliabilities[selected_engine_name]) }} | ||||
|     {% endif %} | ||||
| </div> | ||||
| 
 | ||||
| {% endblock %} | ||||
|  | ||||
| @ -1073,16 +1073,23 @@ def image_proxy(): | ||||
| @app.route('/stats', methods=['GET']) | ||||
| def stats(): | ||||
|     """Render engine statistics page.""" | ||||
|     sort_order = request.args.get('sort', default='name', type=str) | ||||
|     selected_engine_name = request.args.get('engine', default=None, type=str) | ||||
| 
 | ||||
|     filtered_engines = dict(filter(lambda kv: (kv[0], request.preferences.validate_token(kv[1])), engines.items())) | ||||
|     if selected_engine_name: | ||||
|         if selected_engine_name not in filtered_engines: | ||||
|             selected_engine_name = None | ||||
|         else: | ||||
|             filtered_engines = [selected_engine_name] | ||||
| 
 | ||||
|     checker_results = checker_get_result() | ||||
|     checker_results = checker_results['engines'] \ | ||||
|         if checker_results['status'] == 'ok' and 'engines' in checker_results else {} | ||||
| 
 | ||||
|     filtered_engines = dict(filter(lambda kv: (kv[0], request.preferences.validate_token(kv[1])), engines.items())) | ||||
|     engine_stats = get_engines_stats(filtered_engines) | ||||
|     engine_reliabilities = get_reliabilities(filtered_engines, checker_results) | ||||
| 
 | ||||
|     sort_order = request.args.get('sort', default='name', type=str) | ||||
| 
 | ||||
|     SORT_PARAMETERS = { | ||||
|         'name': (False, 'name', ''), | ||||
|         'score': (True, 'score', 0), | ||||
| @ -1114,6 +1121,7 @@ def stats(): | ||||
|         sort_order=sort_order, | ||||
|         engine_stats=engine_stats, | ||||
|         engine_reliabilities=engine_reliabilities, | ||||
|         selected_engine_name=selected_engine_name, | ||||
|     ) | ||||
| 
 | ||||
| 
 | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user