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