##// END OF EJS Templates
system-info: fix translatio of uptime string.
marcink -
r1462:af7abb96 default
parent child Browse files
Show More
@@ -1,662 +1,665 b''
1 1 import os
2 2 import sys
3 3 import time
4 4 import platform
5 5 import pkg_resources
6 6 import logging
7 7 import string
8 8
9 9
10 10 log = logging.getLogger(__name__)
11 11
12 12
13 13 psutil = None
14 14
15 15 try:
16 16 # cygwin cannot have yet psutil support.
17 17 import psutil as psutil
18 18 except ImportError:
19 19 pass
20 20
21 21
22 22 _NA = 'NOT AVAILABLE'
23 23
24 24 STATE_OK = 'ok'
25 25 STATE_ERR = 'error'
26 26 STATE_WARN = 'warning'
27 27
28 28 STATE_OK_DEFAULT = {'message': '', 'type': STATE_OK}
29 29
30 30
31 31 # HELPERS
32 32 def percentage(part, whole):
33 33 whole = float(whole)
34 34 if whole > 0:
35 35 return round(100 * float(part) / whole, 1)
36 36 return 0.0
37 37
38 38
39 39 def get_storage_size(storage_path):
40 40 sizes = []
41 41 for file_ in os.listdir(storage_path):
42 42 storage_file = os.path.join(storage_path, file_)
43 43 if os.path.isfile(storage_file):
44 44 try:
45 45 sizes.append(os.path.getsize(storage_file))
46 46 except OSError:
47 47 log.exception('Failed to get size of storage file %s',
48 48 storage_file)
49 49 pass
50 50
51 51 return sum(sizes)
52 52
53 53
54 54 class SysInfoRes(object):
55 55 def __init__(self, value, state=STATE_OK_DEFAULT, human_value=None):
56 56 self.value = value
57 57 self.state = state
58 58 self.human_value = human_value or value
59 59
60 60 def __json__(self):
61 61 return {
62 62 'value': self.value,
63 63 'state': self.state,
64 64 'human_value': self.human_value,
65 65 }
66 66
67 67 def get_value(self):
68 68 return self.__json__()
69 69
70 70 def __str__(self):
71 71 return '<SysInfoRes({})>'.format(self.__json__())
72 72
73 73
74 74 class SysInfo(object):
75 75
76 76 def __init__(self, func_name, **kwargs):
77 77 self.func_name = func_name
78 78 self.value = _NA
79 79 self.state = None
80 80 self.kwargs = kwargs or {}
81 81
82 82 def __call__(self):
83 83 computed = self.compute(**self.kwargs)
84 84 if not isinstance(computed, SysInfoRes):
85 85 raise ValueError(
86 86 'computed value for {} is not instance of '
87 87 '{}, got {} instead'.format(
88 88 self.func_name, SysInfoRes, type(computed)))
89 89 return computed.__json__()
90 90
91 91 def __str__(self):
92 92 return '<SysInfo({})>'.format(self.func_name)
93 93
94 94 def compute(self, **kwargs):
95 95 return self.func_name(**kwargs)
96 96
97 97
98 98 # SysInfo functions
99 99 def python_info():
100 100 value = dict(version=' '.join(platform._sys_version()),
101 101 executable=sys.executable)
102 102 return SysInfoRes(value=value)
103 103
104 104
105 105 def py_modules():
106 106 mods = dict([(p.project_name, p.version)
107 107 for p in pkg_resources.working_set])
108 108 value = sorted(mods.items(), key=lambda k: k[0].lower())
109 109 return SysInfoRes(value=value)
110 110
111 111
112 112 def platform_type():
113 113 from rhodecode.lib.utils import safe_unicode, generate_platform_uuid
114 114
115 115 value = dict(
116 116 name=safe_unicode(platform.platform()),
117 117 uuid=generate_platform_uuid()
118 118 )
119 119 return SysInfoRes(value=value)
120 120
121 121
122 122 def uptime():
123 123 from rhodecode.lib.helpers import age, time_to_datetime
124 from rhodecode.translation import TranslationString
124 125
125 126 value = dict(boot_time=0, uptime=0, text='')
126 127 state = STATE_OK_DEFAULT
127 128 if not psutil:
128 129 return SysInfoRes(value=value, state=state)
129 130
130 131 boot_time = psutil.boot_time()
131 132 value['boot_time'] = boot_time
132 133 value['uptime'] = time.time() - boot_time
133 134
135 date_or_age = age(time_to_datetime(boot_time))
136 if isinstance(date_or_age, TranslationString):
137 date_or_age = date_or_age.interpolate()
138
134 139 human_value = value.copy()
135 140 human_value['boot_time'] = time_to_datetime(boot_time)
136 141 human_value['uptime'] = age(time_to_datetime(boot_time), show_suffix=False)
137 142
138 human_value['text'] = u'Server started {}'.format(
139 age(time_to_datetime(boot_time)))
140
143 human_value['text'] = u'Server started {}'.format(date_or_age)
141 144 return SysInfoRes(value=value, human_value=human_value)
142 145
143 146
144 147 def memory():
145 148 from rhodecode.lib.helpers import format_byte_size_binary
146 149 value = dict(available=0, used=0, used_real=0, cached=0, percent=0,
147 150 percent_used=0, free=0, inactive=0, active=0, shared=0,
148 151 total=0, buffers=0, text='')
149 152
150 153 state = STATE_OK_DEFAULT
151 154 if not psutil:
152 155 return SysInfoRes(value=value, state=state)
153 156
154 157 value.update(dict(psutil.virtual_memory()._asdict()))
155 158 value['used_real'] = value['total'] - value['available']
156 159 value['percent_used'] = psutil._common.usage_percent(
157 160 value['used_real'], value['total'], 1)
158 161
159 162 human_value = value.copy()
160 163 human_value['text'] = '%s/%s, %s%% used' % (
161 164 format_byte_size_binary(value['used_real']),
162 165 format_byte_size_binary(value['total']),
163 166 value['percent_used'],)
164 167
165 168 keys = value.keys()[::]
166 169 keys.pop(keys.index('percent'))
167 170 keys.pop(keys.index('percent_used'))
168 171 keys.pop(keys.index('text'))
169 172 for k in keys:
170 173 human_value[k] = format_byte_size_binary(value[k])
171 174
172 175 if state['type'] == STATE_OK and value['percent_used'] > 90:
173 176 msg = 'Critical: your available RAM memory is very low.'
174 177 state = {'message': msg, 'type': STATE_ERR}
175 178
176 179 elif state['type'] == STATE_OK and value['percent_used'] > 70:
177 180 msg = 'Warning: your available RAM memory is running low.'
178 181 state = {'message': msg, 'type': STATE_WARN}
179 182
180 183 return SysInfoRes(value=value, state=state, human_value=human_value)
181 184
182 185
183 186 def machine_load():
184 187 value = {'1_min': _NA, '5_min': _NA, '15_min': _NA, 'text': ''}
185 188 state = STATE_OK_DEFAULT
186 189 if not psutil:
187 190 return SysInfoRes(value=value, state=state)
188 191
189 192 # load averages
190 193 if hasattr(psutil.os, 'getloadavg'):
191 194 value.update(dict(
192 195 zip(['1_min', '5_min', '15_min'], psutil.os.getloadavg())))
193 196
194 197 human_value = value.copy()
195 198 human_value['text'] = '1min: {}, 5min: {}, 15min: {}'.format(
196 199 value['1_min'], value['5_min'], value['15_min'])
197 200
198 201 if state['type'] == STATE_OK and value['15_min'] > 5:
199 202 msg = 'Warning: your machine load is very high.'
200 203 state = {'message': msg, 'type': STATE_WARN}
201 204
202 205 return SysInfoRes(value=value, state=state, human_value=human_value)
203 206
204 207
205 208 def cpu():
206 209 value = 0
207 210 state = STATE_OK_DEFAULT
208 211
209 212 if not psutil:
210 213 return SysInfoRes(value=value, state=state)
211 214
212 215 value = psutil.cpu_percent(0.5)
213 216 human_value = '{} %'.format(value)
214 217 return SysInfoRes(value=value, state=state, human_value=human_value)
215 218
216 219
217 220 def storage():
218 221 from rhodecode.lib.helpers import format_byte_size_binary
219 222 from rhodecode.model.settings import VcsSettingsModel
220 223 path = VcsSettingsModel().get_repos_location()
221 224
222 225 value = dict(percent=0, used=0, total=0, path=path, text='')
223 226 state = STATE_OK_DEFAULT
224 227 if not psutil:
225 228 return SysInfoRes(value=value, state=state)
226 229
227 230 try:
228 231 value.update(dict(psutil.disk_usage(path)._asdict()))
229 232 except Exception as e:
230 233 log.exception('Failed to fetch disk info')
231 234 state = {'message': str(e), 'type': STATE_ERR}
232 235
233 236 human_value = value.copy()
234 237 human_value['used'] = format_byte_size_binary(value['used'])
235 238 human_value['total'] = format_byte_size_binary(value['total'])
236 239 human_value['text'] = "{}/{}, {}% used".format(
237 240 format_byte_size_binary(value['used']),
238 241 format_byte_size_binary(value['total']),
239 242 value['percent'])
240 243
241 244 if state['type'] == STATE_OK and value['percent'] > 90:
242 245 msg = 'Critical: your disk space is very low.'
243 246 state = {'message': msg, 'type': STATE_ERR}
244 247
245 248 elif state['type'] == STATE_OK and value['percent'] > 70:
246 249 msg = 'Warning: your disk space is running low.'
247 250 state = {'message': msg, 'type': STATE_WARN}
248 251
249 252 return SysInfoRes(value=value, state=state, human_value=human_value)
250 253
251 254
252 255 def storage_inodes():
253 256 from rhodecode.model.settings import VcsSettingsModel
254 257 path = VcsSettingsModel().get_repos_location()
255 258
256 259 value = dict(percent=0, free=0, used=0, total=0, path=path, text='')
257 260 state = STATE_OK_DEFAULT
258 261 if not psutil:
259 262 return SysInfoRes(value=value, state=state)
260 263
261 264 try:
262 265 i_stat = os.statvfs(path)
263 266 value['free'] = i_stat.f_ffree
264 267 value['used'] = i_stat.f_files-i_stat.f_favail
265 268 value['total'] = i_stat.f_files
266 269 value['percent'] = percentage(value['used'], value['total'])
267 270 except Exception as e:
268 271 log.exception('Failed to fetch disk inodes info')
269 272 state = {'message': str(e), 'type': STATE_ERR}
270 273
271 274 human_value = value.copy()
272 275 human_value['text'] = "{}/{}, {}% used".format(
273 276 value['used'], value['total'], value['percent'])
274 277
275 278 if state['type'] == STATE_OK and value['percent'] > 90:
276 279 msg = 'Critical: your disk free inodes are very low.'
277 280 state = {'message': msg, 'type': STATE_ERR}
278 281
279 282 elif state['type'] == STATE_OK and value['percent'] > 70:
280 283 msg = 'Warning: your disk free inodes are running low.'
281 284 state = {'message': msg, 'type': STATE_WARN}
282 285
283 286 return SysInfoRes(value=value, state=state, human_value=human_value)
284 287
285 288
286 289 def storage_archives():
287 290 import rhodecode
288 291 from rhodecode.lib.utils import safe_str
289 292 from rhodecode.lib.helpers import format_byte_size_binary
290 293
291 294 msg = 'Enable this by setting ' \
292 295 'archive_cache_dir=/path/to/cache option in the .ini file'
293 296 path = safe_str(rhodecode.CONFIG.get('archive_cache_dir', msg))
294 297
295 298 value = dict(percent=0, used=0, total=0, items=0, path=path, text='')
296 299 state = STATE_OK_DEFAULT
297 300 try:
298 301 items_count = 0
299 302 used = 0
300 303 for root, dirs, files in os.walk(path):
301 304 if root == path:
302 305 items_count = len(files)
303 306
304 307 for f in files:
305 308 try:
306 309 used += os.path.getsize(os.path.join(root, f))
307 310 except OSError:
308 311 pass
309 312 value.update({
310 313 'percent': 100,
311 314 'used': used,
312 315 'total': used,
313 316 'items': items_count
314 317 })
315 318
316 319 except Exception as e:
317 320 log.exception('failed to fetch archive cache storage')
318 321 state = {'message': str(e), 'type': STATE_ERR}
319 322
320 323 human_value = value.copy()
321 324 human_value['used'] = format_byte_size_binary(value['used'])
322 325 human_value['total'] = format_byte_size_binary(value['total'])
323 326 human_value['text'] = "{} ({} items)".format(
324 327 human_value['used'], value['items'])
325 328
326 329 return SysInfoRes(value=value, state=state, human_value=human_value)
327 330
328 331
329 332 def storage_gist():
330 333 from rhodecode.model.gist import GIST_STORE_LOC
331 334 from rhodecode.model.settings import VcsSettingsModel
332 335 from rhodecode.lib.utils import safe_str
333 336 from rhodecode.lib.helpers import format_byte_size_binary
334 337 path = safe_str(os.path.join(
335 338 VcsSettingsModel().get_repos_location(), GIST_STORE_LOC))
336 339
337 340 # gist storage
338 341 value = dict(percent=0, used=0, total=0, items=0, path=path, text='')
339 342 state = STATE_OK_DEFAULT
340 343
341 344 try:
342 345 items_count = 0
343 346 used = 0
344 347 for root, dirs, files in os.walk(path):
345 348 if root == path:
346 349 items_count = len(dirs)
347 350
348 351 for f in files:
349 352 try:
350 353 used += os.path.getsize(os.path.join(root, f))
351 354 except OSError:
352 355 pass
353 356 value.update({
354 357 'percent': 100,
355 358 'used': used,
356 359 'total': used,
357 360 'items': items_count
358 361 })
359 362 except Exception as e:
360 363 log.exception('failed to fetch gist storage items')
361 364 state = {'message': str(e), 'type': STATE_ERR}
362 365
363 366 human_value = value.copy()
364 367 human_value['used'] = format_byte_size_binary(value['used'])
365 368 human_value['total'] = format_byte_size_binary(value['total'])
366 369 human_value['text'] = "{} ({} items)".format(
367 370 human_value['used'], value['items'])
368 371
369 372 return SysInfoRes(value=value, state=state, human_value=human_value)
370 373
371 374
372 375 def storage_temp():
373 376 import tempfile
374 377 from rhodecode.lib.helpers import format_byte_size_binary
375 378
376 379 path = tempfile.gettempdir()
377 380 value = dict(percent=0, used=0, total=0, items=0, path=path, text='')
378 381 state = STATE_OK_DEFAULT
379 382
380 383 if not psutil:
381 384 return SysInfoRes(value=value, state=state)
382 385
383 386 try:
384 387 value.update(dict(psutil.disk_usage(path)._asdict()))
385 388 except Exception as e:
386 389 log.exception('Failed to fetch temp dir info')
387 390 state = {'message': str(e), 'type': STATE_ERR}
388 391
389 392 human_value = value.copy()
390 393 human_value['used'] = format_byte_size_binary(value['used'])
391 394 human_value['total'] = format_byte_size_binary(value['total'])
392 395 human_value['text'] = "{}/{}, {}% used".format(
393 396 format_byte_size_binary(value['used']),
394 397 format_byte_size_binary(value['total']),
395 398 value['percent'])
396 399
397 400 return SysInfoRes(value=value, state=state, human_value=human_value)
398 401
399 402
400 403 def search_info():
401 404 import rhodecode
402 405 from rhodecode.lib.index import searcher_from_config
403 406
404 407 backend = rhodecode.CONFIG.get('search.module', '')
405 408 location = rhodecode.CONFIG.get('search.location', '')
406 409
407 410 try:
408 411 searcher = searcher_from_config(rhodecode.CONFIG)
409 412 searcher = searcher.__class__.__name__
410 413 except Exception:
411 414 searcher = None
412 415
413 416 value = dict(
414 417 backend=backend, searcher=searcher, location=location, text='')
415 418 state = STATE_OK_DEFAULT
416 419
417 420 human_value = value.copy()
418 421 human_value['text'] = "backend:`{}`".format(human_value['backend'])
419 422
420 423 return SysInfoRes(value=value, state=state, human_value=human_value)
421 424
422 425
423 426 def git_info():
424 427 from rhodecode.lib.vcs.backends import git
425 428 state = STATE_OK_DEFAULT
426 429 value = human_value = ''
427 430 try:
428 431 value = git.discover_git_version(raise_on_exc=True)
429 432 human_value = 'version reported from VCSServer: {}'.format(value)
430 433 except Exception as e:
431 434 state = {'message': str(e), 'type': STATE_ERR}
432 435
433 436 return SysInfoRes(value=value, state=state, human_value=human_value)
434 437
435 438
436 439 def hg_info():
437 440 from rhodecode.lib.vcs.backends import hg
438 441 state = STATE_OK_DEFAULT
439 442 value = human_value = ''
440 443 try:
441 444 value = hg.discover_hg_version(raise_on_exc=True)
442 445 human_value = 'version reported from VCSServer: {}'.format(value)
443 446 except Exception as e:
444 447 state = {'message': str(e), 'type': STATE_ERR}
445 448 return SysInfoRes(value=value, state=state, human_value=human_value)
446 449
447 450
448 451 def svn_info():
449 452 from rhodecode.lib.vcs.backends import svn
450 453 state = STATE_OK_DEFAULT
451 454 value = human_value = ''
452 455 try:
453 456 value = svn.discover_svn_version(raise_on_exc=True)
454 457 human_value = 'version reported from VCSServer: {}'.format(value)
455 458 except Exception as e:
456 459 state = {'message': str(e), 'type': STATE_ERR}
457 460 return SysInfoRes(value=value, state=state, human_value=human_value)
458 461
459 462
460 463 def vcs_backends():
461 464 import rhodecode
462 465 value = map(
463 466 string.strip, rhodecode.CONFIG.get('vcs.backends', '').split(','))
464 467 human_value = 'Enabled backends in order: {}'.format(','.join(value))
465 468 return SysInfoRes(value=value, human_value=human_value)
466 469
467 470
468 471 def vcs_server():
469 472 import rhodecode
470 473 from rhodecode.lib.vcs.backends import get_vcsserver_version
471 474
472 475 server_url = rhodecode.CONFIG.get('vcs.server')
473 476 enabled = rhodecode.CONFIG.get('vcs.server.enable')
474 477 protocol = rhodecode.CONFIG.get('vcs.server.protocol') or 'http'
475 478 state = STATE_OK_DEFAULT
476 479 version = None
477 480
478 481 try:
479 482 version = get_vcsserver_version()
480 483 connection = 'connected'
481 484 except Exception as e:
482 485 connection = 'failed'
483 486 state = {'message': str(e), 'type': STATE_ERR}
484 487
485 488 value = dict(
486 489 url=server_url,
487 490 enabled=enabled,
488 491 protocol=protocol,
489 492 connection=connection,
490 493 version=version,
491 494 text='',
492 495 )
493 496
494 497 human_value = value.copy()
495 498 human_value['text'] = \
496 499 '{url}@ver:{ver} via {mode} mode, connection:{conn}'.format(
497 500 url=server_url, ver=version, mode=protocol, conn=connection)
498 501
499 502 return SysInfoRes(value=value, state=state, human_value=human_value)
500 503
501 504
502 505 def rhodecode_app_info():
503 506 import rhodecode
504 507 edition = rhodecode.CONFIG.get('rhodecode.edition')
505 508
506 509 value = dict(
507 510 rhodecode_version=rhodecode.__version__,
508 511 rhodecode_lib_path=os.path.abspath(rhodecode.__file__),
509 512 text=''
510 513 )
511 514 human_value = value.copy()
512 515 human_value['text'] = 'RhodeCode {edition}, version {ver}'.format(
513 516 edition=edition, ver=value['rhodecode_version']
514 517 )
515 518 return SysInfoRes(value=value, human_value=human_value)
516 519
517 520
518 521 def rhodecode_config():
519 522 import rhodecode
520 523 path = rhodecode.CONFIG.get('__file__')
521 524 rhodecode_ini_safe = rhodecode.CONFIG.copy()
522 525
523 526 blacklist = [
524 527 'rhodecode_license_key',
525 528 'routes.map',
526 529 'pylons.h',
527 530 'pylons.app_globals',
528 531 'pylons.environ_config',
529 532 'sqlalchemy.db1.url',
530 533 'channelstream.secret',
531 534 'beaker.session.secret',
532 535 'rhodecode.encrypted_values.secret',
533 536 'rhodecode_auth_github_consumer_key',
534 537 'rhodecode_auth_github_consumer_secret',
535 538 'rhodecode_auth_google_consumer_key',
536 539 'rhodecode_auth_google_consumer_secret',
537 540 'rhodecode_auth_bitbucket_consumer_secret',
538 541 'rhodecode_auth_bitbucket_consumer_key',
539 542 'rhodecode_auth_twitter_consumer_secret',
540 543 'rhodecode_auth_twitter_consumer_key',
541 544
542 545 'rhodecode_auth_twitter_secret',
543 546 'rhodecode_auth_github_secret',
544 547 'rhodecode_auth_google_secret',
545 548 'rhodecode_auth_bitbucket_secret',
546 549
547 550 'appenlight.api_key',
548 551 ('app_conf', 'sqlalchemy.db1.url')
549 552 ]
550 553 for k in blacklist:
551 554 if isinstance(k, tuple):
552 555 section, key = k
553 556 if section in rhodecode_ini_safe:
554 557 rhodecode_ini_safe[section] = '**OBFUSCATED**'
555 558 else:
556 559 rhodecode_ini_safe.pop(k, None)
557 560
558 561 # TODO: maybe put some CONFIG checks here ?
559 562 return SysInfoRes(value={'config': rhodecode_ini_safe, 'path': path})
560 563
561 564
562 565 def database_info():
563 566 import rhodecode
564 567 from sqlalchemy.engine import url as engine_url
565 568 from rhodecode.model.meta import Base as sql_base, Session
566 569 from rhodecode.model.db import DbMigrateVersion
567 570
568 571 state = STATE_OK_DEFAULT
569 572
570 573 db_migrate = DbMigrateVersion.query().filter(
571 574 DbMigrateVersion.repository_id == 'rhodecode_db_migrations').one()
572 575
573 576 db_url_obj = engine_url.make_url(rhodecode.CONFIG['sqlalchemy.db1.url'])
574 577
575 578 try:
576 579 engine = sql_base.metadata.bind
577 580 db_server_info = engine.dialect._get_server_version_info(
578 581 Session.connection(bind=engine))
579 582 db_version = '.'.join(map(str, db_server_info))
580 583 except Exception:
581 584 log.exception('failed to fetch db version')
582 585 db_version = 'UNKNOWN'
583 586
584 587 db_info = dict(
585 588 migrate_version=db_migrate.version,
586 589 type=db_url_obj.get_backend_name(),
587 590 version=db_version,
588 591 url=repr(db_url_obj)
589 592 )
590 593
591 594 human_value = db_info.copy()
592 595 human_value['url'] = "{} @ migration version: {}".format(
593 596 db_info['url'], db_info['migrate_version'])
594 597 human_value['version'] = "{} {}".format(db_info['type'], db_info['version'])
595 598 return SysInfoRes(value=db_info, state=state, human_value=human_value)
596 599
597 600
598 601 def server_info(environ):
599 602 import rhodecode
600 603 from rhodecode.lib.base import get_server_ip_addr, get_server_port
601 604
602 605 value = {
603 606 'server_ip': '%s:%s' % (
604 607 get_server_ip_addr(environ, log_errors=False),
605 608 get_server_port(environ)
606 609 ),
607 610 'server_id': rhodecode.CONFIG.get('instance_id'),
608 611 }
609 612 return SysInfoRes(value=value)
610 613
611 614
612 615 def usage_info():
613 616 from rhodecode.model.db import User, Repository
614 617 value = {
615 618 'users': User.query().count(),
616 619 'users_active': User.query().filter(User.active == True).count(),
617 620 'repositories': Repository.query().count(),
618 621 'repository_types': {
619 622 'hg': Repository.query().filter(
620 623 Repository.repo_type == 'hg').count(),
621 624 'git': Repository.query().filter(
622 625 Repository.repo_type == 'git').count(),
623 626 'svn': Repository.query().filter(
624 627 Repository.repo_type == 'svn').count(),
625 628 },
626 629 }
627 630 return SysInfoRes(value=value)
628 631
629 632
630 633 def get_system_info(environ):
631 634 environ = environ or {}
632 635 return {
633 636 'rhodecode_app': SysInfo(rhodecode_app_info)(),
634 637 'rhodecode_config': SysInfo(rhodecode_config)(),
635 638 'rhodecode_usage': SysInfo(usage_info)(),
636 639 'python': SysInfo(python_info)(),
637 640 'py_modules': SysInfo(py_modules)(),
638 641
639 642 'platform': SysInfo(platform_type)(),
640 643 'server': SysInfo(server_info, environ=environ)(),
641 644 'database': SysInfo(database_info)(),
642 645
643 646 'storage': SysInfo(storage)(),
644 647 'storage_inodes': SysInfo(storage_inodes)(),
645 648 'storage_archive': SysInfo(storage_archives)(),
646 649 'storage_gist': SysInfo(storage_gist)(),
647 650 'storage_temp': SysInfo(storage_temp)(),
648 651
649 652 'search': SysInfo(search_info)(),
650 653
651 654 'uptime': SysInfo(uptime)(),
652 655 'load': SysInfo(machine_load)(),
653 656 'cpu': SysInfo(cpu)(),
654 657 'memory': SysInfo(memory)(),
655 658
656 659 'vcs_backends': SysInfo(vcs_backends)(),
657 660 'vcs_server': SysInfo(vcs_server)(),
658 661
659 662 'git': SysInfo(git_info)(),
660 663 'hg': SysInfo(hg_info)(),
661 664 'svn': SysInfo(svn_info)(),
662 665 }
General Comments 0
You need to be logged in to leave comments. Login now