##// END OF EJS Templates
system-info: unified data structures for usage in API....
marcink -
r1112:ff9a513b default
parent child Browse files
Show More
@@ -596,9 +596,9 b' class SettingsController(BaseController)'
596 596
597 597 # Systems stats
598 598 (_('CPU'), val('cpu'), state('cpu')),
599 (_('Load'), val('load'), state('load')),
600 (_('Memory'), val('memory'), state('memory')),
601 (_('Uptime'), val('uptime')['uptime'], state('uptime')),
599 (_('Load'), val('load')['text'], state('load')),
600 (_('Memory'), val('memory')['text'], state('memory')),
601 (_('Uptime'), val('uptime')['text'], state('uptime')),
602 602 ('', '', ''), # spacer
603 603
604 604 # Repo storage
@@ -612,8 +612,8 b' class SettingsController(BaseController)'
612 612 (_('Archive cache storage location'), val('storage_archive')['path'], state('storage_archive')),
613 613 (_('Archive cache info'), val('storage_archive')['text'], state('storage_archive')),
614 614
615 (_('Search storage'), val('storage_search')['path'], state('storage_search')),
616 (_('Search info'), val('storage_search')['text'], state('storage_search')),
615 (_('Search info'), val('search')['text'], state('search')),
616 (_('Search location'), val('search')['location'], state('search')),
617 617 ('', '', ''), # spacer
618 618
619 619 # VCS specific
@@ -4,6 +4,7 b' import time'
4 4 import platform
5 5 import pkg_resources
6 6 import logging
7 import string
7 8
8 9
9 10 log = logging.getLogger(__name__)
@@ -93,10 +94,8 b' class SysInfo(object):'
93 94
94 95 # SysInfo functions
95 96 def python_info():
96 value = {
97 'version': ' '.join(platform._sys_version()),
98 'executable': sys.executable
99 }
97 value = dict(version=' '.join(platform._sys_version()),
98 executable=sys.executable)
100 99 return SysInfoRes(value=value)
101 100
102 101
@@ -115,84 +114,95 b' def platform_type():'
115 114
116 115 def uptime():
117 116 from rhodecode.lib.helpers import age, time_to_datetime
118 from rhodecode.translation import _
119 117
120 _uptime = _uptime_human = {'boot_time': 0, 'uptime': 0}
118 value = dict(boot_time=0, uptime=0, text='')
121 119 state = STATE_OK_DEFAULT
122 120 if not psutil:
123 return SysInfoRes(value=_uptime, state=state)
121 return SysInfoRes(value=value, state=state)
124 122
125 123 boot_time = psutil.boot_time()
126 _uptime['boot_time'] = boot_time
127 _uptime['uptime'] = time.time() - boot_time
124 value['boot_time'] = boot_time
125 value['uptime'] = time.time() - boot_time
128 126
129 _uptime_human['boot_time'] = time_to_datetime(boot_time)
130 _uptime_human['uptime'] = _('Server started {}').format(
127 human_value = value.copy()
128 human_value['boot_time'] = time_to_datetime(boot_time)
129 human_value['uptime'] = age(time_to_datetime(boot_time), show_suffix=False)
130 human_value['text'] = 'Server started {}'.format(
131 131 age(time_to_datetime(boot_time)))
132 132
133 return SysInfoRes(value=_uptime, human_value=_uptime_human)
133 return SysInfoRes(value=value, human_value=human_value)
134 134
135 135
136 136 def memory():
137 137 from rhodecode.lib.helpers import format_byte_size_binary
138 _memory = {'available': 0, 'used': 0, 'cached': 0, 'percent': 0,
139 'percent_used': 0, 'free': 0, 'inactive': 0, 'active': 0,
140 'shared': 0, 'total': 0, 'buffers': 0}
138 value = dict(available=0, used=0, cached=0, percent=0, percent_used=0,
139 free=0, inactive=0, active=0, shared=0, total=0, buffers=0,
140 text='')
141
141 142 state = STATE_OK_DEFAULT
142 143 if not psutil:
143 return SysInfoRes(value=_memory, state=state)
144 return SysInfoRes(value=value, state=state)
144 145
145 # memory
146 _memory = dict(psutil.virtual_memory()._asdict())
147 _memory['percent_used'] = psutil._common.usage_percent(
148 (_memory['total'] - _memory['free']), _memory['total'], 1)
146 value.update(dict(psutil.virtual_memory()._asdict()))
147 value['percent_used'] = psutil._common.usage_percent(
148 (value['total'] - value['free']), value['total'], 1)
149 149
150 try:
151 human_value = '%s/%s, %s%% used' % (
152 format_byte_size_binary(_memory['used']),
153 format_byte_size_binary(_memory['total']),
154 _memory['percent_used'],)
155 except TypeError:
156 human_value = 'NOT AVAILABLE'
150 human_value = value.copy()
151 human_value['text'] = '%s/%s, %s%% used' % (
152 format_byte_size_binary(value['used']),
153 format_byte_size_binary(value['total']),
154 value['percent_used'],)
157 155
158 if state['type'] == STATE_OK and _memory['percent_used'] > 90:
156 keys = value.keys()[::]
157 keys.pop(keys.index('percent'))
158 keys.pop(keys.index('percent_used'))
159 keys.pop(keys.index('text'))
160 for k in keys:
161 human_value[k] = format_byte_size_binary(value[k])
162
163 if state['type'] == STATE_OK and value['percent_used'] > 90:
159 164 msg = 'Critical: your available RAM memory is very low.'
160 165 state = {'message': msg, 'type': STATE_ERR}
161 166
162 elif state['type'] == STATE_OK and _memory['percent_used'] > 70:
167 elif state['type'] == STATE_OK and value['percent_used'] > 70:
163 168 msg = 'Warning: your available RAM memory is running low.'
164 169 state = {'message': msg, 'type': STATE_WARN}
165 170
166 return SysInfoRes(value=_memory, state=state, human_value=human_value)
171 return SysInfoRes(value=value, state=state, human_value=human_value)
167 172
168 173
169 174 def machine_load():
170 _load = {'1_min': _NA, '5_min': _NA, '15_min': _NA}
171
175 value = {'1_min': _NA, '5_min': _NA, '15_min': _NA, 'text': ''}
172 176 state = STATE_OK_DEFAULT
173 177 if not psutil:
174 return SysInfoRes(value=_load, state=state)
178 return SysInfoRes(value=value, state=state)
175 179
176 180 # load averages
177 181 if hasattr(psutil.os, 'getloadavg'):
178 _load = dict(zip(['1_min', '5_min', '15_min'], psutil.os.getloadavg()))
182 value.update(dict(
183 zip(['1_min', '5_min', '15_min'], psutil.os.getloadavg())))
179 184
180 human_value = '1min: %s, 5min: %s, 15min: %s' % (
181 _load['1_min'], _load['5_min'], _load['15_min'])
185 human_value = value.copy()
186 human_value['text'] = '1min: {}, 5min: {}, 15min: {}'.format(
187 value['1_min'], value['5_min'], value['15_min'])
182 188
183 # TODO: warn about too-much load 15 min
184 return SysInfoRes(value=_load, state=state, human_value=human_value)
189 if state['type'] == STATE_OK and value['15_min'] > 5:
190 msg = 'Warning: your machine load is very high.'
191 state = {'message': msg, 'type': STATE_WARN}
192
193 return SysInfoRes(value=value, state=state, human_value=human_value)
185 194
186 195
187 196 def cpu():
197 value = 0
188 198 state = STATE_OK_DEFAULT
189 cpu_value = 0
199
190 200 if not psutil:
191 return SysInfoRes(value=cpu_value, state=state)
201 return SysInfoRes(value=value, state=state)
192 202
193 cpu_value = psutil.cpu_percent(0.5)
194 human_value = '{} %'.format(cpu_value)
195 return SysInfoRes(value=cpu_value, state=state, human_value=human_value)
203 value = psutil.cpu_percent(0.5)
204 human_value = '{} %'.format(value)
205 return SysInfoRes(value=value, state=state, human_value=human_value)
196 206
197 207
198 208 def storage():
@@ -200,69 +210,70 b' def storage():'
200 210 from rhodecode.model.settings import VcsSettingsModel
201 211 path = VcsSettingsModel().get_repos_location()
202 212
203 # disk storage
204 disk = {'percent': 0, 'used': 0, 'total': 0, 'path': path, 'text': ''}
213 value = dict(percent=0, used=0, total=0, path=path, text='')
205 214 state = STATE_OK_DEFAULT
206 215 if not psutil:
207 return SysInfoRes(value=disk, state=state)
216 return SysInfoRes(value=value, state=state)
208 217
209 218 try:
210 disk.update(dict(psutil.disk_usage(path)._asdict()))
219 value.update(dict(psutil.disk_usage(path)._asdict()))
211 220 except Exception as e:
212 221 log.exception('Failed to fetch disk info')
213 222 state = {'message': str(e), 'type': STATE_ERR}
214 223
215 human_value = disk
224 human_value = value.copy()
225 human_value['used'] = format_byte_size_binary(value['used'])
226 human_value['total'] = format_byte_size_binary(value['total'])
216 227 human_value['text'] = "{}/{}, {}% used".format(
217 format_byte_size_binary(disk['used']),
218 format_byte_size_binary(disk['total']),
219 (disk['percent']))
228 format_byte_size_binary(value['used']),
229 format_byte_size_binary(value['total']),
230 value['percent'])
220 231
221 if state['type'] == STATE_OK and disk['percent'] > 90:
232 if state['type'] == STATE_OK and value['percent'] > 90:
222 233 msg = 'Critical: your disk space is very low.'
223 234 state = {'message': msg, 'type': STATE_ERR}
224 235
225 elif state['type'] == STATE_OK and disk['percent'] > 70:
236 elif state['type'] == STATE_OK and value['percent'] > 70:
226 237 msg = 'Warning: your disk space is running low.'
227 238 state = {'message': msg, 'type': STATE_WARN}
228 239
229 return SysInfoRes(value=disk, state=state, human_value=human_value)
240 return SysInfoRes(value=value, state=state, human_value=human_value)
230 241
231 242
232 243 def storage_inodes():
233 244 from rhodecode.model.settings import VcsSettingsModel
234 245 path = VcsSettingsModel().get_repos_location()
235 246
236 _disk_inodes = dict(percent=0, free=0, used=0, total=0, path=path, text='')
247 value = dict(percent=0, free=0, used=0, total=0, path=path, text='')
237 248 state = STATE_OK_DEFAULT
238 249 if not psutil:
239 return SysInfoRes(value=_disk_inodes, state=state)
250 return SysInfoRes(value=value, state=state)
240 251
241 252 try:
242 253 i_stat = os.statvfs(path)
243 254
244 _disk_inodes['used'] = i_stat.f_ffree
245 _disk_inodes['free'] = i_stat.f_favail
246 _disk_inodes['total'] = i_stat.f_files
247 _disk_inodes['percent'] = percentage(
248 _disk_inodes['used'], _disk_inodes['total'])
255 value['used'] = i_stat.f_ffree
256 value['free'] = i_stat.f_favail
257 value['total'] = i_stat.f_files
258 value['percent'] = percentage(
259 value['used'], value['total'])
249 260 except Exception as e:
250 261 log.exception('Failed to fetch disk inodes info')
251 262 state = {'message': str(e), 'type': STATE_ERR}
252 263
253 human_value = _disk_inodes
264 human_value = value.copy()
254 265 human_value['text'] = "{}/{}, {}% used".format(
255 _disk_inodes['used'], _disk_inodes['total'], _disk_inodes['percent'])
266 value['used'], value['total'], value['percent'])
256 267
257 if state['type'] == STATE_OK and _disk_inodes['percent'] > 90:
268 if state['type'] == STATE_OK and value['percent'] > 90:
258 269 msg = 'Critical: your disk free inodes are very low.'
259 270 state = {'message': msg, 'type': STATE_ERR}
260 271
261 elif state['type'] == STATE_OK and _disk_inodes['percent'] > 70:
272 elif state['type'] == STATE_OK and value['percent'] > 70:
262 273 msg = 'Warning: your disk free inodes are running low.'
263 274 state = {'message': msg, 'type': STATE_WARN}
264 275
265 return SysInfoRes(value=_disk_inodes, state=state)
276 return SysInfoRes(value=value, state=state)
266 277
267 278
268 279 def storage_archives():
@@ -274,21 +285,21 b' def storage_archives():'
274 285 'archive_cache_dir=/path/to/cache option in the .ini file'
275 286 path = safe_str(rhodecode.CONFIG.get('archive_cache_dir', msg))
276 287
277 disk_archive = dict(percent=0, used=0, total=0, items=0, path=path, text='')
288 value = dict(percent=0, used=0, total=0, items=0, path=path, text='')
278 289 state = STATE_OK_DEFAULT
279 290 try:
280 291 items_count = 0
281 292 used = 0
282 293 for root, dirs, files in os.walk(path):
283 294 if root == path:
284 items_count = len(dirs)
295 items_count = len(files)
285 296
286 297 for f in files:
287 298 try:
288 299 used += os.path.getsize(os.path.join(root, f))
289 300 except OSError:
290 301 pass
291 disk_archive.update({
302 value.update({
292 303 'percent': 100,
293 304 'used': used,
294 305 'total': used,
@@ -299,11 +310,13 b' def storage_archives():'
299 310 log.exception('failed to fetch archive cache storage')
300 311 state = {'message': str(e), 'type': STATE_ERR}
301 312
302 human_value = disk_archive
303 human_value['text'] = "{} ({} items)".format(format_byte_size_binary(
304 disk_archive['used']), disk_archive['total'])
313 human_value = value.copy()
314 human_value['used'] = format_byte_size_binary(value['used'])
315 human_value['total'] = format_byte_size_binary(value['total'])
316 human_value['text'] = "{} ({} items)".format(
317 human_value['used'], value['items'])
305 318
306 return SysInfoRes(value=disk_archive, state=state, human_value=human_value)
319 return SysInfoRes(value=value, state=state, human_value=human_value)
307 320
308 321
309 322 def storage_gist():
@@ -315,7 +328,7 b' def storage_gist():'
315 328 VcsSettingsModel().get_repos_location(), GIST_STORE_LOC))
316 329
317 330 # gist storage
318 _disk_gist = dict(percent=0, used=0, total=0, items=0, path=path, text='')
331 value = dict(percent=0, used=0, total=0, items=0, path=path, text='')
319 332 state = STATE_OK_DEFAULT
320 333
321 334 try:
@@ -330,7 +343,7 b' def storage_gist():'
330 343 used += os.path.getsize(os.path.join(root, f))
331 344 except OSError:
332 345 pass
333 _disk_gist.update({
346 value.update({
334 347 'percent': 100,
335 348 'used': used,
336 349 'total': used,
@@ -340,37 +353,36 b' def storage_gist():'
340 353 log.exception('failed to fetch gist storage items')
341 354 state = {'message': str(e), 'type': STATE_ERR}
342 355
343 human_value = _disk_gist
344 human_value['text'] = "{} ({} items)".format(format_byte_size_binary(
345 _disk_gist['used']), _disk_gist['items'])
346 return SysInfoRes(value=_disk_gist, state=state, human_value=human_value)
356 human_value = value.copy()
357 human_value['used'] = format_byte_size_binary(value['used'])
358 human_value['total'] = format_byte_size_binary(value['total'])
359 human_value['text'] = "{} ({} items)".format(
360 human_value['used'], value['items'])
361
362 return SysInfoRes(value=value, state=state, human_value=human_value)
347 363
348 364
349 def storage_search():
365 def search_info():
350 366 import rhodecode
351 path = rhodecode.CONFIG.get('search.location', '')
367 from rhodecode.lib.index import searcher_from_config
352 368
353 # search index storage
354 _disk_index = dict(percent=0, used=0, total=0, path=path, text='')
355 state = STATE_OK_DEFAULT
369 backend = rhodecode.CONFIG.get('search.module', '')
370 location = rhodecode.CONFIG.get('search.location', '')
371
356 372 try:
357 search_index_storage_path_exists = os.path.isdir(path)
358 if search_index_storage_path_exists:
359 used = get_storage_size(path)
360 _disk_index.update({
361 'percent': 100,
362 'used': used,
363 'total': used,
364 })
365 except Exception as e:
366 log.exception('failed to fetch search index storage')
367 state = {'message': str(e), 'type': STATE_ERR}
373 searcher = searcher_from_config(rhodecode.CONFIG)
374 searcher = searcher.__class__.__name__
375 except Exception:
376 searcher = None
368 377
369 human_value = _disk_index
370 human_value['text'] = "{}/{}, {}% used".format(
371 _disk_index['used'], _disk_index['total'], _disk_index['percent'])
378 value = dict(
379 backend=backend, searcher=searcher, location=location, text='')
380 state = STATE_OK_DEFAULT
372 381
373 return SysInfoRes(value=_disk_index, state=state, human_value=human_value)
382 human_value = value.copy()
383 human_value['text'] = "backend:`{}`".format(human_value['backend'])
384
385 return SysInfoRes(value=value, state=state, human_value=human_value)
374 386
375 387
376 388 def git_info():
@@ -412,7 +424,8 b' def svn_info():'
412 424
413 425 def vcs_backends():
414 426 import rhodecode
415 value = rhodecode.CONFIG.get('vcs.backends', '').split(',')
427 value = map(
428 string.strip, rhodecode.CONFIG.get('vcs.backends', '').split(','))
416 429 human_value = 'Enabled backends in order: {}'.format(','.join(value))
417 430 return SysInfoRes(value=value, human_value=human_value)
418 431
@@ -443,17 +456,21 b' def vcs_server():'
443 456 text='',
444 457 )
445 458
446 human_value = value
459 human_value = value.copy()
447 460 human_value['text'] = \
448 461 '{url}@ver:{ver} via {mode} mode, connection:{conn}'.format(
449 462 url=server_url, ver=version, mode=protocol, conn=connection)
450 463
451 return SysInfoRes(value='', state=state, human_value=human_value)
464 return SysInfoRes(value=value, state=state, human_value=human_value)
452 465
453 466
454 467 def rhodecode_app_info():
455 468 import rhodecode
456 return SysInfoRes(value={'rhodecode_version': rhodecode.__version__})
469 value = dict(
470 rhodecode_version=rhodecode.__version__,
471 rhodecode_lib_path=os.path.abspath(rhodecode.__file__)
472 )
473 return SysInfoRes(value=value)
457 474
458 475
459 476 def rhodecode_config():
@@ -529,7 +546,7 b' def database_info():'
529 546 url=repr(db_url_obj)
530 547 )
531 548
532 human_value = db_info
549 human_value = db_info.copy()
533 550 human_value['url'] = "{} @ migration version: {}".format(
534 551 db_info['url'], db_info['migrate_version'])
535 552 human_value['version'] = "{} {}".format(db_info['type'], db_info['version'])
@@ -565,9 +582,10 b' def get_system_info(environ):'
565 582 'storage': SysInfo(storage)(),
566 583 'storage_inodes': SysInfo(storage_inodes)(),
567 584 'storage_archive': SysInfo(storage_archives)(),
568 'storage_search': SysInfo(storage_search)(),
569 585 'storage_gist': SysInfo(storage_gist)(),
570 586
587 'search': SysInfo(search_info)(),
588
571 589 'uptime': SysInfo(uptime)(),
572 590 'load': SysInfo(machine_load)(),
573 591 'cpu': SysInfo(cpu)(),
General Comments 0
You need to be logged in to leave comments. Login now