15

インターネットを検索したところ、STDOUT を 2 つの異なる場所に接続するための適切な解決策がいくつか見つかりました。ログファイルと画面を同時に表示します。一例を次に示します。

use IO::Tee;
my $log_filename = "log.txt";
my $log_filehandle;
open( $log_filehandle, '>>', $log_filename )
  or die("Can't open $log_filename for append: $!");
my $tee = IO::Tee->new( $log_filehandle, \*STDOUT );
select $tee;

しかし、この解決策では、STDERR は画面のみに表示され、STDERR は画面と、STDOUT が記録されている同じログ ファイルの両方に表示されます。それは可能ですか?

私の仕事は、ビルド プロセスをログに記録することですが、通常どおり IDE の画面にも表示したいと考えています。また、エラー メッセージをログに記録することは、ハッピー メッセージをログに記録することと同じくらい重要です。また、エラーを別のログ ファイルに記録することは、適切な解決策ではありません。

4

8 に答える 8

13

私はこのようなことにLog::Log4perlを使用しています。画面、ファイル、データベース、またはその他の好きなものを含む、複数の場所への出力の送信を処理します。少しでも複雑になったら、自分でこれを行うべきではありません。

ファイルハンドルに出力する代わりに、Log4perl にメッセージを与えるだけで、あとは理解してくれます。Mastering Perlで簡単に紹介しています。これは Log4j に基づいており、Log4j で実行できることのほとんどは Log4perl でも実行できます。つまり、一度理解すれば、それは移転可能なスキルになります。

于 2009-10-07T16:22:15.993 に答える
8
use PerlIO::Util;
*STDOUT->push_layer(tee => ">>/dir/dir/file");
*STDERR->push_layer(tee => ">>/dir/dir/file");

私はLog::Dispatchを広範囲に使用していますが、実際に画面に表示されたものをファイルに記録するために上記を使用しました。

于 2009-10-07T18:16:07.867 に答える
5

stderr次のような操作を行うことstdoutで、Windowsシェルレベルでリダイレクトできます。

perl stuff.pl 2>&1

公式の言葉については、こちらのサポート記事を参照してください。

次に、このstackoverflowの回答を使用teeして、シェルからを実行できます。

perl stuff.pl 2>&1 | tee stuff.txt
于 2010-03-24T22:07:23.390 に答える
3

STDERRファイルハンドルを再割り当てするだけです...

use IO::Tee;
my $log_filename = "log.txt";
my $log_filehandle;
open( $log_filehandle, '>>', $log_filename )
  or die("Can't open $log_filename for append: $!");
my $tee = IO::Tee->new( $log_filehandle, \*STDOUT );
*STDERR = *$tee{IO};
select $tee;

これを Windows でテストしたことは言うまでもありませんが、動作しますが、StrawberryPerl を使用しています。

于 2010-03-25T08:53:23.703 に答える
2

これをテストするための Windows ボックスはありませんが、STDOUT とログの両方に出力するタイド ハンドルを作成し、STDOUT と STDERR をそれにリダイレクトするようなことはできますか?

編集:私が持っている唯一の懸念は、後で使用するためにSTDOUTを保存する方法です。最初のSTDOUTがWindowsで機能しない場合に、後で使用するためにSTDOUTを保存する2番目の可能性を追加しました。どちらも Linux で動作します。

#!/usr/bin/perl

use strict;
use warnings;

tie *NEWOUT, 'MyHandle', 'test.log';
*STDOUT = *NEWOUT;
*STDERR = *NEWOUT;

print "Print\n";
warn "Warn\n";

package MyHandle;

sub TIEHANDLE {
  my $class = shift;
  my $filename = shift;

  open my $fh, '>', $filename or die "Could not open file $filename";

  ## Use one of these next two lines to store STDOUT for later use.
  ## Both work for me on Linux, if one does not work on Windows try the other.
  open(OLDSTDOUT, '>&STDOUT') or die "Could not store STDOUT";
  #*OLDSTDOUT = *STDOUT;

  my $self = {
    loghandle => $fh,
    logfilename => $filename,
    stdout => \*OLDSTDOUT,
  };

  bless $self, $class;

  return $self;
}

sub PRINT {
  my $self = shift;
  my $log = $self->{loghandle};
  my $stdout = $self->{stdout};
  print $log @_;
  print $stdout @_;
}
于 2011-04-22T03:55:16.087 に答える
1

試す :

my logfh;
my $logfn = "some/path/to/file.log";
open ($logfh, '>',$logfn ) or die "Error opening logfile $logfn\n";
my $tee = IO::Tee->new( $logfh);
my $tee2 = IO::Tee->new( $logfh, \*STDOUT );
# all naked print statements will send output to log file
select($tee);
# all STDERR print statements will send output to console
*STDERR = *$tee2{IO};

ファイル ハンドル (つまり、通常のメッセージ) を指定しないすべての print ステートメントは、出力をログ ファイルに送信します。STDERR ファイル ハンドルを使用するすべての print ステートメント (つまり、すべてのエラー) は、コンソールとログ ファイルの両方に出力を送信します。

于 2011-06-16T20:37:43.887 に答える
0

STDERRのように動作STDOUTして、画面と同じログ ファイルの両方に移動しますか? あなたはちょうどでdupできますSTDERR

open(STDERR, ">&STDOUT") or warn "failed to dup STDOUT:$!";

( の呼び出しの前または後にこれを行うかどうかはわかりませんIO::tee->new)。

于 2009-10-07T16:19:57.163 に答える
0

以下の API を提供する、構成可能な動的ロギングを備えた最小限のperl ロガーを作成しました。

        use strict ; use warnings ; use Exporter;
        use Configurator ; 
        use Logger ; 


        #   anonymous hash !!!
        our $confHolder = () ; 

        sub main {

                # strip the remote path and keep the bare name
                $0=~m/^(.*)(\\|\/)(.*)\.([a-z]*)/; 
                my $MyBareName = $3; 
                my $RunDir= $1 ; 

                # create the configurator object 
                my $objConfigurator = new Configurator($RunDir , $MyBareName ); 
                # get the hash having the vars 
                $confHolder = $objConfigurator ->getConfHolder () ; 
                # pring the hash vars 
                print $objConfigurator->dumpIni();  

                my $objLogger = new Logger (\$confHolder) ; 
                $objLogger->LogMsg  (   " START MAIN " ) ;  

                $objLogger->LogMsg  (   "my \$RunDir is $RunDir" ) ; 
                $objLogger->LogMsg  (   "this is a simple message" ) ; 
                $objLogger->LogErrorMsg (   "This is an error message " ) ; 
                $objLogger->LogWarningMsg   (   "This is a warning message " ) ; 
                $objLogger->LogInfoMsg  (   "This is a info message " ) ; 
                $objLogger->LogDebugMsg (   "This is a debug message " ) ; 
                $objLogger->LogTraceMsg (   "This is a trace message " ) ; 
                $objLogger->LogMsg  (   "using the following log file " .  "$confHolder->{'LogFile'}" ) ; 
                $objLogger->LogMsg  (   " STOP MAIN \n\n" ) ; 

        } #eof main 



        #Action !!!
        main(); 

        1 ; 

        __END__
于 2011-04-21T20:35:42.433 に答える