Show More
@@ -0,0 +1,93 b'' | |||||
|
1 | ||||
|
2 | <table id="procList"> | |||
|
3 | <% | |||
|
4 | def get_name(proc): | |||
|
5 | cmd = ' '.join(proc.cmdline()) | |||
|
6 | if 'vcsserver.ini' in cmd: | |||
|
7 | return 'VCSServer' | |||
|
8 | elif 'rhodecode.ini' in cmd: | |||
|
9 | return 'RhodeCode' | |||
|
10 | return proc.name() | |||
|
11 | %> | |||
|
12 | <tr> | |||
|
13 | <td colspan="8"> | |||
|
14 | <span id="processTimeStamp">${h.format_date(h.datetime.now())}</span> | |||
|
15 | </td> | |||
|
16 | </tr> | |||
|
17 | % for proc in c.gunicorn_processes: | |||
|
18 | <% mem = proc.memory_info()%> | |||
|
19 | <% children = proc.children(recursive=True) %> | |||
|
20 | % if children: | |||
|
21 | ||||
|
22 | <tr> | |||
|
23 | <td> | |||
|
24 | <code> | |||
|
25 | ${proc.pid} - ${get_name(proc)} | |||
|
26 | </code> | |||
|
27 | </td> | |||
|
28 | <td> | |||
|
29 | <a href="#showCommand" onclick="$('#pid'+${proc.pid}).toggle();return false"> command </a> | |||
|
30 | <code id="pid${proc.pid}" style="display: none"> | |||
|
31 | ${' '.join(proc.cmdline())} | |||
|
32 | </code> | |||
|
33 | </td> | |||
|
34 | <td></td> | |||
|
35 | <td> | |||
|
36 | RSS:${h.format_byte_size_binary(mem.rss)} | |||
|
37 | </td> | |||
|
38 | <td> | |||
|
39 | VMS:${h.format_byte_size_binary(mem.vms)} | |||
|
40 | </td> | |||
|
41 | <td> | |||
|
42 | AGE: ${h.age_component(h.time_to_utcdatetime(proc.create_time()))} | |||
|
43 | </td> | |||
|
44 | <td> | |||
|
45 | MASTER | |||
|
46 | </td> | |||
|
47 | </tr> | |||
|
48 | <% mem_sum = 0 %> | |||
|
49 | % for proc_child in children: | |||
|
50 | <% mem = proc_child.memory_info()%> | |||
|
51 | <tr> | |||
|
52 | <td> | |||
|
53 | <code> | |||
|
54 | | ${proc_child.pid} - ${get_name(proc_child)} | |||
|
55 | </code> | |||
|
56 | </td> | |||
|
57 | <td> | |||
|
58 | <a href="#showCommand" onclick="$('#pid'+${proc_child.pid}).toggle();return false"> command </a> | |||
|
59 | <code id="pid${proc_child.pid}" style="display: none"> | |||
|
60 | ${' '.join(proc_child.cmdline())} | |||
|
61 | </code> | |||
|
62 | </td> | |||
|
63 | <td> | |||
|
64 | CPU: ${proc_child.cpu_percent()} % | |||
|
65 | </td> | |||
|
66 | <td> | |||
|
67 | RSS:${h.format_byte_size_binary(mem.rss)} | |||
|
68 | <% mem_sum += mem.rss %> | |||
|
69 | </td> | |||
|
70 | <td> | |||
|
71 | VMS:${h.format_byte_size_binary(mem.vms)} | |||
|
72 | </td> | |||
|
73 | <td> | |||
|
74 | AGE: ${h.age_component(h.time_to_utcdatetime(proc_child.create_time()))} | |||
|
75 | </td> | |||
|
76 | <td> | |||
|
77 | <a href="#restartProcess" onclick="restart(this, ${proc_child.pid});return false"> | |||
|
78 | restart | |||
|
79 | </a> | |||
|
80 | </td> | |||
|
81 | </tr> | |||
|
82 | % endfor | |||
|
83 | <tr> | |||
|
84 | <td colspan="2"><code>| total processes: ${len(children)}</code></td> | |||
|
85 | <td></td> | |||
|
86 | <td><strong>RSS:${h.format_byte_size_binary(mem_sum)}</strong></td> | |||
|
87 | <td></td> | |||
|
88 | </tr> | |||
|
89 | <tr><td> <code> -- </code> </td></tr> | |||
|
90 | ||||
|
91 | % endif | |||
|
92 | % endfor | |||
|
93 | </table> |
@@ -70,6 +70,9 b' def admin_routes(config):' | |||||
70 | name='admin_settings_process_management', |
|
70 | name='admin_settings_process_management', | |
71 | pattern='/settings/process_management') |
|
71 | pattern='/settings/process_management') | |
72 | config.add_route( |
|
72 | config.add_route( | |
|
73 | name='admin_settings_process_management_data', | |||
|
74 | pattern='/settings/process_management/data') | |||
|
75 | config.add_route( | |||
73 | name='admin_settings_process_management_signal', |
|
76 | name='admin_settings_process_management_signal', | |
74 | pattern='/settings/process_management/signal') |
|
77 | pattern='/settings/process_management/signal') | |
75 |
|
78 |
@@ -55,6 +55,18 b' class AdminProcessManagementView(BaseApp' | |||||
55 |
|
55 | |||
56 | @LoginRequired() |
|
56 | @LoginRequired() | |
57 | @HasPermissionAllDecorator('hg.admin') |
|
57 | @HasPermissionAllDecorator('hg.admin') | |
|
58 | @view_config( | |||
|
59 | route_name='admin_settings_process_management_data', request_method='GET', | |||
|
60 | renderer='rhodecode:templates/admin/settings/settings_process_management_data.mako') | |||
|
61 | def process_management_data(self): | |||
|
62 | _ = self.request.translate | |||
|
63 | c = self.load_default_context() | |||
|
64 | c.gunicorn_processes = ( | |||
|
65 | p for p in psutil.process_iter() if 'gunicorn' in p.name()) | |||
|
66 | return self._get_template_context(c) | |||
|
67 | ||||
|
68 | @LoginRequired() | |||
|
69 | @HasPermissionAllDecorator('hg.admin') | |||
58 | @CSRFRequired() |
|
70 | @CSRFRequired() | |
59 | @view_config( |
|
71 | @view_config( | |
60 | route_name='admin_settings_process_management_signal', |
|
72 | route_name='admin_settings_process_management_signal', |
@@ -48,6 +48,7 b' function registerRCRoutes() {' | |||||
48 | pyroutes.register('admin_settings_sessions', '/_admin/settings/sessions', []); |
|
48 | pyroutes.register('admin_settings_sessions', '/_admin/settings/sessions', []); | |
49 | pyroutes.register('admin_settings_sessions_cleanup', '/_admin/settings/sessions/cleanup', []); |
|
49 | pyroutes.register('admin_settings_sessions_cleanup', '/_admin/settings/sessions/cleanup', []); | |
50 | pyroutes.register('admin_settings_process_management', '/_admin/settings/process_management', []); |
|
50 | pyroutes.register('admin_settings_process_management', '/_admin/settings/process_management', []); | |
|
51 | pyroutes.register('admin_settings_process_management_data', '/_admin/settings/process_management/data', []); | |||
51 | pyroutes.register('admin_settings_process_management_signal', '/_admin/settings/process_management/signal', []); |
|
52 | pyroutes.register('admin_settings_process_management_signal', '/_admin/settings/process_management/signal', []); | |
52 | pyroutes.register('admin_defaults_repositories', '/_admin/defaults/repositories', []); |
|
53 | pyroutes.register('admin_defaults_repositories', '/_admin/defaults/repositories', []); | |
53 | pyroutes.register('admin_defaults_repositories_update', '/_admin/defaults/repositories/update', []); |
|
54 | pyroutes.register('admin_defaults_repositories_update', '/_admin/defaults/repositories/update', []); | |
@@ -283,6 +284,7 b' function registerRCRoutes() {' | |||||
283 | pyroutes.register('my_account_ssh_keys_generate', '/_admin/my_account/ssh_keys/generate', []); |
|
284 | pyroutes.register('my_account_ssh_keys_generate', '/_admin/my_account/ssh_keys/generate', []); | |
284 | pyroutes.register('my_account_ssh_keys_add', '/_admin/my_account/ssh_keys/new', []); |
|
285 | pyroutes.register('my_account_ssh_keys_add', '/_admin/my_account/ssh_keys/new', []); | |
285 | pyroutes.register('my_account_ssh_keys_delete', '/_admin/my_account/ssh_keys/delete', []); |
|
286 | pyroutes.register('my_account_ssh_keys_delete', '/_admin/my_account/ssh_keys/delete', []); | |
|
287 | pyroutes.register('my_account_user_group_membership', '/_admin/my_account/user_group_membership', []); | |||
286 | pyroutes.register('my_account_emails', '/_admin/my_account/emails', []); |
|
288 | pyroutes.register('my_account_emails', '/_admin/my_account/emails', []); | |
287 | pyroutes.register('my_account_emails_add', '/_admin/my_account/emails/new', []); |
|
289 | pyroutes.register('my_account_emails_add', '/_admin/my_account/emails/new', []); | |
288 | pyroutes.register('my_account_emails_delete', '/_admin/my_account/emails/delete', []); |
|
290 | pyroutes.register('my_account_emails_delete', '/_admin/my_account/emails/delete', []); |
@@ -7,7 +7,10 b'' | |||||
7 | <div class="panel panel-default"> |
|
7 | <div class="panel panel-default"> | |
8 | <div class="panel-heading"> |
|
8 | <div class="panel-heading"> | |
9 | <h3 class="panel-title">${_('Gunicorn process management')}</h3> |
|
9 | <h3 class="panel-title">${_('Gunicorn process management')}</h3> | |
10 |
|
10 | <div class="pull-right"> | ||
|
11 | <a id="autoRefreshEnable" href="#autoRefreshEnable" onclick="enableAutoRefresh(); return false">${_('start auto refresh')}</a> | |||
|
12 | <a id="autoRefreshDisable" href="#autoRefreshDisable" onclick="disableAutoRefresh(); return false" style="display: none">${_('stop auto refresh')}</a> | |||
|
13 | </div> | |||
11 | </div> |
|
14 | </div> | |
12 | <div class="panel-body" id="app"> |
|
15 | <div class="panel-body" id="app"> | |
13 | <h3>List of Gunicorn processes on this machine</h3> |
|
16 | <h3>List of Gunicorn processes on this machine</h3> | |
@@ -20,88 +23,10 b'' | |||||
20 | return 'RhodeCode' |
|
23 | return 'RhodeCode' | |
21 | return proc.name() |
|
24 | return proc.name() | |
22 | %> |
|
25 | %> | |
23 | <table> |
|
26 | <%include file='settings_process_management_data.mako'/> | |
24 | % for proc in c.gunicorn_processes: |
|
|||
25 | <% mem = proc.memory_info()%> |
|
|||
26 | <% children = proc.children(recursive=True) %> |
|
|||
27 | % if children: |
|
|||
28 |
|
||||
29 | <tr> |
|
|||
30 | <td> |
|
|||
31 | <code> |
|
|||
32 | ${proc.pid} - ${get_name(proc)} |
|
|||
33 | </code> |
|
|||
34 | </td> |
|
|||
35 | <td> |
|
|||
36 | <a href="#showCommand" onclick="$('#pid'+${proc.pid}).toggle();return false"> command </a> |
|
|||
37 | <code id="pid${proc.pid}" style="display: none"> |
|
|||
38 | ${' '.join(proc.cmdline())} |
|
|||
39 | </code> |
|
|||
40 | </td> |
|
|||
41 | <td></td> |
|
|||
42 | <td> |
|
|||
43 | RSS:${h.format_byte_size_binary(mem.rss)} |
|
|||
44 | </td> |
|
|||
45 | <td> |
|
|||
46 | VMS:${h.format_byte_size_binary(mem.vms)} |
|
|||
47 | </td> |
|
|||
48 | <td> |
|
|||
49 | AGE: ${h.age_component(h.time_to_utcdatetime(proc.create_time()))} |
|
|||
50 | </td> |
|
|||
51 | <td> |
|
|||
52 | MASTER |
|
|||
53 | </td> |
|
|||
54 | </tr> |
|
|||
55 | <% mem_sum = 0 %> |
|
|||
56 | % for proc_child in children: |
|
|||
57 | <% mem = proc_child.memory_info()%> |
|
|||
58 | <tr> |
|
|||
59 | <td> |
|
|||
60 | <code> |
|
|||
61 | | ${proc_child.pid} - ${get_name(proc_child)} |
|
|||
62 | </code> |
|
|||
63 | </td> |
|
|||
64 | <td> |
|
|||
65 | <a href="#showCommand" onclick="$('#pid'+${proc_child.pid}).toggle();return false"> command </a> |
|
|||
66 | <code id="pid${proc_child.pid}" style="display: none"> |
|
|||
67 | ${' '.join(proc_child.cmdline())} |
|
|||
68 | </code> |
|
|||
69 | </td> |
|
|||
70 | <td> |
|
|||
71 | CPU: ${proc_child.cpu_percent()} % |
|
|||
72 | </td> |
|
|||
73 | <td> |
|
|||
74 | RSS:${h.format_byte_size_binary(mem.rss)} |
|
|||
75 | <% mem_sum += mem.rss %> |
|
|||
76 | </td> |
|
|||
77 | <td> |
|
|||
78 | VMS:${h.format_byte_size_binary(mem.vms)} |
|
|||
79 | </td> |
|
|||
80 | <td> |
|
|||
81 | AGE: ${h.age_component(h.time_to_utcdatetime(proc_child.create_time()))} |
|
|||
82 | </td> |
|
|||
83 | <td> |
|
|||
84 | <a href="#restartProcess" onclick="restart(this, ${proc_child.pid});return false"> |
|
|||
85 | restart |
|
|||
86 | </a> |
|
|||
87 | </td> |
|
|||
88 | </tr> |
|
|||
89 | % endfor |
|
|||
90 | <tr> |
|
|||
91 | <td colspan="2"><code>| total processes: ${len(children)}</code></td> |
|
|||
92 | <td></td> |
|
|||
93 | <td><strong>RSS:${h.format_byte_size_binary(mem_sum)}</strong></td> |
|
|||
94 | <td></td> |
|
|||
95 | </tr> |
|
|||
96 | <tr><td> <code> -- </code> </td></tr> |
|
|||
97 |
|
||||
98 | % endif |
|
|||
99 | % endfor |
|
|||
100 | </table> |
|
|||
101 | </div> |
|
27 | </div> | |
102 | </div> |
|
28 | </div> | |
103 |
|
29 | |||
104 |
|
||||
105 | <script> |
|
30 | <script> | |
106 |
|
31 | |||
107 |
|
32 | |||
@@ -135,7 +60,50 b' restart = function(elem, pid) {' | |||||
135 | $(elem).removeClass('disabled'); |
|
60 | $(elem).removeClass('disabled'); | |
136 | } |
|
61 | } | |
137 | }) |
|
62 | }) | |
138 | } |
|
63 | }; | |
|
64 | ||||
|
65 | var intervalID = null; | |||
|
66 | var currentRequest = null; | |||
|
67 | ||||
|
68 | autoRefresh = function(value) { | |||
|
69 | var url = pyroutes.url('admin_settings_process_management_data'); | |||
|
70 | var loadData = function() { | |||
|
71 | currentRequest = $.get(url) | |||
|
72 | .done(function(data) { | |||
|
73 | currentRequest = null; | |||
|
74 | $('#procList').html(data); | |||
|
75 | timeagoActivate(); | |||
|
76 | var beat = function(doCallback) { | |||
|
77 | var callback = function () {}; | |||
|
78 | if (doCallback){ | |||
|
79 | var callback = function () {beat(false)}; | |||
|
80 | } | |||
|
81 | $('#processTimeStamp').animate({ | |||
|
82 | opacity: $('#processTimeStamp').css('opacity') == '1' ? '0.3' : '1' | |||
|
83 | }, 500, callback); | |||
|
84 | }; | |||
|
85 | beat(true) | |||
|
86 | }); | |||
|
87 | }; | |||
|
88 | ||||
|
89 | if (value) { | |||
|
90 | intervalID = setInterval(loadData, 5000); | |||
|
91 | } else { | |||
|
92 | clearInterval(intervalID); | |||
|
93 | } | |||
|
94 | }; | |||
|
95 | ||||
|
96 | enableAutoRefresh = function() { | |||
|
97 | $('#autoRefreshEnable').hide(); | |||
|
98 | $('#autoRefreshDisable').show(); | |||
|
99 | autoRefresh(true) | |||
|
100 | }; | |||
|
101 | ||||
|
102 | disableAutoRefresh = function() { | |||
|
103 | $('#autoRefreshEnable').show(); | |||
|
104 | $('#autoRefreshDisable').hide(); | |||
|
105 | autoRefresh(false) | |||
|
106 | }; | |||
139 |
|
107 | |||
140 |
|
108 | |||
141 | </script> |
|
109 | </script> |
General Comments 0
You need to be logged in to leave comments.
Login now