line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Mojolicious::Plugin::Status; |
2
|
1
|
|
|
1
|
|
1335
|
use Mojo::Base 'Mojolicious::Plugin'; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
9
|
|
3
|
|
|
|
|
|
|
|
4
|
1
|
|
|
1
|
|
916
|
use BSD::Resource qw(getrusage); |
|
1
|
|
|
|
|
2216
|
|
|
1
|
|
|
|
|
6
|
|
5
|
1
|
|
|
1
|
|
113
|
use Time::HiRes qw(time); |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
8
|
|
6
|
1
|
|
|
1
|
|
131
|
use Mojo::File qw(path); |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
46
|
|
7
|
1
|
|
|
1
|
|
5
|
use Mojo::IOLoop; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
12
|
|
8
|
1
|
|
|
1
|
|
502
|
use Mojo::MemoryMap; |
|
1
|
|
|
|
|
5
|
|
|
1
|
|
|
|
|
12
|
|
9
|
1
|
|
|
1
|
|
41
|
use Mojo::Util qw(humanize_bytes); |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
64
|
|
10
|
|
|
|
|
|
|
|
11
|
1
|
|
|
1
|
|
6
|
use constant MACOS => $^O eq 'darwin'; |
|
1
|
|
|
|
|
4
|
|
|
1
|
|
|
|
|
3537
|
|
12
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
our $VERSION = '1.17'; |
14
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
sub register { |
16
|
1
|
|
|
1
|
1
|
56
|
my ($self, $app, $config) = @_; |
17
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
# Config |
19
|
1
|
|
33
|
|
|
6
|
my $prefix = $config->{route} // $app->routes->any('/mojo-status'); |
20
|
1
|
|
50
|
|
|
9
|
$prefix->to(return_to => $config->{return_to} // '/'); |
21
|
1
|
|
50
|
|
|
49
|
$self->{slowest} = $config->{slowest} // 10; |
22
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
# Initialize cache |
24
|
1
|
|
|
|
|
5
|
my $map = $self->{map} = Mojo::MemoryMap->new($config->{size}); |
25
|
1
|
|
|
|
|
11
|
$map->writer->store({processed => 0, started => time, stats => _stats(), slowest => []}); |
26
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
# Only the two built-in servers are supported for now |
28
|
1
|
|
|
2
|
|
9
|
$app->hook(before_server_start => sub { $self->_start(@_) }); |
|
2
|
|
|
|
|
7475
|
|
29
|
|
|
|
|
|
|
|
30
|
|
|
|
|
|
|
# Static files |
31
|
1
|
|
|
|
|
50
|
my $resources = path(__FILE__)->sibling('resources'); |
32
|
1
|
|
|
|
|
211
|
push @{$app->static->paths}, $resources->child('public')->to_string; |
|
1
|
|
|
|
|
10
|
|
33
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
# Templates |
35
|
1
|
|
|
|
|
78
|
push @{$app->renderer->paths}, $resources->child('templates')->to_string; |
|
1
|
|
|
|
|
8
|
|
36
|
|
|
|
|
|
|
|
37
|
|
|
|
|
|
|
# Routes |
38
|
1
|
|
|
|
|
62
|
$prefix->get('/' => => [format => ['json']] => {format => undef, mojo_status => $self} => \&_dashboard) |
39
|
|
|
|
|
|
|
->name('mojo_status'); |
40
|
|
|
|
|
|
|
} |
41
|
|
|
|
|
|
|
|
42
|
|
|
|
|
|
|
sub _activity { |
43
|
2
|
|
|
2
|
|
53
|
my $all = shift; |
44
|
|
|
|
|
|
|
|
45
|
|
|
|
|
|
|
# Workers |
46
|
2
|
|
|
|
|
6
|
my @table; |
47
|
2
|
|
|
|
|
6
|
for my $pid (sort keys %{$all->{workers}}) { |
|
2
|
|
|
|
|
19
|
|
48
|
2
|
|
|
|
|
10
|
my $worker = $all->{workers}{$pid}; |
49
|
2
|
|
|
|
|
49
|
my $cpu = sprintf '%.2f', $worker->{utime} + $worker->{stime}; |
50
|
2
|
|
|
|
|
9
|
my @worker = ($pid, $cpu, humanize_bytes($worker->{maxrss})); |
51
|
|
|
|
|
|
|
|
52
|
|
|
|
|
|
|
# Connections |
53
|
2
|
|
|
|
|
32
|
my $connections = $worker->{connections}; |
54
|
2
|
50
|
|
|
|
13
|
if (keys %$connections) { |
55
|
2
|
|
|
|
|
5
|
my $repeat; |
56
|
2
|
|
|
|
|
11
|
for my $cid (sort keys %$connections) { |
57
|
2
|
|
|
|
|
4
|
my $conn = $connections->{$cid}; |
58
|
2
|
50
|
|
|
|
14
|
@worker = ('', '', '') if $repeat++; |
59
|
2
|
|
|
|
|
7
|
my $bytes_read = humanize_bytes $conn->{bytes_read}; |
60
|
2
|
|
|
|
|
40
|
my $bytes_written = humanize_bytes $conn->{bytes_written}; |
61
|
2
|
|
|
|
|
30
|
my $rw = "$bytes_read/$bytes_written"; |
62
|
2
|
|
|
|
|
21
|
my @conn = ($conn->{client}, $rw, $conn->{processed}); |
63
|
|
|
|
|
|
|
|
64
|
|
|
|
|
|
|
# Request |
65
|
2
|
50
|
|
|
|
10
|
if (my $req = $conn->{request}) { |
66
|
2
|
50
|
|
|
|
11
|
my $active = $req->{finished} ? 0 : 1; |
67
|
2
|
|
|
|
|
4
|
my ($rid, $proto) = @{$req}{qw(request_id protocol)}; |
|
2
|
|
|
|
|
9
|
|
68
|
|
|
|
|
|
|
|
69
|
2
|
|
|
|
|
7
|
my $str = "$req->{method} $req->{path}"; |
70
|
2
|
100
|
|
|
|
10
|
$str .= "?$req->{query}" if $req->{query}; |
71
|
2
|
50
|
|
|
|
10
|
$str .= " → $req->{status}" if $req->{status}; |
72
|
|
|
|
|
|
|
|
73
|
2
|
50
|
|
|
|
23
|
my $finished = $active ? time : $req->{finished}; |
74
|
2
|
|
|
|
|
19
|
my $time = sprintf '%.2f', $finished - $req->{started}; |
75
|
2
|
|
|
|
|
19
|
push @table, [@worker, @conn, $rid, $active, $time, $proto, $str]; |
76
|
|
|
|
|
|
|
} |
77
|
0
|
|
|
|
|
0
|
else { push @table, [@worker, @conn] } |
78
|
|
|
|
|
|
|
} |
79
|
|
|
|
|
|
|
} |
80
|
0
|
|
|
|
|
0
|
else { push @table, \@worker } |
81
|
|
|
|
|
|
|
} |
82
|
|
|
|
|
|
|
|
83
|
2
|
|
|
|
|
10
|
return \@table; |
84
|
|
|
|
|
|
|
} |
85
|
|
|
|
|
|
|
|
86
|
|
|
|
|
|
|
sub _dashboard { |
87
|
9
|
|
|
9
|
|
15778
|
my $c = shift; |
88
|
|
|
|
|
|
|
|
89
|
9
|
|
|
|
|
35
|
my $map = $c->stash('mojo_status')->{map}; |
90
|
9
|
100
|
|
|
|
140
|
if ($c->param('reset')) { |
91
|
1
|
|
|
1
|
|
341
|
$map->writer->change(sub { @{$_}{qw(slowest stats)} = ([], _stats()) }); |
|
1
|
|
|
|
|
7
|
|
|
1
|
|
|
|
|
10
|
|
92
|
1
|
|
|
|
|
8
|
return $c->redirect_to('mojo_status'); |
93
|
|
|
|
|
|
|
} |
94
|
|
|
|
|
|
|
|
95
|
8
|
|
|
|
|
2361
|
my $all = $map->writer->fetch; |
96
|
|
|
|
|
|
|
$c->respond_to( |
97
|
|
|
|
|
|
|
html => sub { |
98
|
2
|
|
|
2
|
|
1090
|
$c->render( |
99
|
|
|
|
|
|
|
'mojo-status/dashboard', |
100
|
|
|
|
|
|
|
now => time, |
101
|
|
|
|
|
|
|
usage => humanize_bytes($map->usage), |
102
|
|
|
|
|
|
|
size => humanize_bytes($map->size), |
103
|
|
|
|
|
|
|
activity => _activity($all), |
104
|
|
|
|
|
|
|
slowest => _slowest($all), |
105
|
|
|
|
|
|
|
all => $all |
106
|
|
|
|
|
|
|
); |
107
|
|
|
|
|
|
|
}, |
108
|
8
|
|
|
|
|
47
|
json => {json => $all} |
109
|
|
|
|
|
|
|
); |
110
|
|
|
|
|
|
|
} |
111
|
|
|
|
|
|
|
|
112
|
|
|
|
|
|
|
sub _read_write { |
113
|
64
|
|
|
64
|
|
161
|
my ($all, $id) = @_; |
114
|
64
|
50
|
|
|
|
393
|
return unless my $stream = Mojo::IOLoop->stream($id); |
115
|
64
|
|
|
|
|
1290
|
@{$all->{workers}{$$}{connections}{$id}}{qw(bytes_read bytes_written)} |
|
64
|
|
|
|
|
623
|
|
116
|
|
|
|
|
|
|
= ($stream->bytes_read, $stream->bytes_written); |
117
|
|
|
|
|
|
|
} |
118
|
|
|
|
|
|
|
|
119
|
|
|
|
|
|
|
sub _request { |
120
|
64
|
|
|
64
|
|
152
|
my ($self, $c) = @_; |
121
|
|
|
|
|
|
|
|
122
|
|
|
|
|
|
|
# Request start |
123
|
64
|
|
|
|
|
184
|
my $tx = $c->tx; |
124
|
64
|
|
|
|
|
369
|
my $id = $tx->connection; |
125
|
64
|
|
|
|
|
482
|
my $req = $tx->req; |
126
|
64
|
|
|
|
|
388
|
my $url = $req->url->to_abs; |
127
|
64
|
50
|
|
|
|
12610
|
my $proto = $tx->is_websocket ? 'ws' : 'http'; |
128
|
64
|
50
|
|
|
|
405
|
$proto .= 's' if $req->is_secure; |
129
|
|
|
|
|
|
|
$self->{map}->writer->change(sub { |
130
|
|
|
|
|
|
|
$_->{workers}{$$}{connections}{$id}{request} = { |
131
|
64
|
|
|
64
|
|
275
|
request_id => $req->request_id, |
132
|
|
|
|
|
|
|
method => $req->method, |
133
|
|
|
|
|
|
|
protocol => $proto, |
134
|
|
|
|
|
|
|
path => $url->path->to_abs_string, |
135
|
|
|
|
|
|
|
query => $url->query->to_string, |
136
|
|
|
|
|
|
|
started => time |
137
|
|
|
|
|
|
|
}; |
138
|
64
|
|
|
|
|
14389
|
_read_write($_, $id); |
139
|
64
|
|
|
|
|
243
|
$_->{workers}{$$}{connections}{$id}{client} = $tx->remote_address; |
140
|
64
|
|
|
|
|
1674
|
}); |
141
|
|
|
|
|
|
|
|
142
|
|
|
|
|
|
|
# Request end |
143
|
|
|
|
|
|
|
$tx->on( |
144
|
|
|
|
|
|
|
finish => sub { |
145
|
64
|
|
|
64
|
|
126800
|
my $tx = shift; |
146
|
|
|
|
|
|
|
$self->{map}->writer->change(sub { |
147
|
64
|
50
|
|
|
|
291
|
return unless my $worker = $_->{workers}{$$}; |
148
|
|
|
|
|
|
|
|
149
|
64
|
|
50
|
|
|
228
|
my $code = $tx->res->code || 0; |
150
|
64
|
50
|
|
|
|
795
|
if ($code > 499) { $_->{stats}{server_error}++ } |
|
0
|
50
|
|
|
|
0
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
151
|
0
|
|
|
|
|
0
|
elsif ($code > 399) { $_->{stats}{client_error}++ } |
152
|
2
|
|
|
|
|
6
|
elsif ($code > 299) { $_->{stats}{redirect}++ } |
153
|
62
|
|
|
|
|
131
|
elsif ($code > 199) { $_->{stats}{success}++ } |
154
|
0
|
|
|
|
|
0
|
elsif ($code) { $_->{stats}{info}++ } |
155
|
|
|
|
|
|
|
|
156
|
64
|
|
|
|
|
228
|
@{$worker->{connections}{$id}{request}}{qw(finished status)} = (time, $code); |
|
64
|
|
|
|
|
241
|
|
157
|
64
|
|
|
|
|
142
|
$worker->{connections}{$id}{processed}++; |
158
|
64
|
|
|
|
|
109
|
$worker->{processed}++; |
159
|
64
|
|
|
|
|
188
|
$_->{processed}++; |
160
|
64
|
|
|
|
|
345
|
}); |
161
|
|
|
|
|
|
|
} |
162
|
64
|
|
|
|
|
502
|
); |
163
|
|
|
|
|
|
|
} |
164
|
|
|
|
|
|
|
|
165
|
|
|
|
|
|
|
sub _rendered { |
166
|
64
|
|
|
64
|
|
184
|
my ($self, $c) = @_; |
167
|
|
|
|
|
|
|
|
168
|
64
|
|
|
|
|
220
|
my $id = $c->tx->connection; |
169
|
|
|
|
|
|
|
$self->{map}->writer->change(sub { |
170
|
64
|
50
|
|
64
|
|
296
|
return unless my $conn = $_->{workers}{$$}{connections}{$id}; |
171
|
64
|
50
|
|
|
|
170
|
return unless my $req = $conn->{request}; |
172
|
64
|
|
|
|
|
275
|
$req->{time} = time - $req->{started}; |
173
|
64
|
|
|
|
|
248
|
@{$req}{qw(client status worker)} = ($conn->{client}, $c->res->code, $$); |
|
64
|
|
|
|
|
1061
|
|
174
|
|
|
|
|
|
|
|
175
|
64
|
|
|
|
|
158
|
my $slowest = $_->{slowest}; |
176
|
64
|
|
|
|
|
332
|
@$slowest = sort { $b->{time} <=> $a->{time} } @$slowest, $req; |
|
470
|
|
|
|
|
1074
|
|
177
|
64
|
|
|
|
|
114
|
my %seen; |
178
|
64
|
|
|
|
|
149
|
@$slowest = grep { !$seen{"$_->{method} $_->{path}"}++ } @$slowest; |
|
324
|
|
|
|
|
1192
|
|
179
|
64
|
|
|
|
|
499
|
pop @$slowest while @$slowest > $self->{slowest}; |
180
|
64
|
|
|
|
|
875
|
}); |
181
|
|
|
|
|
|
|
} |
182
|
|
|
|
|
|
|
|
183
|
|
|
|
|
|
|
sub _resources { |
184
|
2
|
|
|
2
|
|
5
|
my $self = shift; |
185
|
|
|
|
|
|
|
|
186
|
|
|
|
|
|
|
$self->{map}->writer->change(sub { |
187
|
2
|
|
|
2
|
|
41
|
@{$_->{workers}{$$}}{qw(utime stime maxrss)} = (getrusage)[0, 1, 2]; |
|
2
|
|
|
|
|
768
|
|
188
|
|
|
|
|
|
|
|
189
|
|
|
|
|
|
|
# macOS actually returns bytes instead of kilobytes |
190
|
2
|
|
|
|
|
12
|
$_->{workers}{$$}{maxrss} = $_->{workers}{$$}{maxrss} * 1000 unless MACOS; |
191
|
|
|
|
|
|
|
|
192
|
2
|
|
|
|
|
4
|
for my $id (keys %{$_->{workers}{$$}{connections}}) { _read_write($_, $id) } |
|
2
|
|
|
|
|
13
|
|
|
0
|
|
|
|
|
0
|
|
193
|
2
|
|
|
|
|
7
|
}); |
194
|
|
|
|
|
|
|
} |
195
|
|
|
|
|
|
|
|
196
|
|
|
|
|
|
|
sub _slowest { |
197
|
2
|
|
|
2
|
|
6
|
my $all = shift; |
198
|
|
|
|
|
|
|
|
199
|
2
|
|
|
|
|
5
|
my @table; |
200
|
2
|
|
|
|
|
4
|
for my $req (@{$all->{slowest}}) { |
|
2
|
|
|
|
|
14
|
|
201
|
8
|
|
|
|
|
24
|
my $str = "$req->{method} $req->{path}"; |
202
|
8
|
100
|
|
|
|
25
|
$str .= "?$req->{query}" if $req->{query}; |
203
|
8
|
50
|
|
|
|
39
|
$str .= " → $req->{status}" if $req->{status}; |
204
|
8
|
|
|
|
|
35
|
my $time = sprintf '%.2f', $req->{time}; |
205
|
8
|
|
|
|
|
18
|
push @table, [$time, $str, @{$req}{qw(request_id worker client started)}]; |
|
8
|
|
|
|
|
30
|
|
206
|
|
|
|
|
|
|
} |
207
|
|
|
|
|
|
|
|
208
|
2
|
|
|
|
|
17
|
return \@table; |
209
|
|
|
|
|
|
|
} |
210
|
|
|
|
|
|
|
|
211
|
|
|
|
|
|
|
sub _start { |
212
|
2
|
|
|
2
|
|
8
|
my ($self, $server, $app) = @_; |
213
|
|
|
|
|
|
|
|
214
|
2
|
50
|
|
|
|
17
|
return $app->log->warn('Server not suported by Mojolicious::Plugin::Status') |
215
|
|
|
|
|
|
|
unless $server->isa('Mojo::Server::Daemon'); |
216
|
|
|
|
|
|
|
|
217
|
|
|
|
|
|
|
# Register started workers |
218
|
|
|
|
|
|
|
Mojo::IOLoop->next_tick(sub { |
219
|
2
|
|
|
2
|
|
1868
|
$self->{map}->writer->change(sub { $_->{workers}{$$} = {started => time, processed => 0} }); |
|
2
|
|
|
|
|
16
|
|
220
|
2
|
|
|
|
|
40
|
}); |
221
|
|
|
|
|
|
|
|
222
|
|
|
|
|
|
|
# Remove stopped workers |
223
|
|
|
|
|
|
|
$server->on( |
224
|
|
|
|
|
|
|
reap => sub { |
225
|
0
|
|
|
0
|
|
0
|
my ($server, $pid) = @_; |
226
|
0
|
|
|
|
|
0
|
$self->{map}->writer->change(sub { delete $_->{workers}{$pid} }); |
|
0
|
|
|
|
|
0
|
|
227
|
|
|
|
|
|
|
} |
228
|
2
|
50
|
|
|
|
210
|
) if $server->isa('Mojo::Server::Prefork'); |
229
|
|
|
|
|
|
|
|
230
|
|
|
|
|
|
|
# Collect stats |
231
|
2
|
|
|
64
|
|
35
|
$app->hook(after_build_tx => sub { $self->_tx(@_) }); |
|
64
|
|
|
|
|
242419
|
|
232
|
2
|
|
|
64
|
|
58
|
$app->hook(before_dispatch => sub { $self->_request(@_) }); |
|
64
|
|
|
|
|
41673
|
|
233
|
2
|
|
|
64
|
|
34
|
$app->hook(after_dispatch => sub { $self->_rendered(@_) }); |
|
64
|
|
|
|
|
108898
|
|
234
|
2
|
|
|
2
|
|
32
|
Mojo::IOLoop->next_tick(sub { $self->_resources }); |
|
2
|
|
|
|
|
25
|
|
235
|
2
|
|
|
0
|
|
65
|
Mojo::IOLoop->recurring(5 => sub { $self->_resources }); |
|
0
|
|
|
|
|
0
|
|
236
|
|
|
|
|
|
|
} |
237
|
|
|
|
|
|
|
|
238
|
2
|
|
|
2
|
|
39
|
sub _stats { {started => time, info => 0, success => 0, redirect => 0, client_error => 0, server_error => 0} } |
239
|
|
|
|
|
|
|
|
240
|
|
|
|
|
|
|
sub _stream { |
241
|
1
|
|
|
1
|
|
5
|
my ($self, $id) = @_; |
242
|
|
|
|
|
|
|
|
243
|
1
|
|
|
|
|
7
|
my $stream = Mojo::IOLoop->stream($id); |
244
|
|
|
|
|
|
|
$stream->on( |
245
|
|
|
|
|
|
|
close => sub { |
246
|
1
|
50
|
|
1
|
|
34974
|
$self->{map}->writer->change(sub { delete $_->{workers}{$$}{connections}{$id} if $_->{workers}{$$} }); |
|
1
|
|
|
|
|
11
|
|
247
|
|
|
|
|
|
|
} |
248
|
1
|
|
|
|
|
24
|
); |
249
|
|
|
|
|
|
|
} |
250
|
|
|
|
|
|
|
|
251
|
|
|
|
|
|
|
sub _tx { |
252
|
64
|
|
|
64
|
|
172
|
my ($self, $tx, $app) = @_; |
253
|
|
|
|
|
|
|
|
254
|
|
|
|
|
|
|
$tx->on( |
255
|
|
|
|
|
|
|
connection => sub { |
256
|
64
|
|
|
64
|
|
2192
|
my ($tx, $id) = @_; |
257
|
|
|
|
|
|
|
|
258
|
64
|
|
|
|
|
205
|
my $map = $self->{map}; |
259
|
64
|
100
|
|
|
|
284
|
return if $map->writer->fetch->{workers}{$$}{connections}{$id}; |
260
|
|
|
|
|
|
|
|
261
|
|
|
|
|
|
|
$map->writer->change(sub { |
262
|
1
|
|
|
|
|
11
|
$_->{workers}{$$}{connections}{$id} = {started => time, processed => 0, bytes_read => 0, bytes_written => 0}; |
263
|
1
|
|
|
|
|
8
|
}); |
264
|
1
|
|
|
|
|
6
|
$self->_stream($id); |
265
|
|
|
|
|
|
|
} |
266
|
64
|
|
|
|
|
403
|
); |
267
|
|
|
|
|
|
|
} |
268
|
|
|
|
|
|
|
|
269
|
|
|
|
|
|
|
1; |
270
|
|
|
|
|
|
|
|
271
|
|
|
|
|
|
|
=encoding utf8 |
272
|
|
|
|
|
|
|
|
273
|
|
|
|
|
|
|
=head1 NAME |
274
|
|
|
|
|
|
|
|
275
|
|
|
|
|
|
|
Mojolicious::Plugin::Status - Mojolicious server status |
276
|
|
|
|
|
|
|
|
277
|
|
|
|
|
|
|
=head1 SYNOPSIS |
278
|
|
|
|
|
|
|
|
279
|
|
|
|
|
|
|
# Mojolicious |
280
|
|
|
|
|
|
|
$self->plugin('Status'); |
281
|
|
|
|
|
|
|
|
282
|
|
|
|
|
|
|
# Mojolicious::Lite |
283
|
|
|
|
|
|
|
plugin 'Status'; |
284
|
|
|
|
|
|
|
|
285
|
|
|
|
|
|
|
# Secure access to the server status ui with Basic authentication |
286
|
|
|
|
|
|
|
my $under = $self->routes->under('/status' => sub ($c) { |
287
|
|
|
|
|
|
|
return 1 if $c->req->url->to_abs->userinfo eq 'Bender:rocks'; |
288
|
|
|
|
|
|
|
$c->res->headers->www_authenticate('Basic'); |
289
|
|
|
|
|
|
|
$c->render(text => 'Authentication required!', status => 401); |
290
|
|
|
|
|
|
|
return undef; |
291
|
|
|
|
|
|
|
}); |
292
|
|
|
|
|
|
|
$self->plugin('Status' => {route => $under}); |
293
|
|
|
|
|
|
|
|
294
|
|
|
|
|
|
|
=head1 DESCRIPTION |
295
|
|
|
|
|
|
|
|
296
|
|
|
|
|
|
|
=begin html |
297
|
|
|
|
|
|
|
|
298
|
|
|
|
|
|
|
|
299
|
|
|
|
|
|
|
|
300
|
|
|
|
|
|
|
width="600px"> |
301
|
|
|
|
|
|
|
|
302
|
|
|
|
|
|
|
|
303
|
|
|
|
|
|
|
=end html |
304
|
|
|
|
|
|
|
|
305
|
|
|
|
|
|
|
L is a L plugin providing a server status ui for L and |
306
|
|
|
|
|
|
|
L. Note that this module is B and should therefore only be used for debugging |
307
|
|
|
|
|
|
|
purposes. |
308
|
|
|
|
|
|
|
|
309
|
|
|
|
|
|
|
=head1 OPTIONS |
310
|
|
|
|
|
|
|
|
311
|
|
|
|
|
|
|
L supports the following options. |
312
|
|
|
|
|
|
|
|
313
|
|
|
|
|
|
|
=head2 return_to |
314
|
|
|
|
|
|
|
|
315
|
|
|
|
|
|
|
# Mojolicious::Lite |
316
|
|
|
|
|
|
|
plugin Status => {return_to => 'some_route'}; |
317
|
|
|
|
|
|
|
|
318
|
|
|
|
|
|
|
Name of route or path to return to when leaving the server status ui, defaults to C>. |
319
|
|
|
|
|
|
|
|
320
|
|
|
|
|
|
|
=head2 route |
321
|
|
|
|
|
|
|
|
322
|
|
|
|
|
|
|
# Mojolicious::Lite |
323
|
|
|
|
|
|
|
plugin Status => {route => app->routes->any('/status')}; |
324
|
|
|
|
|
|
|
|
325
|
|
|
|
|
|
|
L object to attach the server status ui to, defaults to generating a new one with the |
326
|
|
|
|
|
|
|
prefix C. |
327
|
|
|
|
|
|
|
|
328
|
|
|
|
|
|
|
=head2 size |
329
|
|
|
|
|
|
|
|
330
|
|
|
|
|
|
|
# Mojolicious::Lite |
331
|
|
|
|
|
|
|
plugin Status => {size => 1234}; |
332
|
|
|
|
|
|
|
|
333
|
|
|
|
|
|
|
Size of anonymous mapped memory to use for storing statistics, defaults to C<52428800> (50 MiB). |
334
|
|
|
|
|
|
|
|
335
|
|
|
|
|
|
|
=head2 slowest |
336
|
|
|
|
|
|
|
|
337
|
|
|
|
|
|
|
# Mojolicious::Lite |
338
|
|
|
|
|
|
|
plugin Status => {slowest => 5}; |
339
|
|
|
|
|
|
|
|
340
|
|
|
|
|
|
|
Number of slowest requests to track, defaults to C<10>. |
341
|
|
|
|
|
|
|
|
342
|
|
|
|
|
|
|
=head1 METHODS |
343
|
|
|
|
|
|
|
|
344
|
|
|
|
|
|
|
L inherits all methods from L and implements the following new ones. |
345
|
|
|
|
|
|
|
|
346
|
|
|
|
|
|
|
=head2 register |
347
|
|
|
|
|
|
|
|
348
|
|
|
|
|
|
|
my $route = $plugin->register(Mojolicious->new); |
349
|
|
|
|
|
|
|
|
350
|
|
|
|
|
|
|
Register renderer and helper in L application. |
351
|
|
|
|
|
|
|
|
352
|
|
|
|
|
|
|
=head1 BUNDLED FILES |
353
|
|
|
|
|
|
|
|
354
|
|
|
|
|
|
|
The L distribution includes a few files with different licenses that have been bundled for |
355
|
|
|
|
|
|
|
internal use. |
356
|
|
|
|
|
|
|
|
357
|
|
|
|
|
|
|
=head2 Artwork |
358
|
|
|
|
|
|
|
|
359
|
|
|
|
|
|
|
Copyright (C) 2018, Sebastian Riedel. |
360
|
|
|
|
|
|
|
|
361
|
|
|
|
|
|
|
Licensed under the CC-SA License, Version 4.0 L. |
362
|
|
|
|
|
|
|
|
363
|
|
|
|
|
|
|
=head2 Bootstrap |
364
|
|
|
|
|
|
|
|
365
|
|
|
|
|
|
|
Copyright (C) 2011-2018 The Bootstrap Authors. |
366
|
|
|
|
|
|
|
|
367
|
|
|
|
|
|
|
Licensed under the MIT License, L. |
368
|
|
|
|
|
|
|
|
369
|
|
|
|
|
|
|
=head2 Font Awesome |
370
|
|
|
|
|
|
|
|
371
|
|
|
|
|
|
|
Copyright (C) Dave Gandy. |
372
|
|
|
|
|
|
|
|
373
|
|
|
|
|
|
|
Licensed under the MIT License, L, and the SIL OFL 1.1, |
374
|
|
|
|
|
|
|
L. |
375
|
|
|
|
|
|
|
|
376
|
|
|
|
|
|
|
=head1 AUTHOR |
377
|
|
|
|
|
|
|
|
378
|
|
|
|
|
|
|
Sebastian Riedel, C. |
379
|
|
|
|
|
|
|
|
380
|
|
|
|
|
|
|
=head1 COPYRIGHT AND LICENSE |
381
|
|
|
|
|
|
|
|
382
|
|
|
|
|
|
|
Copyright (C) 2018-2021, Sebastian Riedel and others. |
383
|
|
|
|
|
|
|
|
384
|
|
|
|
|
|
|
This program is free software, you can redistribute it and/or modify it under the terms of the Artistic License version |
385
|
|
|
|
|
|
|
2.0. |
386
|
|
|
|
|
|
|
|
387
|
|
|
|
|
|
|
=head1 SEE ALSO |
388
|
|
|
|
|
|
|
|
389
|
|
|
|
|
|
|
L, L, L. |
390
|
|
|
|
|
|
|
|
391
|
|
|
|
|
|
|
=cut |