A friend of mine uses the MS Exchange server. He searched a way to analyze his log-files. He sent me some sample data and I build this small log-analyzer. It offers to select a .log-file and to choose a field to search within. The result is presented in a hierarchical way (sender->mails->events).
#!/usr/bin/perl use strict; use warnings; use CGI; use CGI::Carp qw( fatalsToBrowser warningsToBrowser ); use HTML::Template; my $q = new CGI; print $q->header(), as_html($q); exit(); sub bloat { my $file = shift; my $search = shift; my $field = shift; my $rows = {}; open (FILE,"$file") || die "Error opening $file, RC=$!"; while (<FILE>) { next unless $. > 3; chomp; my @line = split /\t/, $_; next unless @line; my ($date, $time, $to, $id, $subject, $from, $event ) = @line[0,1,7,9,18,19,8]; $date =~ s/^(\d{4})\D(\d+)\D(\d+)$/$3.$2.$1/o; $time =~ s/\s+\w+$//o; if ($line[$field] =~ /$search/i) { $rows->{$from}->{$id} = {from => $from, to => $to, subject => $subject, id => $id} unless exists $rows->{$from}->{$id}; $rows->{$from}->{$id}->{events} = [] unless exists $rows->{$from}->{$id}->{events}; push @{$rows->{$from}->{$id}->{events}}, {event => $event, date => $date, time => $time,}; } } close (FILE); return $rows; } sub flatten { my $row = shift; my $set = []; @$set = map { from => $_ }, (keys %{$row}); for my $from (@$set) { push @{$from->{id}}, $_ for (keys %{$row->{$from->{from}}}); for my $msg (@{$from->{id}}) { push @{$from->{message}}, $_ for ($row->{$from->{from}}->{$msg}) +; } } return $set; } sub as_html { my $q = shift; my $template = HTML::Template->new( filename => "report_exch.tmpl", die_on_bad_params => 0, ); $q->param('action') eq 'analyze' ? $template->param( what => flatten(bloat($q->param('file'), $q->param('search') , $q->param('field') +))) : $template->param( results => 'FALSE'); my @files = map { {file=>$_,} } <*.log>; $template->param( logs => \@files ); $template->param( fields => selection() ); return $template->output; } sub selection { my @fields = qw (0 1 7 9 18 19 8); my @result = map { {option => $_, value => shift @fields} } qw (date time to id subject from event); return \@result; }
I use HTML::Template to separate code from content.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Entwurf V2.0</title> <meta name="author" content="Ronnie Neumann" /> <meta name="generator" content="Perl-Script using HTML::Template" /> <style type="text/css" media="all"> .inner { border-style: solid; border-width: 1px; border-color: #000080; background-color:#FFFFDD; visibility: hidden; position: absolute; margin: 5px; padding: 5px; } body { border-style: solid; border-width: 1px; border-color: #AAAAAA; background-color:#FFFFDF; padding: 3px; margin: 5px; } form { border-style: solid; border-width: 1px; border-color: #AAAAAA; background-color:#DDDDFF; padding: 2px; } </style> <script type="text/javascript"> <!-- function toggle(elementname) { /*if (document.getElementById(elementname).style.visibility == "" ) { document.getElementById(elementname).style.visibility = "visible";}*/ if (document.getElementById(elementname).style.visibility == "visible +" ) { document.getElementById(elementname).style.visibility = "hidden"; document.getElementById(elementname).style.position = "absolute"; //document.getElementById(elementname).style.left = "0px"; //document.getElementById(elementname).style.top = "0px"; } else { document.getElementById(elementname).style.visibility = "visible" +; document.getElementById(elementname).style.position = "relative"; } ; } // --> </script> </head> <body> <form method="POST" action="report_exch.pl"> <select name="file"> <TMPL_LOOP NAME="logs"> <option value="<TMPL_VAR NAME="file">"><TMPL_VAR NAME="file"></optio +n> </TMPL_LOOP> </select> <select name="field"> <TMPL_LOOP NAME="fields"> <option value="<TMPL_VAR NAME="value">"><TMPL_VAR NAME="option"></op +tion> </TMPL_LOOP> </select> search for:&nbsp; <input type='Text' name='search' size='20' maxlength='20' /> <input type="submit" value="analyze" name="action" /><br /> </form> <TMPL_UNLESS NAME="results"> <div id="analyze"> <TMPL_LOOP NAME="what"> Sender: <strong><TMPL_VAR NAME="from"></strong><br /> <a href="javascript:toggle('<TMPL_VAR NAME="from">');">show/hide m +ails</a> <div id="<TMPL_VAR NAME="from">" class="inner"> <TMPL_LOOP NAME="message"> <br />Recipient:&nbsp;<strong><TMPL_VAR NAME="to"></strong><br /> Subject:&nbsp;&nbsp;&nbsp;<strong><TMPL_VAR NAME="subject"></stron +g><br /> <a href="javascript:toggle('<TMPL_VAR NAME="id">');">show/hide eve +nts</a><br /> <table border="1" id="<TMPL_VAR NAME="id">" class="inner"> <tr><th>Date</th><th>Time</th><th>Event-ID</th></tr> <TMPL_LOOP NAME="events"> <tr><td><TMPL_VAR NAME="date"></td><td><TMPL_VAR NAME="time">< +/td><td><TMPL_VAR NAME="event"></td></tr> </TMPL_LOOP> </table> </TMPL_LOOP> </div> <hr /> </TMPL_LOOP> </div> </TMPL_UNLESS> </body> </html>
Of course there is room for further improvements. I'd be glad to hear some suggestions.

neniro


In reply to Exchange Log Analyzer by neniro

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.