~ubuntu-branches/ubuntu/precise/boinc/precise

« back to all changes in this revision

Viewing changes to html/user/server_status.php

Tags: 6.12.8+dfsg-1
* New upstream release.
* Simplified debian/rules

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
<?php
 
2
// This file is part of BOINC.
 
3
// http://boinc.berkeley.edu
 
4
// Copyright (C) 2008 University of California
 
5
//
 
6
// BOINC is free software; you can redistribute it and/or modify it
 
7
// under the terms of the GNU Lesser General Public License
 
8
// as published by the Free Software Foundation,
 
9
// either version 3 of the License, or (at your option) any later version.
 
10
//
 
11
// BOINC is distributed in the hope that it will be useful,
 
12
// but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
14
// See the GNU Lesser General Public License for more details.
 
15
//
 
16
// You should have received a copy of the GNU Lesser General Public License
 
17
// along with BOINC.  If not, see <http://www.gnu.org/licenses/>.
 
18
 
 
19
// server_status.php 
 
20
//   (or server_status.php?xml=1)
 
21
//
 
22
// outputs general information about BOINC server status gathered from
 
23
// config.xml or mysql database queries. If you are running all your
 
24
// services on one machine, and the database isn't so large, this should
 
25
// work right out of the box. Otherwise see configureables below.
 
26
//
 
27
// Daemons in config.xml are checked to see if they are running by ssh'ing
 
28
// into the respective hosts and searching for active pids. Passwordless
 
29
// logins must be in effect if there are multiple hosts involved.
 
30
//
 
31
// The database queries may be very slow. You might consider running these
 
32
// queries elsewhere via cronjob, outputing numbers into a readable file,
 
33
// and then getting the latest values with a `/bin/tail -1 data_file`.
 
34
// See commented example in the code.
 
35
//
 
36
// You can get an xml version of the stats via the web when the url has the
 
37
// optional "?xml=1" tag at the end, i.e 
 
38
//   http://yourboincproject.edu/server_status.php?xml=1
 
39
//
 
40
// You should edit the following variables in config.xml to suit your needs:
 
41
//
 
42
// <www_host>    hostname of web server (default: same as <host>)
 
43
// <sched_host>  hostname of scheduling server (default: same as <host>)
 
44
// <uldl_host>   hostname of upload/download server (default: same as <host>)
 
45
// <uldl_pid>    pid file of upload/download server httpd.conf
 
46
//               (default: /etc/httpd/run/httpd.pid)
 
47
// <ssh_exe>     path to ssh (default: /usr/bin/ssh)
 
48
// <ps_exe>      path to ps (which supports "w" flag) (default: /bin/ps)
 
49
 
 
50
///////////////////////////////////////////////////////////////////////////////
 
51
 
 
52
require_once("../inc/util.inc");
 
53
require_once("../inc/xml.inc");
 
54
require_once("../inc/cache.inc");
 
55
require_once("../inc/translation.inc");
 
56
 
 
57
$xml = get_int("xml", true);
 
58
 
 
59
$cache_args = $languages_in_use[0];
 
60
if ($xml) $cache_args = "xml=1";
 
61
$cache_period = 3600;
 
62
start_cache($cache_period, $cache_args);
 
63
 
 
64
// daemon status outputs: 1 (running) 0 (not running) or -1 (disabled)
 
65
//
 
66
function daemon_status($host, $pidname, $progname, $disabled) {
 
67
    global $ssh_exe, $ps_exe, $project_host;
 
68
    $path = "../../pid_$host/$pidname.pid";
 
69
    $running = 0;
 
70
    if (is_file($path)) {
 
71
        $pid = file_get_contents($path);
 
72
        if ($pid) {
 
73
            $pid = trim($pid);
 
74
            $command = "$ps_exe ww $pid";
 
75
            if ($host != $project_host) {
 
76
                $command = "$ssh_exe $host " . $command;
 
77
            }
 
78
            $foo = exec($command);
 
79
            if ($foo) {
 
80
                if (strstr($foo, (string)$pid)) $running = 1;
 
81
            }
 
82
        }
 
83
    }
 
84
    if ($disabled == 1) $running = -1;
 
85
    return $running;
 
86
}
 
87
 
 
88
function show_status($host, $function, $running) {
 
89
    global $xml;
 
90
    $xmlstring = "    <daemon>\n      <host>$host</host>\n      <command>$function</command>\n";
 
91
    $htmlstring = "<tr><td>$function</td><td>$host</td>";
 
92
    if ($running == 1) {
 
93
        $xmlstring .= "      <status>running</status>\n";
 
94
        $htmlstring .= "<td class=\"running\">".tra("Running")."</td>\n";
 
95
    } elseif ($running == 0) {
 
96
        $xmlstring .= "      <status>not running</status>\n";
 
97
        $htmlstring .= "<td class=\"notrunning\">".tra("Not Running")."</td>\n";
 
98
    } else {
 
99
        $xmlstring .= "      <status>disabled</status>\n";
 
100
        $htmlstring .= "<td class=\"disabled\">".tra("Disabled")."</td>\n";
 
101
    }
 
102
    $xmlstring .= "    </daemon>\n";
 
103
    $htmlstring .= "</tr>\n";
 
104
    if ($xml) {
 
105
        echo $xmlstring;
 
106
    } else {
 
107
        echo $htmlstring;
 
108
    }
 
109
    return 0;
 
110
}
 
111
 
 
112
function show_daemon_status($host, $pidname, $progname, $disabled) {
 
113
    $running = daemon_status($host, $pidname, $progname, $disabled);
 
114
    show_status($host, $pidname, $running);
 
115
}
 
116
 
 
117
function show_counts($key, $xmlkey, $value) {
 
118
    global $xml;
 
119
    $formattedvalue = number_format($value);
 
120
    $xmlstring = "    <$xmlkey>$value</$xmlkey>\n";
 
121
    if ($xml) {
 
122
        echo $xmlstring;
 
123
    } else {
 
124
        echo "<tr><td>$key</td><td>$formattedvalue</td></tr>";
 
125
    }
 
126
    return 0;
 
127
}
 
128
 
 
129
function get_mysql_count ($query) {
 
130
    $result = mysql_query("select count(*) as count from " . $query);
 
131
    $count = mysql_fetch_object($result);
 
132
    mysql_free_result($result);
 
133
    return $count->count;
 
134
}
 
135
 
 
136
function get_mysql_value ($query) {
 
137
    $result = mysql_query($query);
 
138
    $row = mysql_fetch_object($result);
 
139
    mysql_free_result($result);
 
140
    return $row->value;
 
141
}
 
142
 
 
143
function get_mysql_assoc($query) {
 
144
    $sql = "SELECT * FROM app WHERE deprecated != 1";
 
145
    $result = mysql_query($sql);
 
146
    while($row = mysql_fetch_assoc($result)) {
 
147
        $assoc[] = $row;
 
148
    }
 
149
    mysql_free_result($result);
 
150
    return $assoc;
 
151
}
 
152
 
 
153
function get_mysql_user ($clause) {
 
154
    $result = mysql_query("select count(userid) as userid from (SELECT distinct userid FROM result where validate_state=1 and received_time > (unix_timestamp()-(3600*24*1)) " . $clause . ") t");
 
155
    $count = mysql_fetch_object($result);
 
156
    mysql_free_result($result);
 
157
    return $count->userid;
 
158
}
 
159
 
 
160
function get_cpu_time ($appid) {
 
161
    $result = mysql_query("
 
162
        Select ceil(avg(cpu_time)/3600*100)/100 as cpu_time, 
 
163
                ceil(min(cpu_time)/3600*100)/100 as min, 
 
164
                ceil(max(cpu_time)/3600*100)/100 as max 
 
165
        from (SELECT cpu_time FROM `result` WHERE appid = $appid and validate_state =1 and received_time > (unix_timestamp()-(3600*24)) ORDER BY `received_time` DESC limit 100) t");
 
166
    $count = mysql_fetch_object($result);
 
167
    mysql_free_result($result);
 
168
    return $count;
 
169
}
 
170
 
 
171
$config_xml = get_config();
 
172
$config_vars = parse_element($config_xml,"<config>");
 
173
$project_host = parse_element($config_vars,"<host>");
 
174
$www_host = parse_element($config_vars,"<www_host>");
 
175
if ($www_host == "") {
 
176
    $www_host = $project_host;
 
177
}
 
178
$sched_host = parse_element($config_vars,"<sched_host>");
 
179
if ($sched_host == "") {
 
180
    $sched_host = $project_host;
 
181
}
 
182
$uldl_pid = parse_element($config_vars,"<uldl_pid>");
 
183
if ($uldl_pid == "") {
 
184
    $uldl_pid = "/etc/httpd/run/httpd.pid";
 
185
}
 
186
$uldl_host = parse_element($config_vars,"<uldl_host>");
 
187
if ($uldl_host == "") {
 
188
    $uldl_host = $project_host;
 
189
}
 
190
$ssh_exe = parse_element($config_vars,"<ssh_exe>");
 
191
if ($ssh_exe == "") {
 
192
    $ssh_exe = "/usr/bin/ssh";
 
193
 
194
$ps_exe = parse_element($config_vars,"<ps_exe>");
 
195
if ($ps_exe == "") {
 
196
    $ps_exe = "/bin/ps";
 
197
}
 
198
 
 
199
$version = null;
 
200
if (file_exists("../../local.revision")) {
 
201
    $version = trim(file_get_contents("../../local.revision"));
 
202
}
 
203
$now = time();
 
204
 
 
205
$xmlstring = "<server_status>
 
206
  <update_time>$now</update_time>
 
207
";
 
208
if ($version) {
 
209
    $xmlstring .= "<software_version>$version</software_version>\n";
 
210
}
 
211
$xmlstring .= "  <daemon_status>\n";
 
212
if ($xml) {
 
213
    xml_header();
 
214
    echo $xmlstring;
 
215
} else {
 
216
    page_head(tra("Project status"));
 
217
    if ($version) {
 
218
        echo tra("Server software version: %1", $version) . " / ";
 
219
    }
 
220
    echo time_str(time()), "
 
221
        <table width=100%>
 
222
        <tr>
 
223
        <td width=40% valign=top>
 
224
        <h2>".tra("Server status")."</h2>
 
225
        <table border=0 cellpadding=4>
 
226
        <tr><th>".tra("Program")."</th><th>".tra("Host")."</th><th>".tra("Status")."</th></tr>
 
227
    ";
 
228
}
 
229
;
 
230
// Are the data-driven web sites running? Check for existence of stop_web.
 
231
// If it is there, set $web_running to -1 for "disabled",
 
232
// otherwise it will be already set to 1 for "enabled."
 
233
// Set $www_host to the name of server hosting WWW site.
 
234
//
 
235
$web_running = !file_exists("../../stop_web");
 
236
if ($web_running == 0) $web_running = -1;
 
237
show_status($www_host, tra("data-driven web pages"), $web_running);
 
238
 
 
239
// Check for httpd.pid file of upload/download server.
 
240
//
 
241
$uldl_running = file_exists($uldl_pid);
 
242
if ($uldl_running == 0) $uldl_running = -1;
 
243
show_status($uldl_host, tra("upload/download server"), $uldl_running);
 
244
 
 
245
$sched_running = !file_exists("../../stop_sched");
 
246
show_status($sched_host, tra("scheduler"), $sched_running);
 
247
 
 
248
// parse through config.xml to get all daemons running
 
249
//
 
250
$cursor = 0;
 
251
while ($thisxml = trim(parse_next_element($config_xml,"<daemon>",$cursor))) {
 
252
    $host = parse_element($thisxml,"<host>");
 
253
    if ($host == "") {
 
254
        $host = $project_host;
 
255
    }
 
256
    $cmd = parse_element($thisxml,"<cmd>");
 
257
    list($ncmd) = explode(" ",$cmd);
 
258
    $log = parse_element($thisxml,"<output>");
 
259
    if (!$log) {
 
260
        $log = $ncmd . ".log";
 
261
    }
 
262
    list($nlog) = explode(".log",$log);
 
263
    $pid = parse_element($thisxml,"<pid_file>");
 
264
    if (!$pid) {
 
265
        $pid = $ncmd . ".pid";
 
266
    }
 
267
    $disabled = parse_element($thisxml,"<disabled>");
 
268
    show_daemon_status($host, $nlog, $ncmd, $disabled);
 
269
}
 
270
 
 
271
$xmlstring = "  </daemon_status>\n  <database_file_states>\n";
 
272
if ($xml) {
 
273
    echo $xmlstring;
 
274
} else {
 
275
    echo "
 
276
        <tr><td align=right><b>".tra("Running:")."</b></td>
 
277
        <td colspan=2>".tra("Program is operating normally")."</td></tr>
 
278
        <tr><td align=right><b>".tra("Not Running:")."</b></td>
 
279
        <td colspan=2>".tra("Program failed or the project is down")."</td></tr>
 
280
        <tr><td align=right><b>".tra("Disabled:")."</b></td>
 
281
        <td colspan=2>".tra("Program is disabled")."</td></tr>
 
282
        </table>
 
283
        </td>
 
284
        <td valign=top>
 
285
        <h2>".tra("Computing status")."</h2>
 
286
    ";
 
287
}
 
288
 
 
289
$retval = db_init_aux();
 
290
if ($retval) {
 
291
    echo tra("The database server is not accessible");
 
292
} else {
 
293
    if (!$xml) {
 
294
        echo "<table border=0 cellpadding=0 cellspacing=0><tr><td>
 
295
            <table border=0 cellpadding=4>
 
296
            <tr><th>".tra("Work")."</th><th>#</th></tr>
 
297
        ";
 
298
    }
 
299
 
 
300
    // If you are reading these values from a file rather than
 
301
    // making live queries to the database, do something like this:
 
302
    //
 
303
    // $sendfile = "/home/boincadm/server_status_data/count_results_unsent.out";
 
304
    // $n = `/bin/tail -1 $sendfile`;
 
305
    // show_counts("Tasks ready to send","results_ready_to_send",$n);
 
306
 
 
307
    show_counts(
 
308
        tra("Tasks ready to send"),
 
309
        "results_ready_to_send",
 
310
        get_mysql_count("result where server_state = 2")
 
311
    );
 
312
    show_counts(
 
313
        tra("Tasks in progress"),
 
314
        "results_in_progress",
 
315
        get_mysql_count("result where server_state = 4")
 
316
    );
 
317
    show_counts(
 
318
        tra("Workunits waiting for validation"),
 
319
        "workunits_waiting_for_validation",
 
320
        get_mysql_count("workunit where need_validate=1")
 
321
    );
 
322
    show_counts(
 
323
        tra("Workunits waiting for assimilation"),
 
324
        "workunits_waiting_for_assimilation",
 
325
        get_mysql_count("workunit where assimilate_state=1")
 
326
    );
 
327
    show_counts(
 
328
        tra("Workunits waiting for file deletion"),
 
329
        "workunits_waiting_for_deletion",
 
330
        get_mysql_count("workunit where file_delete_state=1")
 
331
    );
 
332
    show_counts(
 
333
        tra("Tasks waiting for file deletion"),
 
334
        "results_waiting_for_deletion",
 
335
        get_mysql_count("result where file_delete_state=1")
 
336
    );
 
337
 
 
338
    $result = mysql_query("select MIN(transition_time) as min from workunit");
 
339
    $min = mysql_fetch_object($result);
 
340
    mysql_free_result($result);
 
341
    $gap = (time() - $min->min)/3600;
 
342
    if (($gap < 0) || ($min->min == 0)) {
 
343
        $gap = 0;
 
344
    }
 
345
    show_counts(
 
346
        tra("Transitioner backlog (hours)"),
 
347
        "transitioner_backlog_hours",
 
348
        $gap
 
349
    );
 
350
    if (!$xml) {
 
351
        echo "</table></td><td>";
 
352
        echo "<table>";
 
353
        echo "<tr><th>".tra("Users")."</th><th>#</th></tr>";
 
354
        show_counts(
 
355
                tra("with recent credit"),
 
356
                "users_with_recent_credit",
 
357
                get_mysql_count("user where expavg_credit>1")
 
358
        );
 
359
        show_counts(
 
360
                tra("with credit"),
 
361
                "users_with_credit",
 
362
                get_mysql_count("user where total_credit>0")
 
363
        );
 
364
        show_counts(
 
365
                tra("registered in past 24 hours"),
 
366
                "users_registered_in_past_24_hours",
 
367
                get_mysql_count("user where create_time > (unix_timestamp() - (24*3600))")
 
368
        );
 
369
        echo "<tr><th>".tra("Computers")."</th><th>#</th></tr>";
 
370
        show_counts(
 
371
                tra("with recent credit"),
 
372
                "hosts_with_recent_credit",
 
373
                get_mysql_count("host where expavg_credit>1")
 
374
        );
 
375
        show_counts(
 
376
                tra("with credit"),
 
377
                "hosts_with_credit",
 
378
                get_mysql_count("host where total_credit>0")
 
379
        );
 
380
        show_counts(
 
381
                tra("registered in past 24 hours"),
 
382
                "hosts_registered_in_past_24_hours",
 
383
                get_mysql_count("host where create_time > (unix_timestamp() - (24*3600))")
 
384
        );
 
385
        // 100,000 cobblestones = 1 TeraFLOPS 
 
386
        // divide by 2, because double credits
 
387
        show_counts(
 
388
                tra("current GigaFLOPs"),
 
389
                "current_floating_point_speed",
 
390
                get_mysql_value("SELECT sum(expavg_credit)/200 as value FROM user")
 
391
        );
 
392
 
 
393
        end_table();
 
394
        echo "</td></tr></table>";
 
395
 
 
396
        start_table();
 
397
        echo "<tr><th colspan=5>".tra("Tasks by application")."</th></tr>";
 
398
        row_heading_array(array(tra("application"),tra("unsent"),tra("in progress"),tra("avg runtime of last 100 results in h (min-max)"),tra("users in last 24h")));
 
399
        $apps = get_mysql_assoc("SELECT * FROM app WHERE deprecated != 1");
 
400
        foreach($apps as $app) {
 
401
            $appid = $app["id"];
 
402
            $uf_name = $app["user_friendly_name"];
 
403
            echo "<tr><td>$uf_name</td>
 
404
                    <td>" . number_format(get_mysql_count("result where server_state = 2 and appid = $appid")) . "</td>
 
405
                    <td>" . number_format(get_mysql_count("result where server_state = 4 and appid = $appid")) . "</td>
 
406
                    <td>";
 
407
            $count = get_cpu_time($appid);
 
408
            echo number_format($count->cpu_time,2) . " (" . number_format($count->min,2) . " - " . number_format($count->max,2) . ")";
 
409
            echo "</td>
 
410
                    <td>" . number_format(get_mysql_user("and appid = $appid")) . "</td>
 
411
                </tr>";
 
412
        }
 
413
        end_table();
 
414
        
 
415
    }
 
416
}
 
417
 
 
418
$xmlstring = "  </database_file_states>\n</server_status>\n";
 
419
if ($xml) {
 
420
    echo $xmlstring;
 
421
} else {
 
422
    echo "
 
423
        </td>
 
424
        </tr>
 
425
        </table>
 
426
    ";
 
427
    page_tail();
 
428
}
 
429
 
 
430
end_cache($cache_period, $cache_args);
 
431
?>