5

Web サイトを Hostmonster に移動し、CGI エラーを自動的にスキャンできるようにサーバー ログの場所を尋ねました。「申し訳ありませんが、アクセス権のあるファイルに cgi エラーが発生することはありません」と言われました。

組織上の理由から、私は Hostmonster とこのひどいポリシーに固執しているので、回避策として、CGI スクリプトを変更して STDERR をカスタム ログ ファイルにリダイレクトすることを考えました。

多くのスクリプト (269) があるため、Python と Perl の両方で STDERR をカスタム ログ ファイルにリダイレクトする簡単な方法が必要です。

共有 CGI エラー ログ ファイルは、複数のスクリプトが同時に失敗した場合、理論的には一度に複数のスクリプトによって書き込まれる可能性があるため、ファイルのロックを明示的または暗黙的に説明できるものは優れています。

(共有エラー ログを使用して、その内容を毎晩自分自身に電子メールで送信し、アーカイブまたは削除できるようにしたいと考えています。)

各ファイル (grrr) を変更する必要があるかもしれないことはわかっています。そのため、数行のコードだけで済むエレガントなものを探しています。ありがとう。

4

7 に答える 7

4

Perl の場合は、閉じてから再度開いSTDERRて、選択したファイルを指定します。

close STDERR;
open STDERR, '>>', '/path/to/your/log.txt' 
  or die "Couldn't redirect STDERR: $!";

warn "this will go to log.txt";

または、 File::Teeのようなファイルハンドル マルチプレクサを調べることもできます。

于 2009-11-23T06:56:16.147 に答える
3

パイソン: cgitb . スクリプトの先頭で、他のインポートの前に:

import cgitb
cgitb.enable(False, '/home/me/www/myapp/logs/errors')

('errors' は、Web サーバー ユーザーが書き込みアクセス権を持つディレクトリです。)

于 2009-11-23T06:38:14.350 に答える
3

Perl でCGI::Carpを試す

BEGIN { 
use CGI::Carp qw(carpout); 
use diagnostics;
open(LOG, ">errors.txt"); 
carpout(LOG);
close(LOG);
}

use CGI::Carp qw(fatalsToBrowser);
于 2009-11-23T06:55:59.517 に答える
2

Python:

import sys

sys.stderr = open('file_path_with_write_permission/filename', 'a')
于 2009-11-23T07:33:28.600 に答える
2

私が最終的に行った解決策は、すべてのスクリプトの上部にある次のようなものでした。

パール:

open(STDERR,">>","/path/to/my/cgi-error.log")
    or die "Could not redirect STDERR: $OS_ERROR";

パイソン:

sys.stderr = open("/path/to/my/cgi-error.log", "a")

どうやら Perl では、STDERR ハンドルを再度開く前に閉じる必要はありません。

通常、ベスト プラクティスとしてとにかく閉じますが、質問で述べたように、269 のスクリプトがあり、変更を最小限に抑えようとしています。(加えて、開いているファイルハンドルを再度開くのはより Perlish のように思えますが、それは恐ろしいことです。)

他の誰かが将来同様のことをした場合に備えて、すべてのスクリプトを一度に更新するために私がやろうとしていることは次のとおりです。

パール:

find . -type f -name "*.pl" -exec perl -pi.bak -e 's%/usr/bin/perl%/usr/bin/perl\nopen(STDERR,">>","/path/to/my/cgi-error.log")\n    or die "Could not redirect STDERR: \$OS_ERROR";%' {} \;

パイソン:

find . -type f -name "*.py" -exec perl -pi.bak -e 's%^(import os, sys.*)%$1\nsys.stderr = open("/path/to/my/cgi-error.log", "a")%' {} \;

私がこれらのコマンドを投稿した理由は、これらのコマンドを機能させるのにかなりの構文操作が必要だったからです (たとえば、Couldn't を Could not に変更したり、#!/usr/bin/perl を /usr/ に変更したりします)。 bin/perl を使用すると、シェルは ! を履歴文字として解釈せず、$! の代わりに $OS_ERROR を使用するなど)

コメントしてくれたみんなに感謝します。Perl と Python の両方について誰も答えなかったので、与えられた答えを「受け入れる」ことはできませんでしたが、正しい方向に導いてくれた答えには投票しました。再度、感謝します!

于 2009-11-24T10:00:20.443 に答える
0

Perl CGI プログラムでは、通常、

BEGIN {
  open(STDERR,'>>','stderr.log');
}

シバン行の直後と「use strict;use warnings;」。必要に応じて、ファイル名に $0 を追加できます。ただし、1 つのプログラムの複数のコピーが同時に実行される可能性があるため、これは複数のプログラムの問題を解決しません。私は通常、プログラムグループごとにいくつかの出力ファイルを持っています。

于 2009-11-23T10:35:37.960 に答える
0

Pythonにはsysがあります。あなたが調べたいと思うかもしれないstderrモジュール。

>>>help(sys.__stderr__.read)
Help on built-in function read:

read(...)
    read([size]) -> read at most size bytes, returned as a string.

    If the size argument is negative or omitted, read until EOF is reached.
    Notice that when in non-blocking mode, less data than what was requested
    may be returned, even if no size parameter was given.

この出力を文字列に保存し、その文字列をファイルに書き込むことができます。

お役に立てれば

于 2009-11-23T07:02:38.163 に答える