5

我正在将一个网站移动到 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')

(“错误”是 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";

Python:

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";%' {} \;

Python:

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")%' {} \;

我发布这些命令的原因是我花了很多语法按摩才能使这些命令正常工作(例如,将无法更改为无法,将 #!/usr/bin/perl 更改为仅 /usr/ bin/perl,因此 shell 不会将 ! 解释为历史字符,使用 $OS_ERROR 而不是 $! 等)

感谢所有评论的人。由于没有人同时回答 Perl 和 Python,我不能真正“接受”任何给定的答案,但我确实给了那些引导我走向正确方向的答案。再次感谢!

于 2009-11-24T10:00:20.443 回答
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 回答
0

在我的 Perl CGI 程序中,我通常有

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

就在 shebang 行和“使用严格;使用警告;”之后。如果需要,您可以将 $0 附加到文件名。但这并不能解决多程序问题,因为一个程序的多个副本可能会同时运行。对于每个程序组,我通常只有几个输出文件。

于 2009-11-23T10:35:37.960 回答