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