This is one those things I've started but never came to an end with. It's a proof of concept - so there ist plenty space for improvements.
In my node: Exchange Log Analyzer - I showed you a CGI-based log-analyzer for exchange-logfiles. As an add-on I'd liked to do some visualization - but never get more far than this (working) snippet:
#!/usr/bin/perl
use strict;
use warnings;
use Graph;
use Graph::Writer::Dot;
use Data::Dumper;
my $file = shift || '20040621.log';
as_graph(bloat($file, 'yahoo', 19));
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_graph {
my $rows = shift || die "as_graph() need a hashref";
my $graph = Graph->new();
my $i = 0;
my @from;
foreach my $from (keys %$rows) {
$from[$i] = $from;
my $k = 0;
my @to;
foreach my $id (keys %{$rows->{$from}}) {
$to[$k] = $rows->{$from}->{$id}->{to};
$graph->add_edge("from$i" => "to$i$k");
$graph->set_attribute("label", "from$i", "$from[$i]");
$graph->set_attribute("label", "to$i$k", "$to[$k]");
$graph->set_attribute("color", "to$i$k", "green");
my @events = @{ $rows->{$from}->{$id}->{events} };
for (my $j = 0; $j != $#events; $j++ ) {
$graph->add_edge("to$i$k" => "event$i$k$j");
$graph->set_attribute("label", "event$i$k$j",
"$events[$j]->{event}\\n$events[$j]->{date}\\n$events[$j]->{ti
+me}");
$graph->set_attribute("color", "event$i$k$j", "blue");
#$graph->set_attribute("color", "event$i$k$j", "red")
# if ($events[$j]->{event} == 1023); # colorize special event
}
$k++;
}
$i++;
}
my $writer = Graph::Writer::Dot->new();
$writer->write_graph($graph, 'file.dot');
system('dot -Tpng file.dot -o file.png');
system('C:\Programme\IrfanView\i_view32.exe file.png');
}