.oO SearXNG Developer Documentation Oo.
Loading...
Searching...
No Matches
searx.metrics Namespace Reference

Namespaces

namespace  error_recorder
 
namespace  models
 

Functions

 histogram_observe_time (*args)
 
 histogram_observe (duration, *args)
 
 histogram (*args, raise_on_not_found=True)
 
 counter_inc (*args)
 
 counter_add (value, *args)
 
 counter (*args)
 
 initialize (engine_names=None, enabled=True)
 
 get_engine_errors (engline_name_list)
 
 get_reliabilities (engline_name_list, checker_results)
 
 get_engines_stats (engine_name_list)
 
 openmetrics (engine_stats, engine_reliabilities)
 

Variables

list __all__
 
dict ENDPOINTS = {'search'}
 
typing histogram_storage = None
 
typing counter_storage = None
 

Function Documentation

◆ counter()

searx.metrics.counter ( * args)

Definition at line 68 of file __init__.py.

68def counter(*args):
69 return counter_storage.get(*args)
70
71

◆ counter_add()

searx.metrics.counter_add ( value,
* args )

Definition at line 64 of file __init__.py.

64def counter_add(value, *args):
65 counter_storage.add(value, *args)
66
67

◆ counter_inc()

searx.metrics.counter_inc ( * args)

Definition at line 60 of file __init__.py.

60def counter_inc(*args):
61 counter_storage.add(1, *args)
62
63

◆ get_engine_errors()

searx.metrics.get_engine_errors ( engline_name_list)

Definition at line 113 of file __init__.py.

113def get_engine_errors(engline_name_list):
114 result = {}
115 engine_names = list(errors_per_engines.keys())
116 engine_names.sort()
117 for engine_name in engine_names:
118 if engine_name not in engline_name_list:
119 continue
120
121 error_stats = errors_per_engines[engine_name]
122 sent_search_count = max(counter('engine', engine_name, 'search', 'count', 'sent'), 1)
123 sorted_context_count_list = sorted(error_stats.items(), key=lambda context_count: context_count[1])
124 r = []
125 for context, count in sorted_context_count_list:
126 percentage = round(20 * count / sent_search_count) * 5
127 r.append(
128 {
129 'filename': context.filename,
130 'function': context.function,
131 'line_no': context.line_no,
132 'code': context.code,
133 'exception_classname': context.exception_classname,
134 'log_message': context.log_message,
135 'log_parameters': context.log_parameters,
136 'secondary': context.secondary,
137 'percentage': percentage,
138 }
139 )
140 result[engine_name] = sorted(r, reverse=True, key=lambda d: d['percentage'])
141 return result
142
143

◆ get_engines_stats()

searx.metrics.get_engines_stats ( engine_name_list)

Definition at line 177 of file __init__.py.

177def get_engines_stats(engine_name_list):
178 assert counter_storage is not None
179 assert histogram_storage is not None
180
181 list_time = []
182 max_time_total = max_result_count = None
183
184 for engine_name in engine_name_list:
185
186 sent_count = counter('engine', engine_name, 'search', 'count', 'sent')
187 if sent_count == 0:
188 continue
189
190 result_count = histogram('engine', engine_name, 'result', 'count').percentage(50)
191 result_count_sum = histogram('engine', engine_name, 'result', 'count').sum
192 successful_count = counter('engine', engine_name, 'search', 'count', 'successful')
193
194 time_total = histogram('engine', engine_name, 'time', 'total').percentage(50)
195 max_time_total = max(time_total or 0, max_time_total or 0)
196 max_result_count = max(result_count or 0, max_result_count or 0)
197
198 stats = {
199 'name': engine_name,
200 'total': None,
201 'total_p80': None,
202 'total_p95': None,
203 'http': None,
204 'http_p80': None,
205 'http_p95': None,
206 'processing': None,
207 'processing_p80': None,
208 'processing_p95': None,
209 'score': 0,
210 'score_per_result': 0,
211 'result_count': result_count,
212 }
213
214 if successful_count and result_count_sum:
215 score = counter('engine', engine_name, 'score')
216
217 stats['score'] = score
218 stats['score_per_result'] = score / float(result_count_sum)
219
220 time_http = histogram('engine', engine_name, 'time', 'http').percentage(50)
221 time_http_p80 = time_http_p95 = 0
222
223 if time_http is not None:
224
225 time_http_p80 = histogram('engine', engine_name, 'time', 'http').percentage(80)
226 time_http_p95 = histogram('engine', engine_name, 'time', 'http').percentage(95)
227
228 stats['http'] = round(time_http, 1)
229 stats['http_p80'] = round(time_http_p80, 1)
230 stats['http_p95'] = round(time_http_p95, 1)
231
232 if time_total is not None:
233
234 time_total_p80 = histogram('engine', engine_name, 'time', 'total').percentage(80)
235 time_total_p95 = histogram('engine', engine_name, 'time', 'total').percentage(95)
236
237 stats['total'] = round(time_total, 1)
238 stats['total_p80'] = round(time_total_p80, 1)
239 stats['total_p95'] = round(time_total_p95, 1)
240
241 stats['processing'] = round(time_total - (time_http or 0), 1)
242 stats['processing_p80'] = round(time_total_p80 - time_http_p80, 1)
243 stats['processing_p95'] = round(time_total_p95 - time_http_p95, 1)
244
245 list_time.append(stats)
246
247 return {
248 'time': list_time,
249 'max_time': math.ceil(max_time_total or 0),
250 'max_result_count': math.ceil(max_result_count or 0),
251 }
252
253

◆ get_reliabilities()

searx.metrics.get_reliabilities ( engline_name_list,
checker_results )

Definition at line 144 of file __init__.py.

144def get_reliabilities(engline_name_list, checker_results):
145 reliabilities = {}
146
147 engine_errors = get_engine_errors(engline_name_list)
148
149 for engine_name in engline_name_list:
150 checker_result = checker_results.get(engine_name, {})
151 checker_success = checker_result.get('success', True)
152 errors = engine_errors.get(engine_name) or []
153 sent_count = counter('engine', engine_name, 'search', 'count', 'sent')
154
155 if sent_count == 0:
156 # no request
157 reliability = None
158 elif checker_success and not errors:
159 reliability = 100
160 elif 'simple' in checker_result.get('errors', {}):
161 # the basic (simple) test doesn't work: the engine is broken according to the checker
162 # even if there is no exception
163 reliability = 0
164 else:
165 # pylint: disable=consider-using-generator
166 reliability = 100 - sum([error['percentage'] for error in errors if not error.get('secondary')])
167
168 reliabilities[engine_name] = {
169 'reliability': reliability,
170 'sent_count': sent_count,
171 'errors': errors,
172 'checker': checker_result.get('errors', {}),
173 }
174 return reliabilities
175
176

◆ histogram()

searx.metrics.histogram ( * args,
raise_on_not_found = True )

Definition at line 53 of file __init__.py.

53def histogram(*args, raise_on_not_found=True):
54 h = histogram_storage.get(*args)
55 if raise_on_not_found and h is None:
56 raise ValueError("histogram " + repr((*args,)) + " doesn't not exist")
57 return h
58
59

◆ histogram_observe()

searx.metrics.histogram_observe ( duration,
* args )

Definition at line 49 of file __init__.py.

49def histogram_observe(duration, *args):
50 histogram_storage.get(*args).observe(duration)
51
52

◆ histogram_observe_time()

searx.metrics.histogram_observe_time ( * args)

Definition at line 38 of file __init__.py.

38def histogram_observe_time(*args):
39 h = histogram_storage.get(*args)
40 before = default_timer()
41 yield before
42 duration = default_timer() - before
43 if h:
44 h.observe(duration)
45 else:
46 raise ValueError("histogram " + repr((*args,)) + " doesn't not exist")
47
48

◆ initialize()

searx.metrics.initialize ( engine_names = None,
enabled = True )
Initialize metrics

Definition at line 72 of file __init__.py.

72def initialize(engine_names=None, enabled=True):
73 """
74 Initialize metrics
75 """
76 global counter_storage, histogram_storage # pylint: disable=global-statement
77
78 if enabled:
79 counter_storage = CounterStorage()
80 histogram_storage = HistogramStorage()
81 else:
82 counter_storage = VoidCounterStorage()
83 histogram_storage = HistogramStorage(histogram_class=VoidHistogram)
84
85 # max_timeout = max of all the engine.timeout
86 max_timeout = 2
87 for engine_name in engine_names or engines:
88 if engine_name in engines:
89 max_timeout = max(max_timeout, engines[engine_name].timeout)
90
91 # histogram configuration
92 histogram_width = 0.1
93 histogram_size = int(1.5 * max_timeout / histogram_width)
94
95 # engines
96 for engine_name in engine_names or engines:
97 # search count
98 counter_storage.configure('engine', engine_name, 'search', 'count', 'sent')
99 counter_storage.configure('engine', engine_name, 'search', 'count', 'successful')
100 # global counter of errors
101 counter_storage.configure('engine', engine_name, 'search', 'count', 'error')
102 # score of the engine
103 counter_storage.configure('engine', engine_name, 'score')
104 # result count per requests
105 histogram_storage.configure(1, 100, 'engine', engine_name, 'result', 'count')
106 # time doing HTTP requests
107 histogram_storage.configure(histogram_width, histogram_size, 'engine', engine_name, 'time', 'http')
108 # total time
109 # .time.request and ...response times may overlap .time.http time.
110 histogram_storage.configure(histogram_width, histogram_size, 'engine', engine_name, 'time', 'total')
111
112

◆ openmetrics()

searx.metrics.openmetrics ( engine_stats,
engine_reliabilities )

Definition at line 254 of file __init__.py.

254def openmetrics(engine_stats, engine_reliabilities):
255 metrics = [
256 OpenMetricsFamily(
257 key="searxng_engines_response_time_total_seconds",
258 type_hint="gauge",
259 help_hint="The average total response time of the engine",
260 data_info=[{'engine_name': engine['name']} for engine in engine_stats['time']],
261 data=[engine['total'] or 0 for engine in engine_stats['time']],
262 ),
263 OpenMetricsFamily(
264 key="searxng_engines_response_time_processing_seconds",
265 type_hint="gauge",
266 help_hint="The average processing response time of the engine",
267 data_info=[{'engine_name': engine['name']} for engine in engine_stats['time']],
268 data=[engine['processing'] or 0 for engine in engine_stats['time']],
269 ),
270 OpenMetricsFamily(
271 key="searxng_engines_response_time_http_seconds",
272 type_hint="gauge",
273 help_hint="The average HTTP response time of the engine",
274 data_info=[{'engine_name': engine['name']} for engine in engine_stats['time']],
275 data=[engine['http'] or 0 for engine in engine_stats['time']],
276 ),
277 OpenMetricsFamily(
278 key="searxng_engines_result_count_total",
279 type_hint="counter",
280 help_hint="The total amount of results returned by the engine",
281 data_info=[{'engine_name': engine['name']} for engine in engine_stats['time']],
282 data=[engine['result_count'] or 0 for engine in engine_stats['time']],
283 ),
284 OpenMetricsFamily(
285 key="searxng_engines_request_count_total",
286 type_hint="counter",
287 help_hint="The total amount of user requests made to this engine",
288 data_info=[{'engine_name': engine['name']} for engine in engine_stats['time']],
289 data=[
290 engine_reliabilities.get(engine['name'], {}).get('sent_count', 0) or 0
291 for engine in engine_stats['time']
292 ],
293 ),
294 OpenMetricsFamily(
295 key="searxng_engines_reliability_total",
296 type_hint="counter",
297 help_hint="The overall reliability of the engine",
298 data_info=[{'engine_name': engine['name']} for engine in engine_stats['time']],
299 data=[
300 engine_reliabilities.get(engine['name'], {}).get('reliability', 0) or 0
301 for engine in engine_stats['time']
302 ],
303 ),
304 ]
305 return "".join([str(metric) for metric in metrics])

Variable Documentation

◆ __all__

list searx.metrics.__all__
private
Initial value:
1= [
2 "initialize",
3 "get_engines_stats",
4 "get_engine_errors",
5 "histogram",
6 "histogram_observe",
7 "histogram_observe_time",
8 "counter",
9 "counter_inc",
10 "counter_add",
11 "count_error",
12 "count_exception",
13]

Definition at line 15 of file __init__.py.

◆ counter_storage

typing searx.metrics.counter_storage = None

Definition at line 34 of file __init__.py.

◆ ENDPOINTS

dict searx.metrics.ENDPOINTS = {'search'}

Definition at line 30 of file __init__.py.

◆ histogram_storage

typing searx.metrics.histogram_storage = None

Definition at line 33 of file __init__.py.