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 | 70 | name='admin_settings_process_management', |
|
71 | 71 | pattern='/settings/process_management') |
|
72 | 72 | config.add_route( |
|
73 | name='admin_settings_process_management_data', | |
|
74 | pattern='/settings/process_management/data') | |
|
75 | config.add_route( | |
|
73 | 76 | name='admin_settings_process_management_signal', |
|
74 | 77 | pattern='/settings/process_management/signal') |
|
75 | 78 |
@@ -55,6 +55,18 b' class AdminProcessManagementView(BaseApp' | |||
|
55 | 55 | |
|
56 | 56 | @LoginRequired() |
|
57 | 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 | 70 | @CSRFRequired() |
|
59 | 71 | @view_config( |
|
60 | 72 | route_name='admin_settings_process_management_signal', |
@@ -48,6 +48,7 b' function registerRCRoutes() {' | |||
|
48 | 48 | pyroutes.register('admin_settings_sessions', '/_admin/settings/sessions', []); |
|
49 | 49 | pyroutes.register('admin_settings_sessions_cleanup', '/_admin/settings/sessions/cleanup', []); |
|
50 | 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 | 52 | pyroutes.register('admin_settings_process_management_signal', '/_admin/settings/process_management/signal', []); |
|
52 | 53 | pyroutes.register('admin_defaults_repositories', '/_admin/defaults/repositories', []); |
|
53 | 54 | pyroutes.register('admin_defaults_repositories_update', '/_admin/defaults/repositories/update', []); |
@@ -283,6 +284,7 b' function registerRCRoutes() {' | |||
|
283 | 284 | pyroutes.register('my_account_ssh_keys_generate', '/_admin/my_account/ssh_keys/generate', []); |
|
284 | 285 | pyroutes.register('my_account_ssh_keys_add', '/_admin/my_account/ssh_keys/new', []); |
|
285 | 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 | 288 | pyroutes.register('my_account_emails', '/_admin/my_account/emails', []); |
|
287 | 289 | pyroutes.register('my_account_emails_add', '/_admin/my_account/emails/new', []); |
|
288 | 290 | pyroutes.register('my_account_emails_delete', '/_admin/my_account/emails/delete', []); |
@@ -7,7 +7,10 b'' | |||
|
7 | 7 | <div class="panel panel-default"> |
|
8 | 8 | <div class="panel-heading"> |
|
9 | 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 | 14 | </div> |
|
12 | 15 | <div class="panel-body" id="app"> |
|
13 | 16 | <h3>List of Gunicorn processes on this machine</h3> |
@@ -20,88 +23,10 b'' | |||
|
20 | 23 | return 'RhodeCode' |
|
21 | 24 | return proc.name() |
|
22 | 25 | %> |
|
23 | <table> | |
|
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> | |
|
26 | <%include file='settings_process_management_data.mako'/> | |
|
101 | 27 | </div> |
|
102 | 28 | </div> |
|
103 | 29 | |
|
104 | ||
|
105 | 30 | <script> |
|
106 | 31 | |
|
107 | 32 | |
@@ -135,7 +60,50 b' restart = function(elem, pid) {' | |||
|
135 | 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 | 109 | </script> |
General Comments 0
You need to be logged in to leave comments.
Login now