Last active
December 9, 2024 10:34
-
-
Save s1037989/2e513d15ea2855323d17b5b64e5e7810 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package Mojolicious::Command::start; | |
use Mojo::Base 'Mojolicious::Command', -signatures; | |
use Mojo::Util qw(extract_usage getopt); | |
has description => 'Show versions of available modules'; | |
has usage => sub { shift->extract_usage }; | |
has perlbrew_with => sub { | |
return undef unless $ENV{PERLBREW_ROOT} && $ENV{PERLBREW_HOME} && $ENV{PERLBREW_PERL}; | |
return join '@', $ENV{PERLBREW_PERL}, $ENV{PERLBREW_LIB}; | |
}; | |
sub run ($self, @args) { | |
my @exec; | |
if (my $perlbrew_with = $self->perlbrew_with) { | |
@exec = ('perlbrew', 'exec', '--with', $perlbrew_with); | |
} | |
$ENV{MOJO_LISTEN} = join ',', $self->app->config->{listen}->@* if $self->app->config->{listen}; | |
$ENV{MOJO_REVERSE_PROXY} = join ',', $self->app->config->{proxy} if $self->app->config->{proxy}; | |
_exec(@exec, $self->app->config->{start}, @args) if $self->app->config->{start}; | |
die "missing configuration key 'start'\n"; | |
} | |
sub _exec { | |
$_ = join ' ', @_; | |
s/\$0/$0/g; | |
warn "$_\n"; | |
exec $_; | |
} | |
1; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package Mojolicious::Plugin::SmartLog; | |
use Mojo::Base 'Mojolicious::Plugin', -signatures; | |
use Mojo::File qw(); | |
use Time::HiRes qw(time); | |
has level => undef; | |
has path => undef; | |
has stderr => 0; | |
has user => sub { sub ($c) {} }; | |
sub register ($self, $app, $conf) { | |
# Note: logging to stdout/stderr will not get picked up by journald when run with hypnotoad | |
# When using hypnotoad, you should log to a file and use journald to monitor the file | |
$app->config->{log} ||= {}; | |
$self->stderr($ENV{MOJO_LOG_STDERR} || $conf->{stderr} || ($app->config->{log}{stderr} && $app->config->{log}{stderr} =~ /^\s*(1|y|yes|on|true)\s*$/i)); | |
if ($ENV{LOGS_DIRECTORY} && -d $ENV{LOGS_DIRECTORY}) { | |
$self->path(Mojo::File::path($ENV{LOGS_DIRECTORY})->child($app->mode . '.log')->touch); | |
} | |
elsif (my $path = $conf->{path} || $app->config->{log}{path}) { | |
$self->path($path)->tap(sub { $_->dirname->make_path }); | |
} | |
elsif (-d $app->home->child('log')) { | |
$self->path($app->home->child('log', $app->mode . '.log')); | |
} | |
$app->log->path($self->path) if $self->path; | |
$self->level($ENV{MOJO_LOG_LEVEL} || $conf->{level} || $app->config->{log}{level}); | |
$app->log->level($self->level) if $self->level; | |
my $time = time; | |
warn sprintf "[smart_log] %s\n", Mojo::File::path($app->log->path)->realpath if $app->log->path; | |
$app->log->on(message => sub ($log, $level, @lines) { | |
# warn Mojo::Util::dumper($log); | |
if ($log->path && $self->stderr) { | |
warn (($conf->{log_time} || $app->config->{log}{log_time}) ? $log->format->(time, $level, @lines) : sprintf("[%.3f] [%s] %s\n", time - $time, $level, join " ", @lines)); | |
} | |
return if grep { /Error handling errors/ } @lines; # don't handle errors if there's an error handling errors | |
return unless grep { /Raptor (Rainbow|Not Found) Shown/ } @lines; # only handle errors if there's a rainbow or not found shown | |
# Handle raptor problems, such as sending a special alert or logging to a different file | |
# $conf->{raptor_handler}->($log, $level, @lines) if $conf->{raptor_handler}; | |
# $self->emit('raptor', $log, $level, @lines); | |
}); | |
$app->hook(before_render => sub ($c, $args) { | |
return unless my $template = $args->{template}; | |
my $user = ref $conf->{user} eq 'CODE' ? $conf->{user}->($c) : '-'; | |
if ($template eq 'exception') { # Make sure we are rendering the exception template | |
return unless my $e = $c->stash->{exception}; | |
return unless my $snapshot = $c->stash->{snapshot}; | |
$c->log->error(sprintf '[%s] [%s] Raptor Rainbow Shown: %s (%s#%s); (%d) %s', $args->{status}, $user, $c->req->url, $snapshot->{controller}, $snapshot->{action}, $e->line->[0], $e); | |
$self->emit('raptor', $c->log->history->[-1]->@*); | |
} | |
elsif ($template eq 'not_found') { # Make sure we are rendering the not_found template | |
$c->log->warn(sprintf '[%s] [%s] Raptor Not Found Shown: %s', $args->{status}, $user, $c->req->url); | |
$self->emit('raptor', $c->log->history->[-1]->@*); | |
} | |
}); | |
} | |
1; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package Mojolicious::Plugin::Minion::AutoPerform; | |
use Mojo::Base 'Mojolicious::Plugin', -signatures; | |
use Mojo::IOLoop; | |
sub register ($self, $app, $conf) { | |
Mojo::IOLoop->recurring($conf->{auto_perform} || 3 => sub { | |
my $minion = $app->minion; | |
my $workers = $minion->workers; | |
return if $workers->total; | |
my @inactive; | |
my $queues = $conf->{queues} || ['default']; | |
$minion->jobs({states => ['inactive'], queues => $queues})->each(sub {push @inactive, $_->{id}}); | |
my $inactive = $#inactive + 1; | |
return unless $inactive; | |
if ($conf->{require_worker} // 1) { | |
$app->log->warn(sprintf 'No registered workers, NOT performing %d jobs (%s) in app', $inactive, join ', ', @inactive); | |
} | |
else { | |
my $queued = $minion->jobs({queues => $queues})->total; | |
$minion->perform_jobs({queues => $queues}); | |
my $performed = $queued - $minion->jobs({queues => $queues})->total; | |
$app->log->warn(sprintf 'No registered workers but performed %d jobs in app', $performed) if $performed && $app->mode eq 'production'; | |
} | |
}); | |
return $self; | |
} | |
1; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package Mojolicious::Plugin::AppPaths; | |
use Mojo::Base 'Mojolicious::Plugin', -signatures; | |
use Mojo::File qw(); | |
sub register ($self, $app, $conf) { | |
my $home = $app->home; | |
$app->helper('paths.app' => sub { $home }); | |
$app->helper('paths.data' => sub { Mojo::File::path($ENV{MOJO_DATA} || $conf->{data} || $home) }); | |
$app->helper('paths.tmp' => sub { Mojo::File::path($conf->{tmp} || '/tmp') }); | |
$app->helper('paths.vartmp' => sub { Mojo::File::path($conf->{vartmp} || '/var/tmp') }); | |
$app->helper('paths.cache' => sub { Mojo::File::path($ENV{CACHE_DIRECTORY} || $conf->{cache} || $home->child('cache')) }); | |
$app->helper('paths.log' => sub { Mojo::File::path($ENV{LOGS_DIRECTORY} || $conf->{logs} || $home->child('log')) }); | |
$app->helper('paths.run' => sub { Mojo::File::path($ENV{RUNTIME_DIRECTORY} || $conf->{runtime} || $home->child('run')) }); | |
$app->helper('paths.state' => sub { Mojo::File::path($ENV{STATE_DIRECTORY} || $conf->{state} || $home) }); | |
return if $conf->{no_chdir} // 1; | |
delete $conf->{chdir_to} unless $conf->{chdir_to} =~ /^(data|state)$/; | |
my $chdir = $conf->{chdir_to} ||= 'data'; | |
return if $app->home->to_string eq $app->paths->$chdir->to_string; | |
$app->home(Mojo::Home->new($app->paths->$chdir)); | |
warn sprintf "[app_paths] chdir %s (%sdir to backup: %s)\n", $app->home->to_string, $chdir, $app->home->realpath if chdir $app->home->to_string; | |
} | |
1; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package Mojolicious::Plugin::Listen; | |
use Mojo::Base 'Mojolicious::Plugin', -signatures; | |
use Mojo::Util qw(getopt); | |
sub register ($self, $app, $conf) { | |
$app->hook(before_command => sub ($command, $args) { | |
$command = ((split /::/, ref $command)[-1]); | |
return unless $command =~ /^(daemon|prefork|cgi|fcgi|morbo|psgi|standalone)$/; | |
$app->hook(before_server_start => sub ($server, $app) { | |
return if $ENV{MOJO_LISTEN}; | |
getopt \@ARGV, ['pass_through'], | |
'l|listen=s' => \my $listen; | |
return if $listen; | |
$listen = $app->config->{listen}; | |
$server->listen($listen) if $listen; | |
}); | |
}); | |
} | |
1; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package Mojolicious::Command::start; | |
use Mojo::Base 'Mojolicious::Command', -signatures; | |
use Mojo::Util qw(extract_usage getopt); | |
has description => 'Show versions of available modules'; | |
has usage => sub { shift->extract_usage }; | |
has perlbrew => sub { | |
return () unless $ENV{PERLBREW_ROOT} && $ENV{PERLBREW_HOME} && $ENV{PERLBREW_PERL}; | |
return ['perlbrew', 'exec', '--with', join '@', grep {$_} $ENV{PERLBREW_PERL}, $ENV{PERLBREW_LIB}]; | |
}; | |
sub run ($self, @args) { | |
$ENV{MOJO_LISTEN} = join ',', $self->app->config->{listen}->@* if $self->app->config->{listen}; | |
$ENV{MOJO_REVERSE_PROXY} = join ',', $self->app->config->{reverse_proxy} if $self->app->config->{reverse_proxy}; | |
$ENV{MOJO_LOG_LEVEL} = join ',', $self->app->config->{log_level} if $self->app->config->{log_level}; | |
$ENV{MOJO_LOG_SHORT} = join ',', $self->app->config->{log_short} if $self->app->config->{log_short}; | |
$ENV{MOJO_LOG_PATH} = join ',', $self->app->config->{log_path} if $self->app->config->{log_path}; | |
$ENV{MOJO_LOG_STDERR} = join ',', $self->app->config->{log_stderr} if $self->app->config->{log_stderr}; | |
_exec(@{$self->perlbrew}, $self->app->config->{start}, @args) if $self->app->config->{start}; | |
die "missing configuration key 'start'\n"; | |
} | |
sub _exec { | |
$_ = join ' ', @_; | |
s/\$0/$0/g; | |
warn "$_\n"; | |
exec $_; | |
} | |
1; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package Mojolicious::Plugin::Start; | |
use Mojo::Base 'Mojolicious::Plugin', -signatures; | |
use Mojo::File qw(); | |
use Mojo::Util qw(trim); | |
use Time::HiRes qw(time); | |
has level => undef; | |
has path => undef; | |
has stderr => 0; | |
has start_time => time; | |
has user => sub { sub ($c) {} }; | |
sub register ($self, $app, $conf) { | |
my $home = $app->home; | |
$app->helper('paths.app' => sub { $home }); | |
$app->helper('paths.data' => sub { Mojo::File::path($ENV{MOJO_DATA} || $conf->{data} || $home) }); | |
$app->helper('paths.tmp' => sub { Mojo::File::path($ENV{TMPDIR} || $conf->{tmp} || '/tmp') }); | |
$app->helper('paths.vartmp' => sub { Mojo::File::path($conf->{vartmp} || '/var/tmp') }); | |
$app->helper('paths.cache' => sub { Mojo::File::path($ENV{CACHE_DIRECTORY} || $conf->{cache} || $home->child('cache')) }); | |
$app->helper('paths.log' => sub { Mojo::File::path($ENV{LOGS_DIRECTORY} || $conf->{logs} || $home->child('log')) }); | |
$app->helper('paths.run' => sub { Mojo::File::path($ENV{RUNTIME_DIRECTORY} || $conf->{runtime} || $home->child('run')) }); | |
$app->helper('paths.state' => sub { Mojo::File::path($ENV{STATE_DIRECTORY} || $conf->{state} || $home) }); | |
$self->stderr(_is_true($ENV{MOJO_LOG_STDERR} || $conf->{log_stderr} || $app->config->{log_stderr})); | |
if (-d $app->paths->log) { | |
$self->path(Mojo::File::path($ENV{LOGS_DIRECTORY})->child($app->mode . '.log')); | |
} | |
elsif (my $log_path = $conf->{log_path} || $app->config->{log_path}) { | |
my $path = Mojo::File::path($log_path)->dirname if $log_path; | |
$self->path($path) if -d $path; | |
} | |
$app->log->path($self->path->realpath) if $self->path; | |
warn sprintf "[log_path] %s\n", Mojo::File::path($app->log->path) if $app->log->path && $self->stderr; | |
$self->level($ENV{MOJO_LOG_LEVEL} || $conf->{log_level} || $app->config->{log_level}); | |
$app->log->level($self->level) if $self->level; | |
$app->log->on(message => sub ($log, $level, @lines) { | |
my $log_time = _is_true($ENV{MOJO_LOG_TIME} || $conf->{log_time} || $app->config->{log_time}); | |
if ($self->stderr && ($log->path || defined $log_time)) { | |
warn _is_true($log_time) ? $log->format->(time, $level, @lines) : sprintf("[%.3f] [%s] %s\n", time - $self->start_time, $level, join " ", @lines); | |
} | |
}); | |
$app->hook(before_render => sub ($c, $args) { | |
my $user = ref $conf->{user} eq 'CODE' ? $conf->{user}->($c) : '-'; | |
return unless my $template = $args->{template}; | |
if ($template eq 'exception') { # Make sure we are rendering the exception template | |
return unless my $e = $c->stash->{exception}; | |
return unless my $snapshot = $c->stash->{snapshot}; | |
my $cal = sprintf '%s#L%s', join('#', grep {$_} $snapshot->{controller}, $snapshot->{action}) || 'callback', $e->line->[0] || 0; | |
my @raptor = ($c->req->request_id, $args->{status}, $user, $c->req->url, $cal, $e); | |
$c->log->error(sprintf '[%s] [%s] [%s] Raptor Exception shown for %s: %s', @raptor[1..2], $cal, $c->req->url, trim $e); | |
$app->log->emit('raptor_exception', @raptor); | |
} | |
elsif ($template eq 'not_found') { # Make sure we are rendering the not_found template | |
my @raptor = ($c->req->request_id, $args->{status}, $user, $c->req->url); | |
$c->log->warn(sprintf '[%s] [%s] Raptor Not Found shown for %s', @raptor[1..$#raptor]); | |
$app->log->emit('raptor_not_found', @raptor); | |
} | |
}); | |
return $self; | |
} | |
sub _is_false ($value) { return undef unless defined $value; $value =~ /^\s*(0|n|no|off|false)\s*$/i } | |
sub _is_true ($value) { return undef unless defined $value; $value =~ /^\s*(1|y|yes|on|true)\s*$/i } | |
1; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment