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