- Community Home
- >
- Servers and Operating Systems
- >
- Operating Systems
- >
- Operating System - HP-UX
- >
- Re: Route emails in a perl script
Categories
Company
Local Language
Forums
Discussions
Forums
- Data Protection and Retention
- Entry Storage Systems
- Legacy
- Midrange and Enterprise Storage
- Storage Networking
- HPE Nimble Storage
Discussions
Discussions
Discussions
Discussions
Forums
Discussions
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
- BladeSystem Infrastructure and Application Solutions
- Appliance Servers
- Alpha Servers
- BackOffice Products
- Internet Products
- HPE 9000 and HPE e3000 Servers
- Networking
- Netservers
- Secure OS Software for Linux
- Server Management (Insight Manager 7)
- Windows Server 2003
- Operating System - Tru64 Unix
- ProLiant Deployment and Provisioning
- Linux-Based Community / Regional
- Microsoft System Center Integration
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Community
Resources
Forums
Blogs
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
08-08-2011 05:12 PM - edited 08-08-2011 05:13 PM
08-08-2011 05:12 PM - edited 08-08-2011 05:13 PM
Route emails in a perl script
HI All,
Have a perl script which parses a file (FILE1 has a list of alerts) and sends an email in certain format.
Only thing I need is that for VIPS/hosts having the word test in it should send the email to test@foobar.com
and VIP/host having the word dev (eg. dev.corp.foobar.com) in it to dev@foobar.com
and VIPs having the name prod in it to prod@foobar.com. The subject needs to be different for each one.
FILE1:
***** Alert ***** Notification Type: PROBLEM Service: Appsname_2333_env1_region Host: vip-scv.corp.foobar.com Address: x.x.x.x State: CRITICAL Date/Time: Mon Aug 8 15:50:02 EDT 2011 Additional Info: CRITICAL - Socket timeout after 3 seconds Console http://foobar.com/nagios/index.php ***** Alert ***** Notification Type: PROBLEM Service: DiffAppsname_8552_env2_region2 Host: vip2-scv.corp.foobar.com Address: x.x.x.x State: CRITICAL Date/Time: Mon Aug 8 15:50:02 EDT 2011 Additional Info: CRITICAL - Socket timeout after 3 seconds Console http://foobar.com/nagios/index.php
PERL SCRIPT:
#!/usr/bin/perl -w use strict; my ($apps,$email,$host); open(HM,"<","/var/tmp/email") or die "Fail- $!\n"; open(WM,">","/var/tmp/email_text") or die "Fail- $!\n"; while(<HM>) { chomp; $apps = $1 if /Service:(.*)/; $host = $1 if /^Host:(.*)/; if (/Date\/Time:(.*)/) { printf WM "%s:%s:%s\n",$apps,$host,$1; } } seek HM,0,0; print WM <HM>; $email='mail -s "alerts from past 4 mins" user@foobar.com < /var/tmp/email_text 2>/var/tmp/email_err'; system($email); if ( $? ne 0 ) { die "Failure - while sending email. Please check file /tmp/email_err \n"; } close(WM); close(HM); unlink "/tmp/email" or warn "Could not unlink email: $!";; unlink "/tmp/email_text" or warn "Could not unlink email_text: $!";;
Thanks,
Allan.
- Tags:
- Perl
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
08-08-2011 10:48 PM
08-08-2011 10:48 PM
Re: Route emails in a perl script
I would add an associative array to the perl script to map hosts to email addresses.
As you process a host, start with a generic Email address.
Replace by a specific one, if it matches a key in the array.
Glue the selected email address in the email command.
Untested example below.
Hope it works...
Hein
#!/usr/bin/perl -w
use strict;
my %email_map = (dev => 'dev@foobar.com', test => 'test@foobar.com', prod=> 'prod@foobar.com');
my ($apps,$email,$host, $email_address);
open(HM,"<","/var/tmp/email") or die "Fail- $!\n";
open(WM,">","/var/tmp/email_text") or die "Fail- $!\n";
while(<HM>) {
chomp;
$apps = $1 if /Service:(.*)/;
$host = $1 if /^Host:(.*)/;
if (/Date\/Time:(.*)/) {
printf WM "%s:%s:%s\n",$apps,$host,$1;
}
}
seek HM,0,0;print WM <HM>;
$email_address = 'user@foobar.com';
for (keys %email_map) { $email_adress = $email_map{$_} if $host =~ /^\s*$_/;
$email='mail -s "alerts from past 4 mins" ' . $email_adress . ' < /var/tmp/email_text 2>/var/tmp/email_err';system($email);
if ( $? ne 0 ) {
die "Failure - while sending email. Please check file /tmp/email_err \n";
}
close(WM);
close(HM);
unlink "/tmp/email" or warn "Could not unlink email: $!";;
unlink "/tmp/email_text" or warn "Could not unlink email_text: $!";;
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
08-09-2011 07:48 AM
08-09-2011 07:48 AM
Re: Route emails in a perl script
OK, I'll bite ...
use strict; use warnings; use Mail::Sendmail; my $alerts = do { local ($/, @ARGV) = (undef, "alerts.txt"); <> }; my @alerts = split m/\s*\Q***** Alert *****\E\s*/ => $alerts; my ($from, $to) = ('reporter@my.site.com', 'user@foobar.com'); my @summ; for (@alerts) { my %tag = (m/^\s*(\S+)\s*:\s*(.*?)\s*$/gm) or next; push @summ, "$tag{Service}:$tag{Host}:$tag{'Date/Time'}\n"; $tag{Host} =~ m/\b test \b/ix and $to =~ s/user/test/; $tag{Host} =~ m/\b dev \b/ix and $to =~ s/user/dev/; $tag{Host} =~ m/\b prod \b/ix and $to =~ s/user/prod/; } sendmail ({ To => $to, From => $from, Subject => "Alerts from past 4 mins", Message => join "\n", @summ, $alerts, }) or die $Mail::Sendmail::error;
This is about what I deduced from your code. I'll leave it up to you to make the change to the subject based on the recipient.
What I did was
1. Read the complete alerts file. (you parsed it twice)
2. Split the alerts into chuncks
3. create a summary line for each chunk
mail the summary and the complete body to the recipient. The recipient is default 'user' and is changed on the first host that matches any of the threee criteria you asked for.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
08-09-2011 01:03 PM - edited 08-09-2011 01:10 PM
08-09-2011 01:03 PM - edited 08-09-2011 01:10 PM
Re: Route emails in a perl script
Thanks Hein,
Can the subject append the word dev, test & prod to the subject line?
Its currently not sending the alerts to specific email ids but rather to the default one.
It would be great if it can.
Regards,
Allan.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
08-09-2011 02:01 PM
08-09-2011 02:01 PM
Re: Route emails in a perl script
Sure...
Again untested...
my $subject = 'alerts from past 4 mins';
$email_address = 'user@foobar.com';
for (keys %email_map) {
if ( $host =~ /^\s*$_/ ) {
$email_adress = $email_map{$_};
$subject .= " from $_";
}
$email = "mail -s \"$subject \" $email_adress . < /var/tmp/email_text 2>/var/tmp/email_err";
system($email);
fwiw,
Hein
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
08-09-2011 02:22 PM
08-09-2011 02:22 PM
Re: Route emails in a perl script
Not getting any emails now :(
Earlier I got the same email four times to the default user.
Can you test out at your end and see what the problem could be... I have given the sample file above.
Thanks,
Allan.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
08-09-2011 06:34 PM
08-09-2011 06:34 PM
Re: Route emails in a perl script
Hi:
Hein's original post(s) mis-spelled "$email_address" [ which the 'strict' pragma would have told you ] and as an untested post, lacked a closing brace. HIS SCRIPT should (likely) be:
#!/usr/bin/perl use strict; use warnings; my %email_map = (dev => 'dev@foobar.com', test => 'test@foobar.com', prod=> 'prod@foobar.com'); my ($apps,$email,$host, $email_address); open(HM,"<","/var/tmp/email") or die "Fail- $!\n"; open(WM,">","/var/tmp/email_text") or die "Fail- $!\n"; while(<HM>) { chomp; $apps = $1 if /Service:(.*)/; $host = $1 if /^Host:(.*)/; if (/Date\/Time:(.*)/) { printf WM "%s:%s:%s\n",$apps,$host,$1; } } seek HM,0,0;print WM <HM>; my $subject = 'alerts from past 4 mins'; $email_address = 'user@foobar.com'; for (keys %email_map) { if ( $host =~ /^\s*$_/ ) { $email_address = $email_map{$_}; $subject .= " from $_"; } $email='mail -s "alerts from past 4 mins" ' . $email_address . ' < /var/tmp/email_text 2>/var/tmp/email_err';system($email); if ( $? ne 0 ) { die "Failure - while sending email. Please check file /tmp/email_err \n"; } } close(WM); close(HM); unlink "/tmp/email" or warn "Could not unlink email: $!"; unlink "/tmp/email_text" or warn "Could not unlink email_text: $!";
Regards!
...JRF...
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
08-10-2011 11:20 AM
08-10-2011 11:20 AM
Re: Route emails in a perl script
Some of it I had figured, also I am a little concerned about the unlinks down below, that it deletes the files even though the program is successful or not.
Regards,
Allan.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
08-10-2011 11:57 AM
08-10-2011 11:57 AM
Re: Route emails in a perl script
@allanm77 wrote:
I am a little concerned about the unlinks down below, that it deletes the files even though the program is successful or not.
Hi Alan:
First, thank Hein. I just fixed up some of his untested syntax. As for the unlink()'s, you don't know that the mail will ever be delivered or not, so everything is on-faith. Because the files in question live in '/var/tmp', the inference is that they aren't critical to anything but this process.
If, for whatever reason, you feel that removing them isn't what you want to do, you could simply rename() them, leaving their eventual cleanup to a routine purge (with 'find') of '/var/tmp' .
In fact, you actually have used to different paths in your script! You 'open()' in '/var/tmp' but 'unlink()' from '/tmp'. A better way to avoid this is to declare variables (or constants) with the file names. Then, by example, you could do this to rename the file or files you want to keep:
my $HM_name = '/var/tmp/email'; my $WM_name = '/var/tmp/email_text'; #... my ($mon,$mday,$year) = (localtime)[4,3,5]; my $suffix = sprintf "_%02d%02d%04d", $mon+1, $mday, $year+1900; rename $HM_name, $HM_name . $suffix; 1;
Regards!
...JRF...
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
08-10-2011 04:56 PM
08-10-2011 04:56 PM
Re: Route emails in a perl script
Have another question about the original perl script (from above), I want to use that on three to four different files -
/var/tmp/email & /var/tmp/email_new & /var/tmp/email_newer
with same logic and probably send to different userids with different subjects.
I tried to keep that in the same script but struggled with die statements which used to close the program if it couldn't find the one of the file.
Thanks,
Allan.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
08-10-2011 06:36 PM
08-10-2011 06:36 PM
Re: Route emails in a perl script
@allanm77 wrote:
Have another question about the original perl script (from above), I want to use that on three to four different files -
/var/tmp/email & /var/tmp/email_new & /var/tmp/email_newer
with same logic and probably send to different userids with different subjects.
I tried to keep that in the same script but struggled with die statements which used to close the program if it couldn't find the one of the file.
Currently you 'die' (with the reason for the death) if you can't open a file. That's one way. I would construct your 'open...or die...' like this, though:
... my $HM_name = '/var/tmp/email';
open NM, .'<', $NM_name or die "Can't open '$NM_name': $!\n";
...
You can also test for the presence of a file and only if present, open it:
if ( -e $NM_name ) { open NM, '<', $NM_name or die "Can't open '$NM_name': $!\n"; } else { ... }
Notice how we defined the file name as a variable for consistent use throughout, too. If it's wrong in one place, its the same "wrong" everywhere :-)
In the second example code where we test for file existence we are ignoring a race condition where a file does indeed exist and the test is satisfied, but the open fails (and you die) because when that's atttempted another process has removed the file. I don't believe that you need to worry in a case like this, but you should be aware of the potential if only in the abstract.
Regards!
...JRF...