No description
- Perl 89.4%
- Raku 10.6%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
| lib/Mojolicious/Plugin | ||
| t | ||
| .gitignore | ||
| .perltidyrc | ||
| .ship.conf | ||
| .travis.yml | ||
| Changes | ||
| cpanfile | ||
| MANIFEST.SKIP | ||
| README.pod | ||
package Mojolicious::Plugin::StatusForServer;
use Mojo::Base 'Mojolicious::Plugin';
sub register {
my ($self, $app, $config) = @_;
my $app_class = ref $app;
$app_class = 'Lite app' if $app_class eq 'Mojolicious::Lite';
$config->{cache_module} ||= 'Cache::FastMmap';
eval "require $config->{cache_module}";
my $shared = $config->{cache_module}->new(%{$config->{cache_config}});
$app->defaults(
status_for_server => {
app_name => $config->{app_name} // $app_class,
os => $^O,
time => {now => -1, restart => Mojo::Date->new($^T)},
total => $shared,
version => {
app => $config->{app_version} // $app_class->VERSION // undef,
ev => eval { require Mojo::Reactor::EV; 1 } ? $EV::VERSION : undef,
mojolicious => $Mojolicious::VERSION,
nnr => Mojo::IOLoop::Client->can_nnr ? $Net::DNS::Native::VERSION : undef,
perl => $^V,
roles => Mojo::Base->ROLES ? $Role::Tiny::VERSION : undef,
socks => Mojo::IOLoop::Client->can_socks ? $IO::Socket::Socks::VERSION : undef,
tls => Mojo::IOLoop::TLS->can_tls ? $IO::Socket::SSL::VERSION : undef,
},
}
);
push @{$app->renderer->classes}, __PACKAGE__;
$app->routes->get($config->{route} || '/status' => \&_get_status);
Mojo::IOLoop->next_tick(
sub {
my $worker = {start => Mojo::Date->new(time)->to_datetime};
$shared->set("worker:$$", $worker);
$app->hook(before_dispatch => $self->_before_dispatch_cb($shared, $worker));
}
);
}
sub _before_dispatch_cb {
my ($self, $shared, $worker) = @_;
return sub {
my $c = shift;
my $method = lc $c->req->method;
$shared->get_and_set("total:$method" => sub { ++$_[1] });
$worker->{$method}++;
$c->tx->on(
finish => sub {
my $tx = shift;
my $code = $tx->res->code || '000';
$worker->{$code}++;
$shared->set("worker:$$", $worker);
$shared->get_and_set("total:$code" => sub { ++$_[1] });
}
);
};
}
sub _get_status {
my $c = shift;
my $json = $c->stash('status_for_server');
my $shared = $json->{total};
local $json->{time}{now} = Mojo::Date->new(time);
local $json->{total} = {};
local $json->{workers} = {};
for my $shared_key ($shared->get_keys(0)) {
my ($group, $key) = split /:/, $shared_key;
if ($group eq 'worker') {
if (kill 0, $key) {
$json->{workers}{$key} = $shared->get($shared_key);
}
else {
$shared->remove($shared_key);
}
}
elsif ($group eq 'total') {
$json->{total}{$key} = $shared->get($shared_key);
}
}
if (($c->stash('format') || '') eq 'json') {
local $json->{time}{now} = $json->{time}{now}->to_datetime;
local $json->{time}{restart} = $json->{time}{restart}->to_datetime;
$c->render(json => $json);
}
else {
$c->render(status_for_server => %$json);
}
}
1;
=encoding utf8
=head1 NAME
Mojolicious::Plugin::StatusForServer - Get statistics from your mojolicious application
=head1 SYNOPSIS
use Mojolicious::Lite;
plugin status_for_server => {app_name => 'My cool app'};
# ...
app->start;
=head1 DESCRIPTION
L<Mojolicious::Plugin::StatusForServer> is a L<Mojolicious> plugin that will
track requests and responses, and render those statistics as either JSON or in
a plain text format.
It will also return information about the application and the system it is
running on. Example plain text response:
Mojolicious Server Status
Application Version: My cool app/4.2
Mojolicious Version: Mojolicious/7.71
Perl Version: v5.26.1/darwin
EV Version: 4.22
IO::Socket::Socks Version: 0.74
IO::Socket::SSL Version: 2.051
Net::DNS::Native Version: n/a
--------------------------------------------------------------------------
Current Time: Mon, 16 Apr 2018 13:10:51 GMT
Restart Time: Mon, 16 Apr 2018 13:10:50 GMT
Server uptime: 9438s
Workers: 4
--------------------------------------------------------------------------
Requests: 73
Responses: 72
See the test suite for information about the JSON structure.
=head1 METHODS
=head2 register
$self->register($app, \%config);
Called when registering this plugin in your L<Mojolicious> application.
C<%config> can have:
=over 2
=item * app_name
Default value is the class name of your application or "Lite app" if it is a
L<Mojolicious::Lite> application.
=item * app_version
Default value is C<$VERSION> in the application class or C<undef> if no version
has been provided.
=item * cache_config
EXPERIMENTAL.
=item * cache_module
EXPERIMENTAL.
=item * route
The resource path to get status for the server. Default value is "/status".
=back
=head1 AUTHOR
Jan Henning Thorsen
=head1 COPYRIGHT AND LICENSE
Copyright (C) 2018, Jan Henning Thorsen
This program is free software, you can redistribute it and/or modify it under
the terms of the Artistic License version 2.0.
=cut
__DATA__
@@ status_for_server.html.ep
% use List::Util 'sum';
Mojolicious Server Status
Application Version: <%= $app_name %>/<%= $version->{app} // '0.01' %>
Mojolicious Version: Mojolicious/<%= $version->{mojolicious} %>
Perl Version: <%= $version->{perl} %>/<%= $^O %>
EV Version: <%= $version->{ev} // 'n/a' %>
IO::Socket::Socks Version: <%= $version->{socks} // 'n/a' %>
IO::Socket::SSL Version: <%= $version->{tls} // 'n/a' %>
Net::DNS::Native Version: <%= $version->{nnr} // 'n/a' %>
--------------------------------------------------------------------------
Current Time: <%= $time->{now} %>
Restart Time: <%= $time->{restart} %>
Server uptime: <%= $time->{now}->epoch - $time->{restart}->epoch %>s
Workers: <%= int keys %$workers %>
--------------------------------------------------------------------------
Requests: <%= sum map { $total->{$_} } grep { /^[a-z]/ } keys %$total %>
Responses: <%= sum map { $total->{$_} } grep { /^[0-9]/ } keys %$total %>