in reply to read from network security log file and display lines as alert boxes
As other monks have already noticed, it would be annoying to pop-up a new alert-box every time a new incident occurred. Maybe it would be more convenient to have just a single scrollable window, so you can see all incidents that occurred during the last check-interval together with the history of previous events? The window would pop-up or would otherwise call for attention when new incidents happen.
As suggested by lostjimmy, File::Tail would be suitable to check for new lines only and even cope with log-rotation. Thus, re-reading the whole log file is not necessary at all. Furthermore, busy waiting is reduced/avoided.
The following Perl/Tk snippet (partly borrowed from Adding the output of tailf -f filename to Tk widget (scrolled)) may give an impression. I hope, the File::Tail::select stuffs works under Windows (sorry, cannot test this here). You might need to tweak the timeouts according to your needs (see: File::Tail). It would have been nice to use Tk::fileevent, but I couldn't manage to make it work with File::Tail :( - anyway, it's a demo. OTOH, the current polling-approach allows you to define a minimum time period uninterrupted from this log watcher (currently: 5s).
#!/usr/bin/perl use strict; use Tk; use File::Tail; my $tail = File::Tail->new(name => "./log2.txt", tail => 150); my $main = MainWindow->new(-title => "Hacker Alert"); my $t = $main->Text(-wrap => 'none')->pack(-expand => 1); my $b = $main->Button( -text => "Quit", -width => 10, -command => \&bye, ); $b->pack(qw/-side right -expand yes -pady 2/); my $b2 = $main->Button( -text => "Hide", -width => 10, -command => sub { $main->iconify }, ); $b2->pack(qw/-side left -expand yes -pady 2/); # check every 5000ms for new events... $main->repeat(5000, [\&collect_lines,$t]); $main->iconify; MainLoop; sub bye { $main->destroy; Tk::exit; } # reap lines arrived during last $main->repeat(...) sub collect_lines { my ($w) = @_; my $timeout = 0.01; my @lines; while (1) { my ($nfound, $timeleft, @pending) = File::Tail::select(undef,undef,undef,$timeout,($tail)); last unless $nfound; # timeout - nothing more to read push @lines, $pending[0]->read; } fill($w,@lines) if @lines; } # update the text widget { my $time = "n/a"; # last timestamp seen (assumes correct log syntax) sub fill { my ($w, @lines) = @_; return unless @lines; # nothing to do foreach (@lines) { $time=$1, next if /^Time:\s*(\S+)/; if ( /(\s+)(\d{1,4})(\.\d{1,4}){3}(\s+)/ ) { $w->insert('end',"[$time] $_"); $w->yview('end'); $time = "n/a"; } } # do annoing stuff to get attention $main->Popup; $main->bell; # $main->focus(); # bah! } }
BTW: Your sample log format looks like snort output? In that case, POE::Filter::Snort looks promising, although it might be overkill for your task - you decide...
|
|---|