Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things

POE, was Re: Tk tail -f - How?

by RMGir (Prior)
on Oct 09, 2003 at 10:47 UTC ( #297870=note: print w/replies, xml ) Need Help??

in reply to Tk tail -f - How?

Take a look at POE, specifically POE::Wheel::FollowTail and POE's Tk integration.

There's an example for POE::Wheel::FollowTail in the POE Cookbook, as well as a POE::Tk example.

You mentioned filtering, though. If you're going to have a lot of lines that you need to drop, you might want to use POE::Wheel::Run instead of FollowTail, and filter the lines in a helper process, using one of the tail -f techniques in the other replies. POE fires an event for every line of input, so if you're going to discard a lot of lines, it's cheaper to do it outside of the POE framework.

(Edit: I forgot to mention, you may want to try typing

perldoc -q "tail -f"
The technique described there should work on Win32 as well as anywhere else, but you'd also have to add a watch to simulate the --follow behaviour if the file is rotated.)

Replies are listed 'Best First'.
Re: POE, was Re: Tk tail -f - How?
by msemtd (Scribe) on Oct 09, 2003 at 12:22 UTC
    Thanks all,
    I put the following together using the tips from perldoc -q "tail -f". As a POE user I was under the impression that the Tk tail would fail on Win32 due to the lack of fileevent - I haven't used it recently so it may be fixed.

    This first version hangs onto the filehandle as you say so it needs some thought to emulate --follow=name.

    #! perl use strict; use warnings; use Tk; # my $file = "C:\\openejb-0.8.3\\openejb.log"; # my $title = "Tk Tail"; my $version = "1.0"; my $mw = new MainWindow( -title => $title ); # Nicer fixed-width font... $mw->fontCreate( 'listboxfont', -family => 'courier', -size => '8' ); my $fr = $mw->Frame()->pack( -expand => 1, -fill => 'both' ); # $fr->Label( -text => "File to tail" )->pack; $fr->Entry( -textvariable => \$file, -width => '50', -font => 'listboxfont', )->pack; $fr->Button( -text => 'GO', -command => \&gopush )->pack; my $listbox = $mw->Scrolled( 'Listbox', -setgrid => '1', -height => '10', -width => '50', -font => 'listboxfont', -selectmode => 'extended', -scrollbars => 'se', -bg => 'black', -fg => 'green', ); $listbox->pack( -expand => 'yes', -fill => 'both', -pady => '3' ); my $fr_statusbar = $mw->Frame( -relief => 'sunken', -borderwidth => '1', )->pack( -fill => 'x' ); #~ $fr_statusbar->Label( -image => $smallicon )->pack(-side => 'left') +; $fr_statusbar->Label( -text => "Version: $version" )->pack( -side => ' +left' ); # sub gopush { close F; open F, '<', $file or die $!; timerstart(); } # repeating actions... my $timerid; sub timerstart { &timerstop(); $timerid = $mw->repeat( 1000, \&timerproc ); } sub timerstop { if ($timerid) { $timerid->cancel; } } sub timerproc { while (<F>) { chomp; my $text = $_; $listbox->insert( 'end', $text ); $listbox->see('end'); $mw->update(); } seek( F, 0, 1 ); } MainLoop();

      You might want to add a check for the number of lines you have in the listbox and limit it to some reasonable size.

      If your file grows quickly, you could rapidly find yourself running out of memory, and (if my limited experience of Tk is still valid) things start to slow down when widgets grow beyond a certain size.

      It would be more efficient to load the listbox using

      $listbox->insert( 'end', <F> ); $listbox->see( 'end' ); $mw->update();

      Also, you probably shouldn't be seeking to the end after you have read. If nothing has been added, it will make no difference as you will already be there. However, if something was added between the last read and the seek, you will never read it and lines (or partial lines) will be lost..

      Examine what is said, not who speaks.
      "Efficiency is intelligent laziness." -David Dunham
      "Think for yourself!" - Abigail

        Of course :) after insert task I have added...
        my $trim = $listbox->size - $maxlines; $listbox->delete(0, $trim-1) if trim > 0;
        I accept the point re last-read-to-seek-delay-data-loss: any ideas anyone?

        Otherwise I don't see any harm with the seek(F,0,1) - isn't it required in order to clear the EOF condition as per docs?

      As a POE user I was under the impression that the Tk tail would fail on Win32 due to the lack of fileevent - I haven't used it recently so it may be fixed.

      It is fixed in the latest release, version 0.27. POE works around ActivePerl's Tk fileevent problems by polling internally. All the usual I/O methods (select_{read,write}, the Wheel classes, and Components) should magically start working after an upgrade.

      -- Rocco Caputo - -

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://297870]
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others making s'mores by the fire in the courtyard of the Monastery: (5)
As of 2020-10-29 13:45 GMT
Find Nodes?
    Voting Booth?
    My favourite web site is:

    Results (271 votes). Check out past polls.