[Vienna-pm] Logger: Threads, STDERR und Pipes?

rs at ednet.at rs at ednet.at
Fri Jun 27 09:54:45 CDT 2003


Hallo !

Da mich auf der Luga hingewiesen wurde, mich doch in Perl-Fragen an die
pm's zu wenden hab ich mich jetzt mal hier angemeldet *ggg*


Ich hab das Problem, dass ich von (groesstenteils!) Perl Programmen STDERR
abfangen, herumwurschteln und dann irgendwohin ausgeben muss.

Dafuer hab ich mir schon vor laengerer Zeit ein Error-Package geschrieben,
dass mir dann den STDERR-Output in ein File, auf STDERR, oder ins Syslog
(auch gleichzeitig in mehrere Ziele) schreibt.

Der Output kann auch waerend eines Programmlaufs wechseln: Zb. zuerst nur
STDERR, dann 300x File+STDERR, und zuletzt wieder nur nach STDERR.

Auch kann ich angeben wie geloggt werden soll: as-is, mit vorgesteltem
Timestamp, mit Timestamp+$0+Pid, usw...


Mein erster Ansatz war, dass ich mir Error:warn und Error::die-Funktionen
gebaut hab, die schreiben. Problem: Manche Module (zb. DBI) rufen einfach
warn auf -> mein Error-File war daher leer, und stdout nicht mehr
zuordnebar (weil keine Timestamps, $0, ...). Beim System-Aufruf eines
(nicht Perl) Programms bekomme ich auch nur Daten von STDERR...


Also zweiter Anlauf: mit SIG{__WARN__} und SIG{__DIE__} Hooks setzen die
schreiben. 

Problem: Was passiert wenn ich fork'e und die Handler auch in ein File
loggen? 'Handler' forken dann auch und Schreiben dann beide muell ins
(gleiche!) error-File??? Das Problem beim System besteht weiterhin.


Dritter Ansatz: Jedesmal wenn ich den Error::output festlege, leite
ich STDERR in eine Pipe um, und lasse von einem Child-Prozess (fork)
die Daten formatieren und schreiben. Daten von 'system(prog)' landen so
(endlich) auch im Error-File.

Problem: Es gibt da so ueberaus intelligente Module (wie zb. DBI) die
schliessen die DB-Handles wenn der Child terminiert. Dh, mache ich ein
DBI-Handle auf, aendere dann Erorr::output (=1. Child, der dann natuerlich
DBH erbt) und dann nochmal Error::output (=2. Child) dann beendet der
erste Child und schliesst mir das DB-Handle. Das Verhalten koennte man
zwar im Child aendern, dazu muesste ich aber dem Child alle offenen
DBI-Handles uebergeben...


Vierter Ansatz - Zauberwort Threads: Dupliziere STDERR, starte einen
Thread der von einer Pipe liest und ins duplizierte STDERR (und File,
und Syslog...) schreibt und verbiege dann STDERR in die Pipe.

Problem: Wie bende ich den Thread (der einfach in einem 'while <READER>'
haengt) damit ich nich jedesmal diese 'A thread exited while 2 other
threads were still running.'-Meldung bekomme?

1. Versuch:

my $R : shared;
my $W : shared;
pipe $R $W      <- "Invalid value for shared scalar"

Geht nicht. Daher uebergebe ich dem Thread einfach die fileno() und mach
im Thread dann ein:

my $reader = new IO::Handle; $reader->fdopen($readerFileno, 'r')
my $stderr = new IO::Handle; $stderr->fdopen($stderrFileno, 'w');

Dummerweise reicht dann aber ein 'close pipe' im Hauptprogramm nicht mehr
aus um den Child aufzuwecken und zu beenden - oder kann man perl
irgendwie dazu bewegen, ein Filehandle ueber die fileno() zu
schliessen?

Zetzt hab ich mir ein 'CLOSE_COMMAND' gebaut, mit dem ich den Child
anweise jetzt zu benden. Diese CLOSE_COMMAND setze ich dann in einem END
{}-Block auf die Pipe ab. Nich sauber, aber es finktioniert soweit mal :-(


Ausserdem ist bei all den Ansaetzen immer noch das Problem ungeloest,
wenn ich von mehreren Prozessen ins gleiche File schreiben will - kommt
zwar noch nicht vor, werde ich daber bald brauchen :-(

Ich denke mal dieses File-Problem koennte ich nur loesen, indem ich den
File-Writer in einen eigenstaentigen Prozess lege (daemon) der dann ueber
einen Socket angesprochen wird...


Oder hab ich mich mit meiner Problemstellung voellig verrannt und ich
brauche nur ein 'use GoodLikeLogger'???


Liebe Gruesse, Schroettner Robert

|   Schroettner Robert
|   IT-Services
|   Eurodata Datenverarbeitungsdienst Ges.m.b.H.  __   _
|   Tel:  +43-1-7747076-51                       / /  (_)__  __ ____  __
|         +43-664-4345798                       / /__/ / _ \/ // /\ \/ / 
|   Fax:  +43-1-7747076-12                     /____/_/_//_/\_,_/ /_/\_\
|   WWW:  http://www.ednet.at                           TUX for President
|
|   EURODATA - WIEN - PRAG - BRUENN - BUDAPEST - BUCAREST




More information about the Vienna-pm mailing list