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

I'm running one of my scripts in the background and I need to get some diagnostic output from it. This is output that would be used in production so I'd prefer the interaction to be somewhat simple.

I had planned on putting in a signal handler whereby I could:

'kill -USR1 pid'

and have it spit the information out to the terminal. The problem is, if I run the program in the background and log out, it has no associated terminal to output to when I log back in. As a result, any print statements go straight to the bit bucket as far as I can tell. Is there any way to do this in a reasonably sane manner?

  • Comment on Diagnositc output on background processes

Replies are listed 'Best First'.
Re: Diagnositc output on background processes
by dga (Hermit) on Aug 25, 2001 at 00:55 UTC

    Some thoughts.

    You should know that signal handlers are not fully safe to do much in especially printing.

    You probably want to set a flag in your handler and return. Then check the flag in your main code and write out relevant info and clear the flag.

    As for reconnecting output with your terminal, I think you should look along the lines of an output file then in your session tail -f the file or look into syslog which can recieve messages from programs and then send them to users (you) when they are logged in. Messages collected while you are not logged in are tossed though unless you also have syslog send those messages to some file, which brings us back to the first method.

      Note that signals in Perl aren't safe even if you just set a flag. This is being fixed but I'm not sure when it will be released. So I'd avoid the signal handler altogether when using Perl.

      You could just have a separate file that you periodically

      seek(STATUS,0,0); truncate(STATUS,0); print STATUS, status();
      and be sure to include a time stamp in that output (and be sure to turn on autoflush).

      Another fun idea is to listen on a socket and occasionally do a non-blocking accept. If the accept succeeds, then you can output status information via the socket so anyone can "telnet" to that port to see how things are going. Our long-running servers have telnet interfaces where you can not only get detailed status information but also change configuration information, reset statistics, etc. Though doing something like that is a bit tricky in Perl since threading support is still experimental.

              - tye (but my friends call me "Tye")
Re: Diagnositc output on background processes
by jlongino (Parson) on Aug 25, 2001 at 00:39 UTC
    I'm not sure if I understand what you want, but why can't you just write the output to a log file?

    If necessary, create a:

    END { # write output to a file here }

    But I would just write to the log file as soon as I obtained the data and then use the END {} block to flush whatever might be left in the buffer.

    If the code and the comments disagree, then both are probably wrong. -- Norm Schryer

      Thanks for the great suggestions.

      I had considered that method and, indeed, that's how I've got it implemented now. The problem is that it already has a pretty substantial log file and the diagnostic stuff tends to get lost in the noise. I would prefer something that outputs right to the screen. Is such a thing possible? I'm running perl 5.6.1 on FreeBSD 4.3-Release if that makes any difference.

        Well, you could always create a separate diagnostics log file and use a different "monitor" script that simply monitors the size of the diagnostics file and then tails/echoes any new lines when detected to the screen.

        I have a script that does this for my backup job stream. When the backup job kicks off it appends whatever is in the daily log file, to the cumulative log file, deletes the daily log, kicks off the monitor job to run in the background and appends any new output to the daily log file. The monitor job echoes everything that is appended to the daily log file to the screen. It even repeats the last line periodically so that the operators can see if something is hung or not. In my case though, the monitor job only runs as long as its parent job is running. But if the terminal session hangs/dies/whatever the log file still has all the diagnostics.

        If you like, I could post both backup and monitor scripts, so you could see how they interact.

        If the code and the comments disagree, then both are probably wrong. -- Norm Schryer

Re: Diagnositc output on background processes
by Monky Python (Scribe) on Aug 25, 2001 at 11:38 UTC
    it's also possible to write to a given tty like:
    ## ## print output to given tty ## $tty = $ARGV[0]; open(OUTPUT, "> /dev/$tty") || die ("can't open device: $!\n"); print OUTPUT "Hi, what's going on?\n"; close(OUTOUT);

    you can get the tty from a terminal by the mighty "tty"-command.

    MP

Re: Diagnositc output on background processes
by larryk (Friar) on Aug 25, 2001 at 00:50 UTC
    write to a log file and then tail -f it when you need to see what's going on.
       larryk                                          
    perl -le "s,,reverse killer,e,y,rifle,lycra,,print"