1 |
sub statuspage { |
2 |
my ($self, $verbose) = @_; |
3 |
|
4 |
my $uptime = format_time ($::NOW - $::starttime); |
5 |
|
6 |
my $content = <<EOF; |
7 |
<html> |
8 |
<head><title>Server Status Page</title></head> |
9 |
<body bgcolor="#ffffff" text="#000000" link="#0000ff" vlink="#000080" alink="#ff0000"> |
10 |
<h1>Server Status Page</h1> |
11 |
<h2>Myhttpd</h2> |
12 |
version <b>$VERSION</b>; current:max connection count: <b>$::conns</b>:<b>$::maxconns</b>; uptime: <b>$uptime</b>;<br /> |
13 |
client-id <b>$self->{remote_id}</b>; client country <b>$self->{country}</b>;<br /> |
14 |
<h2>Queue Statistics</h2> |
15 |
<ul> |
16 |
EOF |
17 |
|
18 |
for ( |
19 |
["download queue", $queue_file], |
20 |
$verbose ? (["other queue", $queue_index]) |
21 |
: (), |
22 |
) { |
23 |
my ($name, $queue) = @$_; |
24 |
my @waiters = $queue->waiters; |
25 |
$waiters[$_]{idx} = $_ + 1 for 0..$#waiters; |
26 |
|
27 |
if (@waiters) { |
28 |
$content .= "<li>$name<br />".(scalar @waiters)." client(s); $queue->{started} downloads started; $queue->{slots} slots free;"; |
29 |
|
30 |
$content .= "<p>Waiting time until download starts, estimated:<ul>"; |
31 |
for ( |
32 |
["by queue average", $queue->{avgspb}], |
33 |
$verbose ? (["by most recently started transfer", $queue->{lastspb}], |
34 |
["by next client in queue", $waiters[0]{spb}]) |
35 |
: (), |
36 |
) { |
37 |
my ($by, $spb) = @$_; |
38 |
$content .= "<li>$by<br />"; |
39 |
if ($spb) { |
40 |
$content .= sprintf "100 KB file: <b>%s</b>; 1 MB file: <b>%s</b>; 100MB file: <b>%s</b>;", |
41 |
format_time($spb* 100_000), |
42 |
format_time($spb* 1_000_000), |
43 |
format_time($spb*100_000_000); |
44 |
} else { |
45 |
$content .= "(unavailable)"; |
46 |
} |
47 |
$content .= "</li>"; |
48 |
} |
49 |
$content .= "</ul></p>"; |
50 |
|
51 |
@waiters = grep { $verbose || $_->{coro}{conn}{remote_id} eq $self->{remote_id} } @waiters; |
52 |
if (@waiters) { |
53 |
$content .= "<table border='1' width='100%'><tr><th>#</th><th>CN</th>". |
54 |
"<th>Remote ID</th><th>Size</th><th>Waiting</th><th>ETA</th><th>URI</th></tr>"; |
55 |
for (@waiters) { |
56 |
my $conn = $_->{coro}{conn}; |
57 |
my $time = format_time ($::NOW - $_->{time}); |
58 |
my $eta = $queue->{avgspb} * $_->{size} - ($::NOW - $_->{time}); |
59 |
|
60 |
$content .= "<tr>". |
61 |
"<td align='right'>$_->{idx}</td>". |
62 |
"<td>$conn->{country}</td>". |
63 |
"<td>$conn->{remote_id}</td>". |
64 |
"<td align='right'>$_->{size}</td>". |
65 |
"<td align='right'>$time</td>". |
66 |
"<td align='right'>".($eta < 0 ? "<font color='red'>overdue</font>" : format_time $eta)."</td>". |
67 |
"<td>".escape_html($conn->{name})."</td>". |
68 |
"</tr>"; |
69 |
} |
70 |
$content .= "</table></li>"; |
71 |
} |
72 |
$content .= "</li>"; |
73 |
} else { |
74 |
$content .= "<li>$name<br />(empty)</li>"; |
75 |
} |
76 |
} |
77 |
|
78 |
$content .= <<EOF; |
79 |
</ul> |
80 |
<h2>Active Downloads</h2> |
81 |
<ul> |
82 |
EOF |
83 |
|
84 |
my @data; |
85 |
my $count = 0; |
86 |
my $fullrate = 0; |
87 |
|
88 |
for (values %conn::conn) { |
89 |
for (values %$_) { |
90 |
next unless $_; |
91 |
$count++; |
92 |
my $rate = sprintf "%.1f", $_->{written} / (($::NOW - $_->{time}) || 1e999); |
93 |
$fullrate += $rate; |
94 |
|
95 |
next unless $verbose || $_->{remote_id} eq $self->{remote_id}; |
96 |
|
97 |
push @data, "<tr><td>$_->{country}</td><td>$_->{remote_id}</td><td align='right'>$_->{written}</td><td align='right'>$rate</td><td>$_->{method}</td><td>$_->{uri}</td></tr>"; |
98 |
} |
99 |
} |
100 |
|
101 |
if (@data) { |
102 |
$content .= "<table width='100%' border='1'><tr><th>CN</th><th>Remote ID</th><th>bytes written</th><th>bps</th><th>RM</th><th>URI</th></tr>" |
103 |
. (join "", sort @data) |
104 |
. "</table>"; |
105 |
} |
106 |
|
107 |
$content .= "<p>$count active downloads, $fullrate bytes/s amortized.</p>"; |
108 |
|
109 |
$content .= <<EOF; |
110 |
</ul> |
111 |
</body> |
112 |
</html> |
113 |
EOF |
114 |
|
115 |
$self->response(200, "ok", |
116 |
{ |
117 |
"Content-Type" => "text/html", |
118 |
"Content-Length" => length $content, |
119 |
}, |
120 |
$content); |
121 |
}; |
122 |
|
123 |
$::internal{status} = sub { statuspage($_[0], 0) }; |
124 |
$::internal{queue} = sub { statuspage($_[0], 1) }; |
125 |
|
126 |
1; |
127 |
|