Subversion Repositories computer_asset_manager_v1

Rev

Rev 93 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
23 rodolico 1
#! /usr/bin/perl -w
2
 
32 rodolico 3
# Version 0.9 20160713 RWR
4
# Added ability to have individual owners receive a summary report
93 rodolico 5
#
6
# Version 1.0 20191020 RWR
7
# Major change to query used for report. Instead of start time of backup,
8
# report will look for date report was added to CAMP. This keeps reports
9
# of backups which take extra time from showing up AFTER they are complete.
10
# For example, if a backup starts on a Tuesday and takes 36 hours to complete
11
# it will be reported as missing on Wed, but will be correctly reported as
12
# completed on Thu.
32 rodolico 13
 
23 rodolico 14
use DBI;
15
use Cwd 'abs_path';
16
#use Data::Dumper;
17
use File::Basename;
18
use YAML::XS;
19
 
20
 
25 rodolico 21
 
93 rodolico 22
my $VERSION = '1.0';
23 rodolico 23
my $MY_DIRECTORY = abs_path(dirname(__FILE__) );
24
my $message; # the message to send
27 rodolico 25
# query to find all reports in last 24 hours. Assumes the script
26
# runs at the same time each day
25 rodolico 27
my $query = qq|select 
32 rodolico 28
                  backups.responsible_party 'mailto',
25 rodolico 29
                  backups_run.backups_run_id 'ID',
30
                  device.device_id 'Device ID',
31
                  device.name 'Source',
93 rodolico 32
                  backups_run.start_time 'Start Time',
25 rodolico 33
                  timediff( backups_run.end_time,backups_run.start_time ) 'Run Time',
34
                  backups_run.transferred_count 'Files',
35
                  round(backups_run.transferred_size/1024/1024,2) 'Size (M)',
36
                  backups_run.files_deleted 'Deleted',
37
                  backups_run.skipped 'Skipped',
38
                  round( backups_run.data_sent/1024/1024,2) 'Traffic (M)'
39
               from
40
                  backups_run
41
                  join backups using (backups_id)
42
                  join device using (device_id)
43
               where
93 rodolico 44
                  backups_run.added_date > date_sub( now(), interval 24 hour)
27 rodolico 45
               order by Source
25 rodolico 46
               |;
47
 
23 rodolico 48
 
27 rodolico 49
# Find number of backups in the past 24 hours.                  
25 rodolico 50
my $count = qq/select count(*) 'Count' 
51
               from backups_run 
27 rodolico 52
               where
53
                  backups_run.start_time > date_sub( now(), interval 24 hour)/;
23 rodolico 54
 
27 rodolico 55
# looks for backups which did NOT happen in last 24 hours, but did
56
# happen in last 7 days, ie backups that did not make it.
25 rodolico 57
my $missing = qq/select 
58
                  device.device_id ID,
59
                  device.name name
93 rodolico 60
               from 
25 rodolico 61
                  ( 
62
                     select distinct( backups_id ) 
63
                     from 
64
                        backups_run 
65
                     where 
27 rodolico 66
                        (datediff( now(),added_date) < 7 ) 
25 rodolico 67
                  ) last_five
68
                  left join
69
                  (
70
                     select 
71
                        distinct( backups_id ) 
72
                     from 
73
                        backups_run
74
                     where 
93 rodolico 75
                        backups_run.added_date > date_sub( now(), interval 24 hour)
25 rodolico 76
                  ) today using (backups_id)
77
                  join 
78
                     backups using (backups_id)
79
                  join 
80
                     device using (device_id)
81
               where 
82
                  today.backups_id is null
93 rodolico 83
               /;
25 rodolico 84
 
85
 
23 rodolico 86
# following are used to find the configuration file
25 rodolico 87
my $confFileName = "rsbackupRead.conf.yaml";
23 rodolico 88
my @searchPaths = ( '/etc/camp', '/opt/camp', '/opt/camp/sysinfo', $MY_DIRECTORY );
89
 
90
 
91
sub loadConfig {
92
   my ( $confFileName, @searchPaths ) = @_;
93
   my $configuration;
94
   for ( $i = 0; $i < @searchPaths; $i++ ) {
95
      $filename = $searchPaths[$i] . '/' . $confFileName;
96
      if ( -e $filename ) {
97
         #print "Found $filename\n";
98
         open CONF, "<$filename" or warn "Could not read $filename: $!\n";
99
         $configuration = Load( join( '', <CONF> ) );
100
         close CONF;
101
         last; # exit out of the loop; we don't try to load it more than once
102
      } # if
103
   } # foreach
104
   return $configuration;
105
} # sub loadConfig
106
 
107
sub sendReport {
108
   my ($parameters,$report) = @_;
109
   my %CLIParams ;
110
   $CLIParams{'-f'}  = qq/$$parameters{'mailFrom'}/    if $$parameters{'mailFrom'};
111
   $CLIParams{'-t'}  = qq/$$parameters{'mailTo'}/      if $$parameters{'mailTo'};
112
   $CLIParams{'-u'}  = qq/$$parameters{'mailSubject'}/ if $$parameters{'mailSubject'};
113
   $CLIParams{'-s'}  = qq/$$parameters{'mailServer'}/  if $$parameters{'mailServer'};
114
   $CLIParams{'-xu'} = qq/$$parameters{'smtpUser'}/    if $$parameters{'smtpUser'};
115
   $CLIParams{'-xp'} = qq/$$parameters{'smtpPass'}/    if $$parameters{'smtpPass'};
116
   $CLIParams{'-cc'} = qq/$$parameters{'mailCC'}/      if $$parameters{'mailCC'};
117
   $CLIParams{'-bcc'}= qq/$$parameters{'mailBCC'}/     if $$parameters{'mailBCC'};
118
   $CLIParams{'-l'}  = qq/$$parameters{'logFile'}/     if $$parameters{'logFile'};
119
   $CLIParams{'-a'}  = qq/$$parameters{'attachment'}/  if $$parameters{'attachment'};
120
   $CLIParams{'-o tls='} = qq/$$parameters{'tls'}/     if $$parameters{'tls'};
121
 
122
   $commandLine = qq/$$parameters{'emailScript'}/;
123
   die "Could not find executable $commandLine in sendEmailScript\n" unless -x $commandLine;
124
   $commandLine .= ' -q'; # make it act quietly
125
   foreach my $key ( keys %CLIParams ) {
126
      # depending on whether the key ends in an = or not, we will or will not use a space
127
      # between the key and the parameter
128
      $commandLine .= $key =~ m/=$/ ? " $key'$CLIParams{$key}'" : " $key '$CLIParams{$key}'";
129
   }
130
   $commandLine .= ' ' . $$parameters{'otherCLParams'} if $$parameters{'otherCLParams'};
131
   open SENDMAIL, "|$commandLine" or die "Could not open [$commandLine]: $!\n";
132
   print SENDMAIL $report;
133
   close SENDMAIL;
134
} # sendReport
135
 
73 rodolico 136
sub sendViaSendmail {
137
   my ( $parameters, $report ) = @_;
138
   my @header;
139
   push @header, 'To: ' . qq/$$parameters{'mailTo'}/;
140
   push @header, 'From: ' . qq/$$parameters{'mailFrom'}/;
141
   push @header, 'Subject: ' . qq/$$parameters{'mailSubject'}/;
142
   $report = join( "\n", @header ) . "\n\n" . $report . "\n.\n";
75 rodolico 143
   open SENDMAIL, "|/usr/sbin/sendmail $$parameters{mailTo}" or die "could not open sendmail: $!\n";
73 rodolico 144
   print SENDMAIL $report;
145
   close SENDMAIL;
146
} 
147
 
148
 
149
 
150
 
32 rodolico 151
sub individualReport {
152
   my $data = shift;
153
   my @report;
154
 
155
   for my $key ( 'Device ID', 'Run Time', 'Files', 'Size (M)', 'Deleted', 'Skipped', 'Traffic (M)' ) {
156
      push @report, "$key: " . $$data{$key} unless $key eq 'mailto';
157
   }
158
   return join( "\n", @report );
159
}
160
 
73 rodolico 161
 
162
 
23 rodolico 163
########################################################################
164
# Main Program
165
########################################################################
166
 
167
# Read anything passed on STDIN to prepend to e-mail
168
while ( my $line = <> ) {
169
   $message .= $line;
170
}
171
 
172
my $configuration = &loadConfig( $confFileName, @searchPaths );
173
die "Could not find configuration file $confFileName in " . join( ', ', @searchPaths) . "\n" unless $configuration;
174
 
115 rodolico 175
my $dbh = DBI->connect('DBI:mysql:database=' . $$configuration{'database'}{'database'} . ';host=' . $$configuration{'database'}{'databaseServer'},
176
                       $$configuration{'database'}{'databaseUsername'},
177
                                              $$configuration{'database'}{'databasePassword'} )
178
                                                       || die "Could not connect to database: $DBI::errstr";
179
 
23 rodolico 180
 
115 rodolico 181
#my $dbh = DBI->connect('DBI:mysql:' . $$configuration{'database'}{'database'},
182
#                       $$configuration{'database'}{'databaseUsername'}, 
183
#                       $$configuration{'database'}{'databasePassword'} )
184
#         || die "Could not connect to database: $DBI::errstr";
185
 
23 rodolico 186
my $sth = $dbh->prepare( $count );
187
$sth->execute();
188
my $results = $sth->fetchrow_hashref();
189
$message .= "$results->{Count} reports in last 24 hours\n";
190
$sth->finish();
191
 
25 rodolico 192
$results = $dbh->selectall_hashref( $missing, 'ID' );
193
if ( %$results ) {
194
   $message .= '='x40 . "\nWARNING, no backup reports for the following machines\n" . '='x40 . "\n";
195
   foreach my $device ( keys %$results ) {
196
      $message .= sprintf( "%6d\t%s\n", $device, $results->{$device}->{name} );
197
   }
198
   $message .= '='x40 . "\n\n";
199
}
200
 
32 rodolico 201
# we're going to reuse the mail configuration for the individual reports
202
# if any, so let's save the mailTo and mailSubject
203
my $saveMailTo = $$configuration{'sendReport'}->{'mailTo'};
204
my $saveSubject = $$configuration{'sendReport'}->{'mailSubject'};
205
 
23 rodolico 206
$results = $dbh->selectall_hashref( $query, 'ID' );
93 rodolico 207
$message .= 'Device  Device Name                               Files Size (M) Delete   Skip     xfer  Start Time           Run Time' . "\n" . '='x40 . "\n";
79 rodolico 208
# following sorts the results by the name ('source'} field
209
foreach my $id ( sort { $results->{$a}->{'Source'} cmp $results->{$b}->{'Source'} } keys %$results ) {
93 rodolico 210
   $message .= sprintf( "%7u %-40s %6u %8.2f %6u %6u %8.2f %20s %9s\n",
25 rodolico 211
                  $results->{$id}->{'Device ID'} , 
212
                  $results->{$id}->{'Source'} , 
213
                  $results->{$id}->{'Files'} ,
214
                  $results->{$id}->{'Size (M)'} ,
215
                  $results->{$id}->{'Deleted'} ,
216
                  $results->{$id}->{'Skipped'} ,
93 rodolico 217
                  $results->{$id}->{'Traffic (M)'},
218
                  $results->{$id}->{'Start Time'},
219
                  $results->{$id}->{'Run Time'}
25 rodolico 220
               );
32 rodolico 221
   if ( $results->{$id}->{'mailto'} ) {
222
      $$configuration{'sendReport'}->{'mailTo'} = $results->{$id}->{'mailto'};
223
      $$configuration{'sendReport'}->{'mailSubject'} = 'Backup Report for ' . $results->{$id}->{'Source'};
73 rodolico 224
      if ( $$configuration{'sendReport'}{'emailScript'} ) {
225
         &sendReport( $$configuration{'sendReport'}, &individualReport( $results->{$id} ) );
226
      } else {
227
         &sendViaSendmail( $$configuration{'sendReport'}, &individualReport( $results->{$id} ) );
228
      }
32 rodolico 229
   }
230
 
23 rodolico 231
}
232
$dbh->disconnect();
32 rodolico 233
 
234
# reset mailTo and MailSubject to original values
235
$$configuration{'sendReport'}->{'mailTo'} = $saveMailTo;
236
$$configuration{'sendReport'}->{'mailSubject'} = $saveSubject;
237
 
238
 
239
#print $message;
73 rodolico 240
if ( $$configuration{'sendReport'}{'emailScript'} ) {
241
   &sendReport( $$configuration{'sendReport'}, $message );
242
} else {
243
   &sendViaSendmail( $$configuration{'sendReport'}, $message );
244
}
245
 
23 rodolico 246
1;