Jamnet has asked for the wisdom of the Perl Monks concerning the following question:

Dear Monks

Perl programs that I have written are more like cron jobs. They do the processing and exit. Only if there is an error then the message is shown and program exits. Now the problem I am facing is that I need to know the current status when the program is running (As I have been programming under windows and Dos). I am sure many of you must have faced this problem and must be following some style to display the status and so I request you all to advice me on the same. This will really help me and other programmers like me.

Regards

Jamnet

Replies are listed 'Best First'.
(jeffa) Re: perl program status
by jeffa (Bishop) on Apr 04, 2001 at 18:01 UTC
    Logfiles! Open a designated file and write a line containing the time and date, and whatever accurately describes what is being processed at the time.

    I program on *nix systems 99% of the time - I use the STDERR handle for this kind of thing. I am sure someone more enlightened with Win32 can explain more about how STDERR works with a Win32 system . . .

    Jeff

    R-R-R--R-R-R--R-R-R--R-R-R--R-R-R--
    L-L--L-L--L-L--L-L--L-L--L-L--L-L--
    
      i believe that on Win32 STDERR is the same as STDOUT. i could be wrong. humbly. nov.
        s/could be/am/;

        At least on Windows NT STDOUT and STDERR are quite separate, and you can redirect them pretty much as you would expect.

Re: perl program status
by arturo (Vicar) on Apr 04, 2001 at 18:08 UTC

    If you only have a few and you're on a *nix-type system, you can do the nifty /dev/tty trick, and have them redirect their status output to a certain terminal (call them in the cron job with foo.pl > /dev/tty9 or whatever makes sense. If you have a bunch, this can still work if you prepend the process' name to the message, e.g.

    print "$0:(", scalar localtime, ") : $message\n";

    Philosophy can be made out of anything. Or less -- Jerry A. Fodor

Re: perl program status
by Rhandom (Curate) on Apr 04, 2001 at 19:34 UTC
    I haven't tried this under Win32, but it is great under OS's that support it. You can try doing something like the following -- doesn't require any other files and it shows up on ps reports
    #!/usr/bin/perl exit if fork; my $dollar_0 = $0; $0 = "$dollar_0 (first)"; sleep(4); $0 = "$dollar_0 (second)"; sleep(4); $0 = "$dollar_0 (third)"; sleep(4);
    Try doing a ps and grep for the process while it is running, you should see it there nicely with its current status.
Re: perl program status
by Lexicon (Chaplain) on Apr 05, 2001 at 04:42 UTC
    I think I have a different take on what you're after than everyone else. I've written a few jobs that take an hour or so to finish, and I want to know that they're proceeding along smoothly. This is also pretty standard for debugging things in the first place, so if you set this up first it will help with your debugging and give you status afterwards. I assume you're doing everything at the command line and not TK or anything...

    First, build a standard subroutine to do all your output for you. Mine follows. It prints my status messages where I want them as well as the message index, the time, and the elapsed time.

    Before every major section, Log what you are about to do. Give the message a nice bold start so you know you're at a major heading. If you are processing and you want status of the processing, put an if statement in your loop and print some status every 1000 iterations or whatever is apropriate. If it's really heavy processing, the single if shouldn't slow you down too much, especially if you're calling subroutines, at least if Fundamental Benchmarks has any validity. Put some dashes in front of the message so you know you're in a subsection. I also like to throw in some extra processing to give me an Estimated Time To Completion. I have never ever seen this value be very accurate, as programs tend to slow down after a while of heavy processing. But I do it anyway.

    Hope this helps!

    my $Start_Time = time; my $LogFile = "logfile.log"; my $ProgressIndex = 1; my $i = 0; EnterIntoLog ("My freaky message"); $i *= $i for (1..10000000); EnterIntoLog ("Another message"); sub EnterIntoLog { my $message = shift; my $Now = time; my $Seconds_Past = int ($Now - $Start_Time); my $Minutes = int ($Seconds_Past/60); my $Seconds = $Seconds_Past % 60; my $ProgressString = sprintf ( "%05d\t" . localtime($Now) . "\t%02d:%02d\t$message\n", $ProgressIndex++, $Minutes, $Seconds); print $ProgressString; open LOG, ">>$LogFile" or die "Can't open $LogFile: $!\n"; print LOG $ProgressString or die "Can't print to $LogFile: $!\n"; close LOG or die "Can't close $LogFile: $!\n"; }

    -Lexicon

Re: perl program status
by grinder (Bishop) on Apr 05, 2001 at 11:43 UTC

    Coming in a bit late into the debate, but what the hell..

    A lot of my work looks like this too. Here are some rules of thumb I have come up with.

    • Get to know Getopt::Std or Getopt::Mixed, in order to drive your scripts with command-line switches.
    • One of those switches, especially from cronnable jobs, is "shut the fu%$ up" so that you don't get mail filling your inbox. If something does go wrong and you want to send mail alerts, use Mail::Sendmail and make your own report. When cron sends the unexpected output of a job it invariably lacks context to help you determine what blew up.
    • Write everything to a datestamped log file (this has already been mentioned).
    • Count the records, items, iterations, and print out "where you are" every n loops, such that you print something out every 10 seconds or so. That way it's easy to glance at a running script and determine if its wedged. Something like
      my $count = 0; while( 1 ) { print "\t$count\n" unless ++$count % 100_000; }
      and maybe add a few different state variables in there too.
    • In your log and/or results files, delimit things with tabs. Don't use commas or spaces, because they crop up far too often in real data and then it becomes a bear to parse downstream. Using tabs lets you hand the logfile to an end-user who can import it in Excel with no difficulty should they need to do their own processing on it.
    • Open your logfile in a BEGIN clause and close it in an END clause. This way even if you die you have a chance to scribble some last minute items into the logile.

    HTH


    --
    g r i n d e r
      Why do you write your own message?

      I use Carp, and sprinkle heavy calls to confess() with informative error messages. If I can't figure out what is going wrong from that, I assume that something more fundamental is at issue...

Re: perl program status - Try TK
by Anonymous Monk on Apr 05, 2001 at 00:41 UTC
    If you are in the windows world, you probably want to be consistent with that metophor and have your program status be printed into a window that the user can see. If you install tk, then play with the 'widget' demo that comes with the install, you will see a bouncing ball simulation. That proves that it's possible to 'multi-task' in a limited way within perl. You would probably want to make a large 'Text' widget and just write into that as you go. There's a tk command that I can't think of right now that will update the screen so that the user can see what you placed into the widget. It's a kind of 'yield' command. Oh, it's in the Tk::After docs: vwait or update. Alternatively, you can just use 'After' to run all you logic in which case as each piece of logic runs, it will return control to the screen briefly for a second, then the next 'after' kicks in.
Re: perl program status
by thabenksta (Pilgrim) on Apr 04, 2001 at 18:19 UTC