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