Adding mail report support.
This commit is contained in:
parent
09e7d74d2f
commit
91562a3ae3
@ -10,5 +10,11 @@ WriteMakefile(
|
|||||||
PREREQ_PM => {
|
PREREQ_PM => {
|
||||||
'DBD::SQLite' => 0,
|
'DBD::SQLite' => 0,
|
||||||
'DateTime' => 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 warnings;
|
||||||
|
|
||||||
use Carp qw/confess/;
|
use Carp qw/confess/;
|
||||||
|
use POSIX qw/WNOHANG/;
|
||||||
|
|
||||||
|
use Try::Tiny;
|
||||||
|
|
||||||
use Cualsea::Server::Loop;
|
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) {
|
while (1) {
|
||||||
try {
|
$monitor_controller->loop;
|
||||||
$loop->run;
|
}
|
||||||
} catch {
|
|
||||||
confess $_;
|
sub finish_parent {
|
||||||
};
|
kill 'INT', $pid;
|
||||||
|
1 while waitpid $pid, WNOHANG;
|
||||||
|
exit;
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,11 @@ my @migrations = (
|
|||||||
date_execution TEXT,
|
date_execution TEXT,
|
||||||
parameters TEXT,
|
parameters TEXT,
|
||||||
result 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::MessageManager;
|
||||||
use Cualsea::Server::DB;
|
use Cualsea::Server::DB;
|
||||||
|
use Cualsea::Server::Service;
|
||||||
|
|
||||||
sub handle_add {
|
sub handle_add {
|
||||||
my %params = @_;
|
my %params = @_;
|
||||||
@ -62,7 +63,7 @@ sub handle_del {
|
|||||||
my $name = $params{name};
|
my $name = $params{name};
|
||||||
my $dbh = Cualsea::Server::DB->dbh();
|
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 {
|
return {
|
||||||
is_error => 1,
|
is_error => 1,
|
||||||
desc => 'Service not found.',
|
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 {
|
sub handle_start {
|
||||||
my %params = @_;
|
my %params = @_;
|
||||||
my $name = $params{name};
|
my $name = $params{name};
|
||||||
|
|
||||||
if ( !check_if_service_exists_in_db($name) ) {
|
if ( !Cualsea::Server::Service::check_if_service_exists_in_db($name) ) {
|
||||||
return {
|
return {
|
||||||
is_error => 1,
|
is_error => 1,
|
||||||
desc => 'Service not found.',
|
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 {
|
return {
|
||||||
is_error => 1,
|
is_error => 1,
|
||||||
desc => 'Service already started.',
|
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 {
|
sub handle_stop {
|
||||||
my %params = @_;
|
my %params = @_;
|
||||||
my $name = $params{name};
|
my $name = $params{name};
|
||||||
|
|
||||||
if ( !check_if_service_exists_in_db($name) ) {
|
if ( !Cualsea::Server::Service::check_if_service_exists_in_db($name) ) {
|
||||||
return {
|
return {
|
||||||
is_error => 1,
|
is_error => 1,
|
||||||
desc => 'Service not found.',
|
desc => 'Service not found.',
|
||||||
status => 404,
|
status => 404,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if ( !_is_started_service($name) ) {
|
if ( !Cualsea::Server::Service::is_started_service($name) ) {
|
||||||
return {
|
return {
|
||||||
is_error => 1,
|
is_error => 1,
|
||||||
desc => 'Service already stopped.',
|
desc => 'Service already stopped.',
|
||||||
@ -156,7 +143,7 @@ sub handle_restart {
|
|||||||
my %params = @_;
|
my %params = @_;
|
||||||
my $name = $params{name};
|
my $name = $params{name};
|
||||||
|
|
||||||
if ( !check_if_service_exists_in_db($name) ) {
|
if ( !Cualsea::Server::Service::check_if_service_exists_in_db($name) ) {
|
||||||
return {
|
return {
|
||||||
is_error => 1,
|
is_error => 1,
|
||||||
desc => 'Service not found.',
|
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