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