##// END OF EJS Templates
system-info: use safer resource.getrlimit becuase of #5501
marcink -
r3184:343cf3c2 default
parent child Browse files
Show More
@@ -1,763 +1,770 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2017-2018 RhodeCode GmbH
3 # Copyright (C) 2017-2018 RhodeCode GmbH
4 #
4 #
5 # This program is free software: you can redistribute it and/or modify
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Affero General Public License, version 3
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
7 # (only), as published by the Free Software Foundation.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU Affero General Public License
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
16 #
17 # This program is dual-licensed. If you wish to learn more about the
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
20
21
21
22 import os
22 import os
23 import sys
23 import sys
24 import time
24 import time
25 import platform
25 import platform
26 import collections
26 import collections
27 import pkg_resources
27 import pkg_resources
28 import logging
28 import logging
29 import resource
29 import resource
30
30
31 from pyramid.compat import configparser
31 from pyramid.compat import configparser
32
32
33 log = logging.getLogger(__name__)
33 log = logging.getLogger(__name__)
34
34
35
35
36 psutil = None
36 psutil = None
37
37
38 try:
38 try:
39 # cygwin cannot have yet psutil support.
39 # cygwin cannot have yet psutil support.
40 import psutil as psutil
40 import psutil as psutil
41 except ImportError:
41 except ImportError:
42 pass
42 pass
43
43
44
44
45 _NA = 'NOT AVAILABLE'
45 _NA = 'NOT AVAILABLE'
46
46
47 STATE_OK = 'ok'
47 STATE_OK = 'ok'
48 STATE_ERR = 'error'
48 STATE_ERR = 'error'
49 STATE_WARN = 'warning'
49 STATE_WARN = 'warning'
50
50
51 STATE_OK_DEFAULT = {'message': '', 'type': STATE_OK}
51 STATE_OK_DEFAULT = {'message': '', 'type': STATE_OK}
52
52
53
53
54 # HELPERS
54 # HELPERS
55 def percentage(part, whole):
55 def percentage(part, whole):
56 whole = float(whole)
56 whole = float(whole)
57 if whole > 0:
57 if whole > 0:
58 return round(100 * float(part) / whole, 1)
58 return round(100 * float(part) / whole, 1)
59 return 0.0
59 return 0.0
60
60
61
61
62 def get_storage_size(storage_path):
62 def get_storage_size(storage_path):
63 sizes = []
63 sizes = []
64 for file_ in os.listdir(storage_path):
64 for file_ in os.listdir(storage_path):
65 storage_file = os.path.join(storage_path, file_)
65 storage_file = os.path.join(storage_path, file_)
66 if os.path.isfile(storage_file):
66 if os.path.isfile(storage_file):
67 try:
67 try:
68 sizes.append(os.path.getsize(storage_file))
68 sizes.append(os.path.getsize(storage_file))
69 except OSError:
69 except OSError:
70 log.exception('Failed to get size of storage file %s',
70 log.exception('Failed to get size of storage file %s',
71 storage_file)
71 storage_file)
72 pass
72 pass
73
73
74 return sum(sizes)
74 return sum(sizes)
75
75
76
76
77 def get_resource(resource_type):
78 try:
79 return resource.getrlimit(resource_type)
80 except Exception:
81 return 'NOT_SUPPORTED'
82
83
77 class SysInfoRes(object):
84 class SysInfoRes(object):
78 def __init__(self, value, state=STATE_OK_DEFAULT, human_value=None):
85 def __init__(self, value, state=None, human_value=None):
79 self.value = value
86 self.value = value
80 self.state = state
87 self.state = state or STATE_OK_DEFAULT
81 self.human_value = human_value or value
88 self.human_value = human_value or value
82
89
83 def __json__(self):
90 def __json__(self):
84 return {
91 return {
85 'value': self.value,
92 'value': self.value,
86 'state': self.state,
93 'state': self.state,
87 'human_value': self.human_value,
94 'human_value': self.human_value,
88 }
95 }
89
96
90 def get_value(self):
97 def get_value(self):
91 return self.__json__()
98 return self.__json__()
92
99
93 def __str__(self):
100 def __str__(self):
94 return '<SysInfoRes({})>'.format(self.__json__())
101 return '<SysInfoRes({})>'.format(self.__json__())
95
102
96
103
97 class SysInfo(object):
104 class SysInfo(object):
98
105
99 def __init__(self, func_name, **kwargs):
106 def __init__(self, func_name, **kwargs):
100 self.func_name = func_name
107 self.func_name = func_name
101 self.value = _NA
108 self.value = _NA
102 self.state = None
109 self.state = None
103 self.kwargs = kwargs or {}
110 self.kwargs = kwargs or {}
104
111
105 def __call__(self):
112 def __call__(self):
106 computed = self.compute(**self.kwargs)
113 computed = self.compute(**self.kwargs)
107 if not isinstance(computed, SysInfoRes):
114 if not isinstance(computed, SysInfoRes):
108 raise ValueError(
115 raise ValueError(
109 'computed value for {} is not instance of '
116 'computed value for {} is not instance of '
110 '{}, got {} instead'.format(
117 '{}, got {} instead'.format(
111 self.func_name, SysInfoRes, type(computed)))
118 self.func_name, SysInfoRes, type(computed)))
112 return computed.__json__()
119 return computed.__json__()
113
120
114 def __str__(self):
121 def __str__(self):
115 return '<SysInfo({})>'.format(self.func_name)
122 return '<SysInfo({})>'.format(self.func_name)
116
123
117 def compute(self, **kwargs):
124 def compute(self, **kwargs):
118 return self.func_name(**kwargs)
125 return self.func_name(**kwargs)
119
126
120
127
121 # SysInfo functions
128 # SysInfo functions
122 def python_info():
129 def python_info():
123 value = dict(version=' '.join(platform._sys_version()),
130 value = dict(version=' '.join(platform._sys_version()),
124 executable=sys.executable)
131 executable=sys.executable)
125 return SysInfoRes(value=value)
132 return SysInfoRes(value=value)
126
133
127
134
128 def py_modules():
135 def py_modules():
129 mods = dict([(p.project_name, p.version)
136 mods = dict([(p.project_name, p.version)
130 for p in pkg_resources.working_set])
137 for p in pkg_resources.working_set])
131 value = sorted(mods.items(), key=lambda k: k[0].lower())
138 value = sorted(mods.items(), key=lambda k: k[0].lower())
132 return SysInfoRes(value=value)
139 return SysInfoRes(value=value)
133
140
134
141
135 def platform_type():
142 def platform_type():
136 from rhodecode.lib.utils import safe_unicode, generate_platform_uuid
143 from rhodecode.lib.utils import safe_unicode, generate_platform_uuid
137
144
138 value = dict(
145 value = dict(
139 name=safe_unicode(platform.platform()),
146 name=safe_unicode(platform.platform()),
140 uuid=generate_platform_uuid()
147 uuid=generate_platform_uuid()
141 )
148 )
142 return SysInfoRes(value=value)
149 return SysInfoRes(value=value)
143
150
144
151
145 def locale_info():
152 def locale_info():
146 import locale
153 import locale
147
154
148 value = dict(
155 value = dict(
149 locale_default=locale.getdefaultlocale(),
156 locale_default=locale.getdefaultlocale(),
150 locale_lc_all=locale.getlocale(locale.LC_ALL),
157 locale_lc_all=locale.getlocale(locale.LC_ALL),
151 lang_env=os.environ.get('LANG'),
158 lang_env=os.environ.get('LANG'),
152 lc_all_env=os.environ.get('LC_ALL'),
159 lc_all_env=os.environ.get('LC_ALL'),
153 local_archive_env=os.environ.get('LOCALE_ARCHIVE'),
160 local_archive_env=os.environ.get('LOCALE_ARCHIVE'),
154 )
161 )
155 human_value = 'LANG: {}, locale LC_ALL: {}, Default locales: {}'.format(
162 human_value = 'LANG: {}, locale LC_ALL: {}, Default locales: {}'.format(
156 value['lang_env'], value['locale_lc_all'], value['locale_default'])
163 value['lang_env'], value['locale_lc_all'], value['locale_default'])
157 return SysInfoRes(value=value, human_value=human_value)
164 return SysInfoRes(value=value, human_value=human_value)
158
165
159
166
160 def ulimit_info():
167 def ulimit_info():
161 data = collections.OrderedDict([
168 data = collections.OrderedDict([
162 ('cpu time (seconds)', resource.getrlimit(resource.RLIMIT_CPU)),
169 ('cpu time (seconds)', get_resource(resource.RLIMIT_CPU)),
163 ('file size', resource.getrlimit(resource.RLIMIT_FSIZE)),
170 ('file size', get_resource(resource.RLIMIT_FSIZE)),
164 ('stack size', resource.getrlimit(resource.RLIMIT_STACK)),
171 ('stack size', get_resource(resource.RLIMIT_STACK)),
165 ('core file size', resource.getrlimit(resource.RLIMIT_CORE)),
172 ('core file size', get_resource(resource.RLIMIT_CORE)),
166 ('address space size', resource.getrlimit(resource.RLIMIT_AS)),
173 ('address space size', get_resource(resource.RLIMIT_AS)),
167 ('locked in mem size', resource.getrlimit(resource.RLIMIT_MEMLOCK)),
174 ('locked in mem size', get_resource(resource.RLIMIT_MEMLOCK)),
168 ('heap size', resource.getrlimit(resource.RLIMIT_DATA)),
175 ('heap size', get_resource(resource.RLIMIT_DATA)),
169 ('rss size', resource.getrlimit(resource.RLIMIT_RSS)),
176 ('rss size', get_resource(resource.RLIMIT_RSS)),
170 ('number of processes', resource.getrlimit(resource.RLIMIT_NPROC)),
177 ('number of processes', get_resource(resource.RLIMIT_NPROC)),
171 ('open files', resource.getrlimit(resource.RLIMIT_NOFILE)),
178 ('open files', get_resource(resource.RLIMIT_NOFILE)),
172 ])
179 ])
173
180
174 text = ', '.join('{}:{}'.format(k,v) for k,v in data.items())
181 text = ', '.join('{}:{}'.format(k,v) for k,v in data.items())
175
182
176 value = {
183 value = {
177 'limits': data,
184 'limits': data,
178 'text': text,
185 'text': text,
179 }
186 }
180 return SysInfoRes(value=value)
187 return SysInfoRes(value=value)
181
188
182
189
183 def uptime():
190 def uptime():
184 from rhodecode.lib.helpers import age, time_to_datetime
191 from rhodecode.lib.helpers import age, time_to_datetime
185 from rhodecode.translation import TranslationString
192 from rhodecode.translation import TranslationString
186
193
187 value = dict(boot_time=0, uptime=0, text='')
194 value = dict(boot_time=0, uptime=0, text='')
188 state = STATE_OK_DEFAULT
195 state = STATE_OK_DEFAULT
189 if not psutil:
196 if not psutil:
190 return SysInfoRes(value=value, state=state)
197 return SysInfoRes(value=value, state=state)
191
198
192 boot_time = psutil.boot_time()
199 boot_time = psutil.boot_time()
193 value['boot_time'] = boot_time
200 value['boot_time'] = boot_time
194 value['uptime'] = time.time() - boot_time
201 value['uptime'] = time.time() - boot_time
195
202
196 date_or_age = age(time_to_datetime(boot_time))
203 date_or_age = age(time_to_datetime(boot_time))
197 if isinstance(date_or_age, TranslationString):
204 if isinstance(date_or_age, TranslationString):
198 date_or_age = date_or_age.interpolate()
205 date_or_age = date_or_age.interpolate()
199
206
200 human_value = value.copy()
207 human_value = value.copy()
201 human_value['boot_time'] = time_to_datetime(boot_time)
208 human_value['boot_time'] = time_to_datetime(boot_time)
202 human_value['uptime'] = age(time_to_datetime(boot_time), show_suffix=False)
209 human_value['uptime'] = age(time_to_datetime(boot_time), show_suffix=False)
203
210
204 human_value['text'] = u'Server started {}'.format(date_or_age)
211 human_value['text'] = u'Server started {}'.format(date_or_age)
205 return SysInfoRes(value=value, human_value=human_value)
212 return SysInfoRes(value=value, human_value=human_value)
206
213
207
214
208 def memory():
215 def memory():
209 from rhodecode.lib.helpers import format_byte_size_binary
216 from rhodecode.lib.helpers import format_byte_size_binary
210 value = dict(available=0, used=0, used_real=0, cached=0, percent=0,
217 value = dict(available=0, used=0, used_real=0, cached=0, percent=0,
211 percent_used=0, free=0, inactive=0, active=0, shared=0,
218 percent_used=0, free=0, inactive=0, active=0, shared=0,
212 total=0, buffers=0, text='')
219 total=0, buffers=0, text='')
213
220
214 state = STATE_OK_DEFAULT
221 state = STATE_OK_DEFAULT
215 if not psutil:
222 if not psutil:
216 return SysInfoRes(value=value, state=state)
223 return SysInfoRes(value=value, state=state)
217
224
218 value.update(dict(psutil.virtual_memory()._asdict()))
225 value.update(dict(psutil.virtual_memory()._asdict()))
219 value['used_real'] = value['total'] - value['available']
226 value['used_real'] = value['total'] - value['available']
220 value['percent_used'] = psutil._common.usage_percent(
227 value['percent_used'] = psutil._common.usage_percent(
221 value['used_real'], value['total'], 1)
228 value['used_real'], value['total'], 1)
222
229
223 human_value = value.copy()
230 human_value = value.copy()
224 human_value['text'] = '%s/%s, %s%% used' % (
231 human_value['text'] = '%s/%s, %s%% used' % (
225 format_byte_size_binary(value['used_real']),
232 format_byte_size_binary(value['used_real']),
226 format_byte_size_binary(value['total']),
233 format_byte_size_binary(value['total']),
227 value['percent_used'],)
234 value['percent_used'],)
228
235
229 keys = value.keys()[::]
236 keys = value.keys()[::]
230 keys.pop(keys.index('percent'))
237 keys.pop(keys.index('percent'))
231 keys.pop(keys.index('percent_used'))
238 keys.pop(keys.index('percent_used'))
232 keys.pop(keys.index('text'))
239 keys.pop(keys.index('text'))
233 for k in keys:
240 for k in keys:
234 human_value[k] = format_byte_size_binary(value[k])
241 human_value[k] = format_byte_size_binary(value[k])
235
242
236 if state['type'] == STATE_OK and value['percent_used'] > 90:
243 if state['type'] == STATE_OK and value['percent_used'] > 90:
237 msg = 'Critical: your available RAM memory is very low.'
244 msg = 'Critical: your available RAM memory is very low.'
238 state = {'message': msg, 'type': STATE_ERR}
245 state = {'message': msg, 'type': STATE_ERR}
239
246
240 elif state['type'] == STATE_OK and value['percent_used'] > 70:
247 elif state['type'] == STATE_OK and value['percent_used'] > 70:
241 msg = 'Warning: your available RAM memory is running low.'
248 msg = 'Warning: your available RAM memory is running low.'
242 state = {'message': msg, 'type': STATE_WARN}
249 state = {'message': msg, 'type': STATE_WARN}
243
250
244 return SysInfoRes(value=value, state=state, human_value=human_value)
251 return SysInfoRes(value=value, state=state, human_value=human_value)
245
252
246
253
247 def machine_load():
254 def machine_load():
248 value = {'1_min': _NA, '5_min': _NA, '15_min': _NA, 'text': ''}
255 value = {'1_min': _NA, '5_min': _NA, '15_min': _NA, 'text': ''}
249 state = STATE_OK_DEFAULT
256 state = STATE_OK_DEFAULT
250 if not psutil:
257 if not psutil:
251 return SysInfoRes(value=value, state=state)
258 return SysInfoRes(value=value, state=state)
252
259
253 # load averages
260 # load averages
254 if hasattr(psutil.os, 'getloadavg'):
261 if hasattr(psutil.os, 'getloadavg'):
255 value.update(dict(
262 value.update(dict(
256 zip(['1_min', '5_min', '15_min'], psutil.os.getloadavg())))
263 zip(['1_min', '5_min', '15_min'], psutil.os.getloadavg())))
257
264
258 human_value = value.copy()
265 human_value = value.copy()
259 human_value['text'] = '1min: {}, 5min: {}, 15min: {}'.format(
266 human_value['text'] = '1min: {}, 5min: {}, 15min: {}'.format(
260 value['1_min'], value['5_min'], value['15_min'])
267 value['1_min'], value['5_min'], value['15_min'])
261
268
262 if state['type'] == STATE_OK and value['15_min'] > 5:
269 if state['type'] == STATE_OK and value['15_min'] > 5:
263 msg = 'Warning: your machine load is very high.'
270 msg = 'Warning: your machine load is very high.'
264 state = {'message': msg, 'type': STATE_WARN}
271 state = {'message': msg, 'type': STATE_WARN}
265
272
266 return SysInfoRes(value=value, state=state, human_value=human_value)
273 return SysInfoRes(value=value, state=state, human_value=human_value)
267
274
268
275
269 def cpu():
276 def cpu():
270 value = {'cpu': 0, 'cpu_count': 0, 'cpu_usage': []}
277 value = {'cpu': 0, 'cpu_count': 0, 'cpu_usage': []}
271 state = STATE_OK_DEFAULT
278 state = STATE_OK_DEFAULT
272
279
273 if not psutil:
280 if not psutil:
274 return SysInfoRes(value=value, state=state)
281 return SysInfoRes(value=value, state=state)
275
282
276 value['cpu'] = psutil.cpu_percent(0.5)
283 value['cpu'] = psutil.cpu_percent(0.5)
277 value['cpu_usage'] = psutil.cpu_percent(0.5, percpu=True)
284 value['cpu_usage'] = psutil.cpu_percent(0.5, percpu=True)
278 value['cpu_count'] = psutil.cpu_count()
285 value['cpu_count'] = psutil.cpu_count()
279
286
280 human_value = value.copy()
287 human_value = value.copy()
281 human_value['text'] = '{} cores at {} %'.format(
288 human_value['text'] = '{} cores at {} %'.format(
282 value['cpu_count'], value['cpu'])
289 value['cpu_count'], value['cpu'])
283
290
284 return SysInfoRes(value=value, state=state, human_value=human_value)
291 return SysInfoRes(value=value, state=state, human_value=human_value)
285
292
286
293
287 def storage():
294 def storage():
288 from rhodecode.lib.helpers import format_byte_size_binary
295 from rhodecode.lib.helpers import format_byte_size_binary
289 from rhodecode.model.settings import VcsSettingsModel
296 from rhodecode.model.settings import VcsSettingsModel
290 path = VcsSettingsModel().get_repos_location()
297 path = VcsSettingsModel().get_repos_location()
291
298
292 value = dict(percent=0, used=0, total=0, path=path, text='')
299 value = dict(percent=0, used=0, total=0, path=path, text='')
293 state = STATE_OK_DEFAULT
300 state = STATE_OK_DEFAULT
294 if not psutil:
301 if not psutil:
295 return SysInfoRes(value=value, state=state)
302 return SysInfoRes(value=value, state=state)
296
303
297 try:
304 try:
298 value.update(dict(psutil.disk_usage(path)._asdict()))
305 value.update(dict(psutil.disk_usage(path)._asdict()))
299 except Exception as e:
306 except Exception as e:
300 log.exception('Failed to fetch disk info')
307 log.exception('Failed to fetch disk info')
301 state = {'message': str(e), 'type': STATE_ERR}
308 state = {'message': str(e), 'type': STATE_ERR}
302
309
303 human_value = value.copy()
310 human_value = value.copy()
304 human_value['used'] = format_byte_size_binary(value['used'])
311 human_value['used'] = format_byte_size_binary(value['used'])
305 human_value['total'] = format_byte_size_binary(value['total'])
312 human_value['total'] = format_byte_size_binary(value['total'])
306 human_value['text'] = "{}/{}, {}% used".format(
313 human_value['text'] = "{}/{}, {}% used".format(
307 format_byte_size_binary(value['used']),
314 format_byte_size_binary(value['used']),
308 format_byte_size_binary(value['total']),
315 format_byte_size_binary(value['total']),
309 value['percent'])
316 value['percent'])
310
317
311 if state['type'] == STATE_OK and value['percent'] > 90:
318 if state['type'] == STATE_OK and value['percent'] > 90:
312 msg = 'Critical: your disk space is very low.'
319 msg = 'Critical: your disk space is very low.'
313 state = {'message': msg, 'type': STATE_ERR}
320 state = {'message': msg, 'type': STATE_ERR}
314
321
315 elif state['type'] == STATE_OK and value['percent'] > 70:
322 elif state['type'] == STATE_OK and value['percent'] > 70:
316 msg = 'Warning: your disk space is running low.'
323 msg = 'Warning: your disk space is running low.'
317 state = {'message': msg, 'type': STATE_WARN}
324 state = {'message': msg, 'type': STATE_WARN}
318
325
319 return SysInfoRes(value=value, state=state, human_value=human_value)
326 return SysInfoRes(value=value, state=state, human_value=human_value)
320
327
321
328
322 def storage_inodes():
329 def storage_inodes():
323 from rhodecode.model.settings import VcsSettingsModel
330 from rhodecode.model.settings import VcsSettingsModel
324 path = VcsSettingsModel().get_repos_location()
331 path = VcsSettingsModel().get_repos_location()
325
332
326 value = dict(percent=0, free=0, used=0, total=0, path=path, text='')
333 value = dict(percent=0, free=0, used=0, total=0, path=path, text='')
327 state = STATE_OK_DEFAULT
334 state = STATE_OK_DEFAULT
328 if not psutil:
335 if not psutil:
329 return SysInfoRes(value=value, state=state)
336 return SysInfoRes(value=value, state=state)
330
337
331 try:
338 try:
332 i_stat = os.statvfs(path)
339 i_stat = os.statvfs(path)
333 value['free'] = i_stat.f_ffree
340 value['free'] = i_stat.f_ffree
334 value['used'] = i_stat.f_files-i_stat.f_favail
341 value['used'] = i_stat.f_files-i_stat.f_favail
335 value['total'] = i_stat.f_files
342 value['total'] = i_stat.f_files
336 value['percent'] = percentage(value['used'], value['total'])
343 value['percent'] = percentage(value['used'], value['total'])
337 except Exception as e:
344 except Exception as e:
338 log.exception('Failed to fetch disk inodes info')
345 log.exception('Failed to fetch disk inodes info')
339 state = {'message': str(e), 'type': STATE_ERR}
346 state = {'message': str(e), 'type': STATE_ERR}
340
347
341 human_value = value.copy()
348 human_value = value.copy()
342 human_value['text'] = "{}/{}, {}% used".format(
349 human_value['text'] = "{}/{}, {}% used".format(
343 value['used'], value['total'], value['percent'])
350 value['used'], value['total'], value['percent'])
344
351
345 if state['type'] == STATE_OK and value['percent'] > 90:
352 if state['type'] == STATE_OK and value['percent'] > 90:
346 msg = 'Critical: your disk free inodes are very low.'
353 msg = 'Critical: your disk free inodes are very low.'
347 state = {'message': msg, 'type': STATE_ERR}
354 state = {'message': msg, 'type': STATE_ERR}
348
355
349 elif state['type'] == STATE_OK and value['percent'] > 70:
356 elif state['type'] == STATE_OK and value['percent'] > 70:
350 msg = 'Warning: your disk free inodes are running low.'
357 msg = 'Warning: your disk free inodes are running low.'
351 state = {'message': msg, 'type': STATE_WARN}
358 state = {'message': msg, 'type': STATE_WARN}
352
359
353 return SysInfoRes(value=value, state=state, human_value=human_value)
360 return SysInfoRes(value=value, state=state, human_value=human_value)
354
361
355
362
356 def storage_archives():
363 def storage_archives():
357 import rhodecode
364 import rhodecode
358 from rhodecode.lib.utils import safe_str
365 from rhodecode.lib.utils import safe_str
359 from rhodecode.lib.helpers import format_byte_size_binary
366 from rhodecode.lib.helpers import format_byte_size_binary
360
367
361 msg = 'Enable this by setting ' \
368 msg = 'Enable this by setting ' \
362 'archive_cache_dir=/path/to/cache option in the .ini file'
369 'archive_cache_dir=/path/to/cache option in the .ini file'
363 path = safe_str(rhodecode.CONFIG.get('archive_cache_dir', msg))
370 path = safe_str(rhodecode.CONFIG.get('archive_cache_dir', msg))
364
371
365 value = dict(percent=0, used=0, total=0, items=0, path=path, text='')
372 value = dict(percent=0, used=0, total=0, items=0, path=path, text='')
366 state = STATE_OK_DEFAULT
373 state = STATE_OK_DEFAULT
367 try:
374 try:
368 items_count = 0
375 items_count = 0
369 used = 0
376 used = 0
370 for root, dirs, files in os.walk(path):
377 for root, dirs, files in os.walk(path):
371 if root == path:
378 if root == path:
372 items_count = len(files)
379 items_count = len(files)
373
380
374 for f in files:
381 for f in files:
375 try:
382 try:
376 used += os.path.getsize(os.path.join(root, f))
383 used += os.path.getsize(os.path.join(root, f))
377 except OSError:
384 except OSError:
378 pass
385 pass
379 value.update({
386 value.update({
380 'percent': 100,
387 'percent': 100,
381 'used': used,
388 'used': used,
382 'total': used,
389 'total': used,
383 'items': items_count
390 'items': items_count
384 })
391 })
385
392
386 except Exception as e:
393 except Exception as e:
387 log.exception('failed to fetch archive cache storage')
394 log.exception('failed to fetch archive cache storage')
388 state = {'message': str(e), 'type': STATE_ERR}
395 state = {'message': str(e), 'type': STATE_ERR}
389
396
390 human_value = value.copy()
397 human_value = value.copy()
391 human_value['used'] = format_byte_size_binary(value['used'])
398 human_value['used'] = format_byte_size_binary(value['used'])
392 human_value['total'] = format_byte_size_binary(value['total'])
399 human_value['total'] = format_byte_size_binary(value['total'])
393 human_value['text'] = "{} ({} items)".format(
400 human_value['text'] = "{} ({} items)".format(
394 human_value['used'], value['items'])
401 human_value['used'], value['items'])
395
402
396 return SysInfoRes(value=value, state=state, human_value=human_value)
403 return SysInfoRes(value=value, state=state, human_value=human_value)
397
404
398
405
399 def storage_gist():
406 def storage_gist():
400 from rhodecode.model.gist import GIST_STORE_LOC
407 from rhodecode.model.gist import GIST_STORE_LOC
401 from rhodecode.model.settings import VcsSettingsModel
408 from rhodecode.model.settings import VcsSettingsModel
402 from rhodecode.lib.utils import safe_str
409 from rhodecode.lib.utils import safe_str
403 from rhodecode.lib.helpers import format_byte_size_binary
410 from rhodecode.lib.helpers import format_byte_size_binary
404 path = safe_str(os.path.join(
411 path = safe_str(os.path.join(
405 VcsSettingsModel().get_repos_location(), GIST_STORE_LOC))
412 VcsSettingsModel().get_repos_location(), GIST_STORE_LOC))
406
413
407 # gist storage
414 # gist storage
408 value = dict(percent=0, used=0, total=0, items=0, path=path, text='')
415 value = dict(percent=0, used=0, total=0, items=0, path=path, text='')
409 state = STATE_OK_DEFAULT
416 state = STATE_OK_DEFAULT
410
417
411 try:
418 try:
412 items_count = 0
419 items_count = 0
413 used = 0
420 used = 0
414 for root, dirs, files in os.walk(path):
421 for root, dirs, files in os.walk(path):
415 if root == path:
422 if root == path:
416 items_count = len(dirs)
423 items_count = len(dirs)
417
424
418 for f in files:
425 for f in files:
419 try:
426 try:
420 used += os.path.getsize(os.path.join(root, f))
427 used += os.path.getsize(os.path.join(root, f))
421 except OSError:
428 except OSError:
422 pass
429 pass
423 value.update({
430 value.update({
424 'percent': 100,
431 'percent': 100,
425 'used': used,
432 'used': used,
426 'total': used,
433 'total': used,
427 'items': items_count
434 'items': items_count
428 })
435 })
429 except Exception as e:
436 except Exception as e:
430 log.exception('failed to fetch gist storage items')
437 log.exception('failed to fetch gist storage items')
431 state = {'message': str(e), 'type': STATE_ERR}
438 state = {'message': str(e), 'type': STATE_ERR}
432
439
433 human_value = value.copy()
440 human_value = value.copy()
434 human_value['used'] = format_byte_size_binary(value['used'])
441 human_value['used'] = format_byte_size_binary(value['used'])
435 human_value['total'] = format_byte_size_binary(value['total'])
442 human_value['total'] = format_byte_size_binary(value['total'])
436 human_value['text'] = "{} ({} items)".format(
443 human_value['text'] = "{} ({} items)".format(
437 human_value['used'], value['items'])
444 human_value['used'], value['items'])
438
445
439 return SysInfoRes(value=value, state=state, human_value=human_value)
446 return SysInfoRes(value=value, state=state, human_value=human_value)
440
447
441
448
442 def storage_temp():
449 def storage_temp():
443 import tempfile
450 import tempfile
444 from rhodecode.lib.helpers import format_byte_size_binary
451 from rhodecode.lib.helpers import format_byte_size_binary
445
452
446 path = tempfile.gettempdir()
453 path = tempfile.gettempdir()
447 value = dict(percent=0, used=0, total=0, items=0, path=path, text='')
454 value = dict(percent=0, used=0, total=0, items=0, path=path, text='')
448 state = STATE_OK_DEFAULT
455 state = STATE_OK_DEFAULT
449
456
450 if not psutil:
457 if not psutil:
451 return SysInfoRes(value=value, state=state)
458 return SysInfoRes(value=value, state=state)
452
459
453 try:
460 try:
454 value.update(dict(psutil.disk_usage(path)._asdict()))
461 value.update(dict(psutil.disk_usage(path)._asdict()))
455 except Exception as e:
462 except Exception as e:
456 log.exception('Failed to fetch temp dir info')
463 log.exception('Failed to fetch temp dir info')
457 state = {'message': str(e), 'type': STATE_ERR}
464 state = {'message': str(e), 'type': STATE_ERR}
458
465
459 human_value = value.copy()
466 human_value = value.copy()
460 human_value['used'] = format_byte_size_binary(value['used'])
467 human_value['used'] = format_byte_size_binary(value['used'])
461 human_value['total'] = format_byte_size_binary(value['total'])
468 human_value['total'] = format_byte_size_binary(value['total'])
462 human_value['text'] = "{}/{}, {}% used".format(
469 human_value['text'] = "{}/{}, {}% used".format(
463 format_byte_size_binary(value['used']),
470 format_byte_size_binary(value['used']),
464 format_byte_size_binary(value['total']),
471 format_byte_size_binary(value['total']),
465 value['percent'])
472 value['percent'])
466
473
467 return SysInfoRes(value=value, state=state, human_value=human_value)
474 return SysInfoRes(value=value, state=state, human_value=human_value)
468
475
469
476
470 def search_info():
477 def search_info():
471 import rhodecode
478 import rhodecode
472 from rhodecode.lib.index import searcher_from_config
479 from rhodecode.lib.index import searcher_from_config
473
480
474 backend = rhodecode.CONFIG.get('search.module', '')
481 backend = rhodecode.CONFIG.get('search.module', '')
475 location = rhodecode.CONFIG.get('search.location', '')
482 location = rhodecode.CONFIG.get('search.location', '')
476
483
477 try:
484 try:
478 searcher = searcher_from_config(rhodecode.CONFIG)
485 searcher = searcher_from_config(rhodecode.CONFIG)
479 searcher = searcher.__class__.__name__
486 searcher = searcher.__class__.__name__
480 except Exception:
487 except Exception:
481 searcher = None
488 searcher = None
482
489
483 value = dict(
490 value = dict(
484 backend=backend, searcher=searcher, location=location, text='')
491 backend=backend, searcher=searcher, location=location, text='')
485 state = STATE_OK_DEFAULT
492 state = STATE_OK_DEFAULT
486
493
487 human_value = value.copy()
494 human_value = value.copy()
488 human_value['text'] = "backend:`{}`".format(human_value['backend'])
495 human_value['text'] = "backend:`{}`".format(human_value['backend'])
489
496
490 return SysInfoRes(value=value, state=state, human_value=human_value)
497 return SysInfoRes(value=value, state=state, human_value=human_value)
491
498
492
499
493 def git_info():
500 def git_info():
494 from rhodecode.lib.vcs.backends import git
501 from rhodecode.lib.vcs.backends import git
495 state = STATE_OK_DEFAULT
502 state = STATE_OK_DEFAULT
496 value = human_value = ''
503 value = human_value = ''
497 try:
504 try:
498 value = git.discover_git_version(raise_on_exc=True)
505 value = git.discover_git_version(raise_on_exc=True)
499 human_value = 'version reported from VCSServer: {}'.format(value)
506 human_value = 'version reported from VCSServer: {}'.format(value)
500 except Exception as e:
507 except Exception as e:
501 state = {'message': str(e), 'type': STATE_ERR}
508 state = {'message': str(e), 'type': STATE_ERR}
502
509
503 return SysInfoRes(value=value, state=state, human_value=human_value)
510 return SysInfoRes(value=value, state=state, human_value=human_value)
504
511
505
512
506 def hg_info():
513 def hg_info():
507 from rhodecode.lib.vcs.backends import hg
514 from rhodecode.lib.vcs.backends import hg
508 state = STATE_OK_DEFAULT
515 state = STATE_OK_DEFAULT
509 value = human_value = ''
516 value = human_value = ''
510 try:
517 try:
511 value = hg.discover_hg_version(raise_on_exc=True)
518 value = hg.discover_hg_version(raise_on_exc=True)
512 human_value = 'version reported from VCSServer: {}'.format(value)
519 human_value = 'version reported from VCSServer: {}'.format(value)
513 except Exception as e:
520 except Exception as e:
514 state = {'message': str(e), 'type': STATE_ERR}
521 state = {'message': str(e), 'type': STATE_ERR}
515 return SysInfoRes(value=value, state=state, human_value=human_value)
522 return SysInfoRes(value=value, state=state, human_value=human_value)
516
523
517
524
518 def svn_info():
525 def svn_info():
519 from rhodecode.lib.vcs.backends import svn
526 from rhodecode.lib.vcs.backends import svn
520 state = STATE_OK_DEFAULT
527 state = STATE_OK_DEFAULT
521 value = human_value = ''
528 value = human_value = ''
522 try:
529 try:
523 value = svn.discover_svn_version(raise_on_exc=True)
530 value = svn.discover_svn_version(raise_on_exc=True)
524 human_value = 'version reported from VCSServer: {}'.format(value)
531 human_value = 'version reported from VCSServer: {}'.format(value)
525 except Exception as e:
532 except Exception as e:
526 state = {'message': str(e), 'type': STATE_ERR}
533 state = {'message': str(e), 'type': STATE_ERR}
527 return SysInfoRes(value=value, state=state, human_value=human_value)
534 return SysInfoRes(value=value, state=state, human_value=human_value)
528
535
529
536
530 def vcs_backends():
537 def vcs_backends():
531 import rhodecode
538 import rhodecode
532 value = rhodecode.CONFIG.get('vcs.backends')
539 value = rhodecode.CONFIG.get('vcs.backends')
533 human_value = 'Enabled backends in order: {}'.format(','.join(value))
540 human_value = 'Enabled backends in order: {}'.format(','.join(value))
534 return SysInfoRes(value=value, human_value=human_value)
541 return SysInfoRes(value=value, human_value=human_value)
535
542
536
543
537 def vcs_server():
544 def vcs_server():
538 import rhodecode
545 import rhodecode
539 from rhodecode.lib.vcs.backends import get_vcsserver_service_data
546 from rhodecode.lib.vcs.backends import get_vcsserver_service_data
540
547
541 server_url = rhodecode.CONFIG.get('vcs.server')
548 server_url = rhodecode.CONFIG.get('vcs.server')
542 enabled = rhodecode.CONFIG.get('vcs.server.enable')
549 enabled = rhodecode.CONFIG.get('vcs.server.enable')
543 protocol = rhodecode.CONFIG.get('vcs.server.protocol') or 'http'
550 protocol = rhodecode.CONFIG.get('vcs.server.protocol') or 'http'
544 state = STATE_OK_DEFAULT
551 state = STATE_OK_DEFAULT
545 version = None
552 version = None
546 workers = 0
553 workers = 0
547
554
548 try:
555 try:
549 data = get_vcsserver_service_data()
556 data = get_vcsserver_service_data()
550 if data and 'version' in data:
557 if data and 'version' in data:
551 version = data['version']
558 version = data['version']
552
559
553 if data and 'config' in data:
560 if data and 'config' in data:
554 conf = data['config']
561 conf = data['config']
555 workers = conf.get('workers', 'NOT AVAILABLE')
562 workers = conf.get('workers', 'NOT AVAILABLE')
556
563
557 connection = 'connected'
564 connection = 'connected'
558 except Exception as e:
565 except Exception as e:
559 connection = 'failed'
566 connection = 'failed'
560 state = {'message': str(e), 'type': STATE_ERR}
567 state = {'message': str(e), 'type': STATE_ERR}
561
568
562 value = dict(
569 value = dict(
563 url=server_url,
570 url=server_url,
564 enabled=enabled,
571 enabled=enabled,
565 protocol=protocol,
572 protocol=protocol,
566 connection=connection,
573 connection=connection,
567 version=version,
574 version=version,
568 text='',
575 text='',
569 )
576 )
570
577
571 human_value = value.copy()
578 human_value = value.copy()
572 human_value['text'] = \
579 human_value['text'] = \
573 '{url}@ver:{ver} via {mode} mode[workers:{workers}], connection:{conn}'.format(
580 '{url}@ver:{ver} via {mode} mode[workers:{workers}], connection:{conn}'.format(
574 url=server_url, ver=version, workers=workers, mode=protocol,
581 url=server_url, ver=version, workers=workers, mode=protocol,
575 conn=connection)
582 conn=connection)
576
583
577 return SysInfoRes(value=value, state=state, human_value=human_value)
584 return SysInfoRes(value=value, state=state, human_value=human_value)
578
585
579
586
580 def rhodecode_app_info():
587 def rhodecode_app_info():
581 import rhodecode
588 import rhodecode
582 edition = rhodecode.CONFIG.get('rhodecode.edition')
589 edition = rhodecode.CONFIG.get('rhodecode.edition')
583
590
584 value = dict(
591 value = dict(
585 rhodecode_version=rhodecode.__version__,
592 rhodecode_version=rhodecode.__version__,
586 rhodecode_lib_path=os.path.abspath(rhodecode.__file__),
593 rhodecode_lib_path=os.path.abspath(rhodecode.__file__),
587 text=''
594 text=''
588 )
595 )
589 human_value = value.copy()
596 human_value = value.copy()
590 human_value['text'] = 'RhodeCode {edition}, version {ver}'.format(
597 human_value['text'] = 'RhodeCode {edition}, version {ver}'.format(
591 edition=edition, ver=value['rhodecode_version']
598 edition=edition, ver=value['rhodecode_version']
592 )
599 )
593 return SysInfoRes(value=value, human_value=human_value)
600 return SysInfoRes(value=value, human_value=human_value)
594
601
595
602
596 def rhodecode_config():
603 def rhodecode_config():
597 import rhodecode
604 import rhodecode
598 path = rhodecode.CONFIG.get('__file__')
605 path = rhodecode.CONFIG.get('__file__')
599 rhodecode_ini_safe = rhodecode.CONFIG.copy()
606 rhodecode_ini_safe = rhodecode.CONFIG.copy()
600
607
601 try:
608 try:
602 config = configparser.ConfigParser()
609 config = configparser.ConfigParser()
603 config.read(path)
610 config.read(path)
604 parsed_ini = config
611 parsed_ini = config
605 if parsed_ini.has_section('server:main'):
612 if parsed_ini.has_section('server:main'):
606 parsed_ini = dict(parsed_ini.items('server:main'))
613 parsed_ini = dict(parsed_ini.items('server:main'))
607 except Exception:
614 except Exception:
608 log.exception('Failed to read .ini file for display')
615 log.exception('Failed to read .ini file for display')
609 parsed_ini = {}
616 parsed_ini = {}
610
617
611 cert_path = os.path.join(
618 cert_path = os.path.join(
612 os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(path)))),
619 os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(path)))),
613 '.rccontrol-profile/etc/ca-bundle.crt')
620 '.rccontrol-profile/etc/ca-bundle.crt')
614
621
615 rhodecode_ini_safe['server:main'] = parsed_ini
622 rhodecode_ini_safe['server:main'] = parsed_ini
616
623
617 blacklist = [
624 blacklist = [
618 'rhodecode_license_key',
625 'rhodecode_license_key',
619 'routes.map',
626 'routes.map',
620 'sqlalchemy.db1.url',
627 'sqlalchemy.db1.url',
621 'channelstream.secret',
628 'channelstream.secret',
622 'beaker.session.secret',
629 'beaker.session.secret',
623 'rhodecode.encrypted_values.secret',
630 'rhodecode.encrypted_values.secret',
624 'rhodecode_auth_github_consumer_key',
631 'rhodecode_auth_github_consumer_key',
625 'rhodecode_auth_github_consumer_secret',
632 'rhodecode_auth_github_consumer_secret',
626 'rhodecode_auth_google_consumer_key',
633 'rhodecode_auth_google_consumer_key',
627 'rhodecode_auth_google_consumer_secret',
634 'rhodecode_auth_google_consumer_secret',
628 'rhodecode_auth_bitbucket_consumer_secret',
635 'rhodecode_auth_bitbucket_consumer_secret',
629 'rhodecode_auth_bitbucket_consumer_key',
636 'rhodecode_auth_bitbucket_consumer_key',
630 'rhodecode_auth_twitter_consumer_secret',
637 'rhodecode_auth_twitter_consumer_secret',
631 'rhodecode_auth_twitter_consumer_key',
638 'rhodecode_auth_twitter_consumer_key',
632
639
633 'rhodecode_auth_twitter_secret',
640 'rhodecode_auth_twitter_secret',
634 'rhodecode_auth_github_secret',
641 'rhodecode_auth_github_secret',
635 'rhodecode_auth_google_secret',
642 'rhodecode_auth_google_secret',
636 'rhodecode_auth_bitbucket_secret',
643 'rhodecode_auth_bitbucket_secret',
637
644
638 'appenlight.api_key',
645 'appenlight.api_key',
639 ('app_conf', 'sqlalchemy.db1.url')
646 ('app_conf', 'sqlalchemy.db1.url')
640 ]
647 ]
641 for k in blacklist:
648 for k in blacklist:
642 if isinstance(k, tuple):
649 if isinstance(k, tuple):
643 section, key = k
650 section, key = k
644 if section in rhodecode_ini_safe:
651 if section in rhodecode_ini_safe:
645 rhodecode_ini_safe[section] = '**OBFUSCATED**'
652 rhodecode_ini_safe[section] = '**OBFUSCATED**'
646 else:
653 else:
647 rhodecode_ini_safe.pop(k, None)
654 rhodecode_ini_safe.pop(k, None)
648
655
649 # TODO: maybe put some CONFIG checks here ?
656 # TODO: maybe put some CONFIG checks here ?
650 return SysInfoRes(value={'config': rhodecode_ini_safe,
657 return SysInfoRes(value={'config': rhodecode_ini_safe,
651 'path': path, 'cert_path': cert_path})
658 'path': path, 'cert_path': cert_path})
652
659
653
660
654 def database_info():
661 def database_info():
655 import rhodecode
662 import rhodecode
656 from sqlalchemy.engine import url as engine_url
663 from sqlalchemy.engine import url as engine_url
657 from rhodecode.model.meta import Base as sql_base, Session
664 from rhodecode.model.meta import Base as sql_base, Session
658 from rhodecode.model.db import DbMigrateVersion
665 from rhodecode.model.db import DbMigrateVersion
659
666
660 state = STATE_OK_DEFAULT
667 state = STATE_OK_DEFAULT
661
668
662 db_migrate = DbMigrateVersion.query().filter(
669 db_migrate = DbMigrateVersion.query().filter(
663 DbMigrateVersion.repository_id == 'rhodecode_db_migrations').one()
670 DbMigrateVersion.repository_id == 'rhodecode_db_migrations').one()
664
671
665 db_url_obj = engine_url.make_url(rhodecode.CONFIG['sqlalchemy.db1.url'])
672 db_url_obj = engine_url.make_url(rhodecode.CONFIG['sqlalchemy.db1.url'])
666
673
667 try:
674 try:
668 engine = sql_base.metadata.bind
675 engine = sql_base.metadata.bind
669 db_server_info = engine.dialect._get_server_version_info(
676 db_server_info = engine.dialect._get_server_version_info(
670 Session.connection(bind=engine))
677 Session.connection(bind=engine))
671 db_version = '.'.join(map(str, db_server_info))
678 db_version = '.'.join(map(str, db_server_info))
672 except Exception:
679 except Exception:
673 log.exception('failed to fetch db version')
680 log.exception('failed to fetch db version')
674 db_version = 'UNKNOWN'
681 db_version = 'UNKNOWN'
675
682
676 db_info = dict(
683 db_info = dict(
677 migrate_version=db_migrate.version,
684 migrate_version=db_migrate.version,
678 type=db_url_obj.get_backend_name(),
685 type=db_url_obj.get_backend_name(),
679 version=db_version,
686 version=db_version,
680 url=repr(db_url_obj)
687 url=repr(db_url_obj)
681 )
688 )
682 current_version = db_migrate.version
689 current_version = db_migrate.version
683 expected_version = rhodecode.__dbversion__
690 expected_version = rhodecode.__dbversion__
684 if state['type'] == STATE_OK and current_version != expected_version:
691 if state['type'] == STATE_OK and current_version != expected_version:
685 msg = 'Critical: database schema mismatch, ' \
692 msg = 'Critical: database schema mismatch, ' \
686 'expected version {}, got {}. ' \
693 'expected version {}, got {}. ' \
687 'Please run migrations on your database.'.format(
694 'Please run migrations on your database.'.format(
688 expected_version, current_version)
695 expected_version, current_version)
689 state = {'message': msg, 'type': STATE_ERR}
696 state = {'message': msg, 'type': STATE_ERR}
690
697
691 human_value = db_info.copy()
698 human_value = db_info.copy()
692 human_value['url'] = "{} @ migration version: {}".format(
699 human_value['url'] = "{} @ migration version: {}".format(
693 db_info['url'], db_info['migrate_version'])
700 db_info['url'], db_info['migrate_version'])
694 human_value['version'] = "{} {}".format(db_info['type'], db_info['version'])
701 human_value['version'] = "{} {}".format(db_info['type'], db_info['version'])
695 return SysInfoRes(value=db_info, state=state, human_value=human_value)
702 return SysInfoRes(value=db_info, state=state, human_value=human_value)
696
703
697
704
698 def server_info(environ):
705 def server_info(environ):
699 import rhodecode
706 import rhodecode
700 from rhodecode.lib.base import get_server_ip_addr, get_server_port
707 from rhodecode.lib.base import get_server_ip_addr, get_server_port
701
708
702 value = {
709 value = {
703 'server_ip': '%s:%s' % (
710 'server_ip': '%s:%s' % (
704 get_server_ip_addr(environ, log_errors=False),
711 get_server_ip_addr(environ, log_errors=False),
705 get_server_port(environ)
712 get_server_port(environ)
706 ),
713 ),
707 'server_id': rhodecode.CONFIG.get('instance_id'),
714 'server_id': rhodecode.CONFIG.get('instance_id'),
708 }
715 }
709 return SysInfoRes(value=value)
716 return SysInfoRes(value=value)
710
717
711
718
712 def usage_info():
719 def usage_info():
713 from rhodecode.model.db import User, Repository
720 from rhodecode.model.db import User, Repository
714 value = {
721 value = {
715 'users': User.query().count(),
722 'users': User.query().count(),
716 'users_active': User.query().filter(User.active == True).count(),
723 'users_active': User.query().filter(User.active == True).count(),
717 'repositories': Repository.query().count(),
724 'repositories': Repository.query().count(),
718 'repository_types': {
725 'repository_types': {
719 'hg': Repository.query().filter(
726 'hg': Repository.query().filter(
720 Repository.repo_type == 'hg').count(),
727 Repository.repo_type == 'hg').count(),
721 'git': Repository.query().filter(
728 'git': Repository.query().filter(
722 Repository.repo_type == 'git').count(),
729 Repository.repo_type == 'git').count(),
723 'svn': Repository.query().filter(
730 'svn': Repository.query().filter(
724 Repository.repo_type == 'svn').count(),
731 Repository.repo_type == 'svn').count(),
725 },
732 },
726 }
733 }
727 return SysInfoRes(value=value)
734 return SysInfoRes(value=value)
728
735
729
736
730 def get_system_info(environ):
737 def get_system_info(environ):
731 environ = environ or {}
738 environ = environ or {}
732 return {
739 return {
733 'rhodecode_app': SysInfo(rhodecode_app_info)(),
740 'rhodecode_app': SysInfo(rhodecode_app_info)(),
734 'rhodecode_config': SysInfo(rhodecode_config)(),
741 'rhodecode_config': SysInfo(rhodecode_config)(),
735 'rhodecode_usage': SysInfo(usage_info)(),
742 'rhodecode_usage': SysInfo(usage_info)(),
736 'python': SysInfo(python_info)(),
743 'python': SysInfo(python_info)(),
737 'py_modules': SysInfo(py_modules)(),
744 'py_modules': SysInfo(py_modules)(),
738
745
739 'platform': SysInfo(platform_type)(),
746 'platform': SysInfo(platform_type)(),
740 'locale': SysInfo(locale_info)(),
747 'locale': SysInfo(locale_info)(),
741 'server': SysInfo(server_info, environ=environ)(),
748 'server': SysInfo(server_info, environ=environ)(),
742 'database': SysInfo(database_info)(),
749 'database': SysInfo(database_info)(),
743 'ulimit': SysInfo(ulimit_info)(),
750 'ulimit': SysInfo(ulimit_info)(),
744 'storage': SysInfo(storage)(),
751 'storage': SysInfo(storage)(),
745 'storage_inodes': SysInfo(storage_inodes)(),
752 'storage_inodes': SysInfo(storage_inodes)(),
746 'storage_archive': SysInfo(storage_archives)(),
753 'storage_archive': SysInfo(storage_archives)(),
747 'storage_gist': SysInfo(storage_gist)(),
754 'storage_gist': SysInfo(storage_gist)(),
748 'storage_temp': SysInfo(storage_temp)(),
755 'storage_temp': SysInfo(storage_temp)(),
749
756
750 'search': SysInfo(search_info)(),
757 'search': SysInfo(search_info)(),
751
758
752 'uptime': SysInfo(uptime)(),
759 'uptime': SysInfo(uptime)(),
753 'load': SysInfo(machine_load)(),
760 'load': SysInfo(machine_load)(),
754 'cpu': SysInfo(cpu)(),
761 'cpu': SysInfo(cpu)(),
755 'memory': SysInfo(memory)(),
762 'memory': SysInfo(memory)(),
756
763
757 'vcs_backends': SysInfo(vcs_backends)(),
764 'vcs_backends': SysInfo(vcs_backends)(),
758 'vcs_server': SysInfo(vcs_server)(),
765 'vcs_server': SysInfo(vcs_server)(),
759
766
760 'git': SysInfo(git_info)(),
767 'git': SysInfo(git_info)(),
761 'hg': SysInfo(hg_info)(),
768 'hg': SysInfo(hg_info)(),
762 'svn': SysInfo(svn_info)(),
769 'svn': SysInfo(svn_info)(),
763 }
770 }
General Comments 0
You need to be logged in to leave comments. Login now