Adding mail report support.
This commit is contained in:
parent
09e7d74d2f
commit
91562a3ae3
@ -10,5 +10,11 @@ WriteMakefile(
|
||||
PREREQ_PM => {
|
||||
'DBD::SQLite' => 0,
|
||||
'DateTime' => 0,
|
||||
'Email::Sender::Simple' => 0,
|
||||
'Email::Sender::Transport::SMTP' => 0,
|
||||
'Email::MIME' => 0,
|
||||
'IO::Socket::SSL' => 0,
|
||||
'MIME::Base64' => 0,
|
||||
'Authen::SASL' => 0,
|
||||
}
|
||||
);
|
||||
|
@ -6,15 +6,34 @@ use strict;
|
||||
use warnings;
|
||||
|
||||
use Carp qw/confess/;
|
||||
use POSIX qw/WNOHANG/;
|
||||
|
||||
use Try::Tiny;
|
||||
|
||||
use Cualsea::Server::Loop;
|
||||
use Cualsea::Server::MonitorController;
|
||||
|
||||
my $loop = Cualsea::Server::Loop->new;
|
||||
my $pid = fork;
|
||||
if ($pid) {{
|
||||
local $SIG{INT} = \&finish_parent;
|
||||
while (1) {
|
||||
my $loop = Cualsea::Server::Loop->new;
|
||||
try {
|
||||
$loop->run;
|
||||
} catch {
|
||||
confess $_;
|
||||
};
|
||||
}
|
||||
finish_parent();
|
||||
}}
|
||||
|
||||
my $monitor_controller = Cualsea::Server::MonitorController->new;
|
||||
while (1) {
|
||||
try {
|
||||
$loop->run;
|
||||
} catch {
|
||||
confess $_;
|
||||
};
|
||||
$monitor_controller->loop;
|
||||
}
|
||||
|
||||
sub finish_parent {
|
||||
kill 'INT', $pid;
|
||||
1 while waitpid $pid, WNOHANG;
|
||||
exit;
|
||||
}
|
||||
|
@ -25,6 +25,11 @@ my @migrations = (
|
||||
date_execution TEXT,
|
||||
parameters TEXT,
|
||||
result TEXT
|
||||
);',
|
||||
'CREATE TABLE monitor (
|
||||
id INTEGER PRIMARY KEY,
|
||||
date_execution TEXT,
|
||||
is_up INTEGER
|
||||
);'
|
||||
);
|
||||
|
||||
|
88
cualsea-server/lib/Cualsea/Server/Mail.pm
Normal file
88
cualsea-server/lib/Cualsea/Server/Mail.pm
Normal file
@ -0,0 +1,88 @@
|
||||
package Cualsea::Server::Mail;
|
||||
|
||||
use v5.30.0;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use Const::Fast;
|
||||
use Email::Sender::Transport::SMTP;
|
||||
use Email::Sender::Simple qw/sendmail/;
|
||||
use Email::MIME;
|
||||
|
||||
const my $MAIL_CONFIG_FILE => '/etc/cualsea/mail.conf';
|
||||
const my $REPORT_TO_CONFIG_FILE => '/etc/cualsea/report_to';
|
||||
const my $FROM_CONFIG_FILE => '/etc/cualsea/from';
|
||||
|
||||
sub new {
|
||||
my $class = shift;
|
||||
return bless {}, $class;
|
||||
}
|
||||
|
||||
sub notify_service_down {
|
||||
my $self = shift;
|
||||
my $name = shift;
|
||||
|
||||
my $mime = Email::MIME->create(
|
||||
header_str => [
|
||||
From => $self->from,
|
||||
To => [ $self->report_to ],
|
||||
Subject => "Service $name down",
|
||||
],
|
||||
parts => [
|
||||
Email::MIME->create(
|
||||
attributes => {
|
||||
content_type => 'text/plain',
|
||||
disposition => 'attachment',
|
||||
charset => 'UTF-8',
|
||||
encoding => "8bit",
|
||||
},
|
||||
body_str => "$name is not up",
|
||||
)
|
||||
]
|
||||
);
|
||||
sendmail($mime, { transport => $self->transport });
|
||||
}
|
||||
|
||||
sub report_to {
|
||||
my $self = shift;
|
||||
if (!defined $self->{report_to}) {
|
||||
open my $fh, '<', $REPORT_TO_CONFIG_FILE or die "Unable to get mail to report from config file";
|
||||
my $email = <$fh>;
|
||||
chomp $email;
|
||||
close $fh;
|
||||
$self->{report_to} = $email;
|
||||
}
|
||||
return $self->{report_to};
|
||||
}
|
||||
|
||||
sub from {
|
||||
my $self = shift;
|
||||
if (!defined $self->{from}) {
|
||||
open my $fh, '<', $FROM_CONFIG_FILE or die "Unable to get mail From from config file";
|
||||
my $email = <$fh>;
|
||||
chomp $email;
|
||||
close $fh;
|
||||
$self->{from} = $email;
|
||||
}
|
||||
return $self->{from};
|
||||
}
|
||||
|
||||
sub transport {
|
||||
my $self = shift;
|
||||
if (!defined $self->{transport}) {
|
||||
my %parameters;
|
||||
open my $fh, '<', $MAIL_CONFIG_FILE or die "Unable to get transport from config file";
|
||||
while (my $line = <$fh>) {
|
||||
my ($key, $value) = $line =~ /^(.*?)=(.*?)\s*$/;
|
||||
if ($key eq 'hosts') {
|
||||
$value = [ $value ];
|
||||
}
|
||||
$parameters{$key} = $value;
|
||||
}
|
||||
close $fh;
|
||||
$self->{transport} = Email::Sender::Transport::SMTP->new(%parameters);
|
||||
}
|
||||
return $self->{transport};
|
||||
}
|
||||
1;
|
@ -18,6 +18,7 @@ use JSON;
|
||||
|
||||
use Cualsea::MessageManager;
|
||||
use Cualsea::Server::DB;
|
||||
use Cualsea::Server::Service;
|
||||
|
||||
sub handle_add {
|
||||
my %params = @_;
|
||||
@ -62,7 +63,7 @@ sub handle_del {
|
||||
my $name = $params{name};
|
||||
my $dbh = Cualsea::Server::DB->dbh();
|
||||
|
||||
if ( !check_if_service_exists_in_db($name) ) {
|
||||
if ( !Cualsea::Server::Service::check_if_service_exists_in_db($name) ) {
|
||||
return {
|
||||
is_error => 1,
|
||||
desc => 'Service not found.',
|
||||
@ -81,23 +82,13 @@ EOF
|
||||
};
|
||||
}
|
||||
|
||||
sub check_if_service_exists_in_db {
|
||||
my $name = shift;
|
||||
my $dbh = Cualsea::Server::DB->dbh();
|
||||
my $service = $dbh->selectrow_hashref( <<"EOF", undef, $name );
|
||||
SELECT name FROM services WHERE name = ?
|
||||
EOF
|
||||
if ( !defined $service ) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
sub handle_start {
|
||||
my %params = @_;
|
||||
my $name = $params{name};
|
||||
|
||||
if ( !check_if_service_exists_in_db($name) ) {
|
||||
if ( !Cualsea::Server::Service::check_if_service_exists_in_db($name) ) {
|
||||
return {
|
||||
is_error => 1,
|
||||
desc => 'Service not found.',
|
||||
@ -105,7 +96,7 @@ sub handle_start {
|
||||
};
|
||||
}
|
||||
|
||||
if ( _is_started_service($name) ) {
|
||||
if ( Cualsea::Server::Service::is_started_service($name) ) {
|
||||
return {
|
||||
is_error => 1,
|
||||
desc => 'Service already started.',
|
||||
@ -120,23 +111,19 @@ sub handle_start {
|
||||
};
|
||||
}
|
||||
|
||||
sub _is_started_service {
|
||||
my $name = shift;
|
||||
return !system "/etc/init.d/$name", 'status';
|
||||
}
|
||||
|
||||
sub handle_stop {
|
||||
my %params = @_;
|
||||
my $name = $params{name};
|
||||
|
||||
if ( !check_if_service_exists_in_db($name) ) {
|
||||
if ( !Cualsea::Server::Service::check_if_service_exists_in_db($name) ) {
|
||||
return {
|
||||
is_error => 1,
|
||||
desc => 'Service not found.',
|
||||
status => 404,
|
||||
};
|
||||
}
|
||||
if ( !_is_started_service($name) ) {
|
||||
if ( !Cualsea::Server::Service::is_started_service($name) ) {
|
||||
return {
|
||||
is_error => 1,
|
||||
desc => 'Service already stopped.',
|
||||
@ -156,7 +143,7 @@ sub handle_restart {
|
||||
my %params = @_;
|
||||
my $name = $params{name};
|
||||
|
||||
if ( !check_if_service_exists_in_db($name) ) {
|
||||
if ( !Cualsea::Server::Service::check_if_service_exists_in_db($name) ) {
|
||||
return {
|
||||
is_error => 1,
|
||||
desc => 'Service not found.',
|
||||
|
68
cualsea-server/lib/Cualsea/Server/MonitorController.pm
Normal file
68
cualsea-server/lib/Cualsea/Server/MonitorController.pm
Normal file
@ -0,0 +1,68 @@
|
||||
package Cualsea::Server::MonitorController;
|
||||
|
||||
use v5.30.0;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use DateTime;
|
||||
|
||||
use Cualsea::Server::DB;
|
||||
use Cualsea::Server::Service;
|
||||
use Cualsea::Server::Mail;
|
||||
|
||||
sub new {
|
||||
my $class = shift;
|
||||
return bless {}, $class;
|
||||
}
|
||||
|
||||
sub last_date {
|
||||
my $self = shift;
|
||||
if ( !exists $self->{last_date} ) {
|
||||
$self->{last_date} = DateTime->now();
|
||||
}
|
||||
return $self->{last_date};
|
||||
}
|
||||
|
||||
sub loop {
|
||||
my $self = shift;
|
||||
my $last_date = $self->last_date;
|
||||
my $current_date = DateTime->now();
|
||||
if ( $current_date > $last_date->clone->add( minutes => 1 ) ) {
|
||||
$self->{last_date} = $current_date;
|
||||
$self->monitor;
|
||||
}
|
||||
}
|
||||
|
||||
sub monitor {
|
||||
my $self = shift;
|
||||
my $dbh = Cualsea::Server::DB->dbh();
|
||||
my $services = $dbh->selectall_arrayref( <<'EOF', { Slice => {} } );
|
||||
SELECT name,pidfile FROM services;
|
||||
EOF
|
||||
for my $service (@$services) {
|
||||
my $pidfile = $service->{pidfile};
|
||||
my $name = $service->{name};
|
||||
my $started = Cualsea::Server::Service::is_started_service($name);
|
||||
if ($started) {{
|
||||
my $success_opening = open my $fh, '<', $pidfile;
|
||||
if (!$success_opening) {
|
||||
$started = 0;
|
||||
# Cool trick to escape if {{ }}
|
||||
next;
|
||||
}
|
||||
my $pid = <$fh>;
|
||||
chomp $pid;
|
||||
$started = !system 'ps', '-p', $pid;
|
||||
close $fh;
|
||||
}}
|
||||
$dbh->do( 'INSERT INTO monitor (date_execution, is_up) VALUES (?, ?);',
|
||||
undef, DateTime->now() . '', $started );
|
||||
if (!$started) {
|
||||
say "$name stopped";
|
||||
my $mailer = Cualsea::Server::Mail->new();
|
||||
$mailer->notify_service_down($name);
|
||||
}
|
||||
}
|
||||
}
|
||||
1;
|
24
cualsea-server/lib/Cualsea/Server/Service.pm
Normal file
24
cualsea-server/lib/Cualsea/Server/Service.pm
Normal file
@ -0,0 +1,24 @@
|
||||
package Cualsea::Server::Service;
|
||||
|
||||
use v5.30.0;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
sub is_started_service {
|
||||
my $name = shift;
|
||||
return !system "/etc/init.d/$name", 'status';
|
||||
}
|
||||
|
||||
sub check_if_service_exists_in_db {
|
||||
my $name = shift;
|
||||
my $dbh = Cualsea::Server::DB->dbh();
|
||||
my $service = $dbh->selectrow_hashref( <<"EOF", undef, $name );
|
||||
SELECT name FROM services WHERE name = ?
|
||||
EOF
|
||||
if ( !defined $service ) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
1;
|
Loading…
Reference in New Issue
Block a user