将 CGI 错误输出从 STDERR 重定向到文件(python 和 perl)

发布于 2024-08-11 16:49:30 字数 450 浏览 4 评论 0原文

我正在将一个网站移至 Hostmonster,并询问服务器日志位于何处,以便我可以自动扫描它是否有 CGI 错误。有人告诉我:“很抱歉,您有权访问的任何文件都不会出现 CGI 错误。”

出于组织原因,我坚持使用 Hostmonster 和这个糟糕的策略,因此作为一种解决方法,我想也许我应该修改 CGI 脚本以将 STDERR 重定向到自定义日志文件。

我有很多脚本 (269),因此我需要一种使用 Python 和 Perl 的简单方法将 STDERR 重定向到自定义日志文件。

能够显式或隐式地解释文件锁定的东西会很棒,因为理论上,如果多个脚本同时失败,共享的 CGI 错误日志文件可以由多个脚本同时写入。

(我想使用共享错误日志,这样我就可以每晚通过电子邮件将其内容发送给自己,然后存档或删除它。)

我知道我可能必须修改每个文件(grrr),这就是为什么我正在寻找一些优雅的东西只需几行代码。谢谢。

I'm moving a website to Hostmonster and asked where the server log is located so I can automatically scan it for CGI errors. I was told, "We're sorry, but we do not have cgi errors go to any files that you have access to."

For organizational reasons I'm stuck with Hostmonster and this awful policy, so as a workaround I thought maybe I'd modify the CGI scripts to redirect STDERR to a custom log file.

I have a lot of scripts (269) so I need an easy way in both Python and Perl to redirect STDERR to a custom log file.

Something that accounts for file locking either explicitly or implicitly would be great, since a shared CGI error log file could theoretically be written to by more than one script at once if more than one script fails at the same time.

(I want to use a shared error log so I can email its contents to myself nightly and then archive or delete it.)

I know I may have to modify each file (grrr), that's why I'm looking for something elegant that will only be a few lines of code. Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

绝影如岚 2024-08-18 16:49:30

对于 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::三通

For Perl, just close and re-open STDERR to point to a file of your choice.

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

warn "this will go to log.txt";

Alternatively, you could look into a filehandle multiplexer like File::Tee.

喵星人汪星人 2024-08-18 16:49:30

Python:cgitb。在脚本的顶部,在其他导入之前:(

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

“errors”是 Web 服务器用户具有写入访问权限的目录。)

Python: cgitb. At the top of your script, before other imports:

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

(‘errors’ being a directory the web server user has write-access to.)

安静被遗忘 2024-08-18 16:49:30

在 Perl 中尝试 CGI::Carp

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

use CGI::Carp qw(fatalsToBrowser);

In Perl try CGI::Carp

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

use CGI::Carp qw(fatalsToBrowser);
柠栀 2024-08-18 16:49:30

我最终采用的解决方案类似于以下内容,靠近所有脚本的顶部:

Perl:

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,听起来很糟糕。)

如果将来其他人有类似的东西,我将执行以下操作来立即更新所有脚本:

Perl :

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

我发布这些命令的原因是我花了相当多的语法调整才能使这些命令起作用(例如,将 Couldn't 更改为 Could not,将 #!/usr/bin/perl 更改为/usr/bin/perl 这样 shell 就不会将 ! 解释为历史字符,使用 $OS_ERROR 而不是 $! 等)

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

The solution I finally went with was similar to the following, near the top of all my scripts:

Perl:

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")

Apparently in Perl you don't need to close the STDERR handle before reopening it.

Normally I would close it anyway as a best practice, but as I said in the question, I have 269 scripts and I'm trying to minimize the changes. (Plus it seems more Perlish to just re-open the open filehandle, as awful as that sounds.)

In case anyone else has something similar in the future, here's what I'm going to do for updating all my scripts at once:

Perl:

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

The reason I'm posting these commands is that it took me quite a lot of syntactical massaging to get those commands to work (e.g., changing Couldn't to Could not, changing #!/usr/bin/perl to just /usr/bin/perl so the shell wouldn't interpret ! as a history character, using $OS_ERROR instead of $!, etc.)

Thanks to everyone who commented. Since no one answered for both Perl and Python I couldn't really "accept" any of the given answers, but I did give votes to the ones which led me in the right direction. Thanks again!

雾里花 2024-08-18 16:49:30

Python:

import sys

sys.stderr = open('file_path_with_write_permission/filename', 'a')

python:

import sys

sys.stderr = open('file_path_with_write_permission/filename', 'a')
痞味浪人 2024-08-18 16:49:30

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.

您可以将其输出存储在字符串中并将该字符串写入文件。

希望这有帮助

Python has the sys.stderr module that you might want to look into.

>>>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.

You can store the output of this in a string and write that string to a file.

Hope this helps

墨落画卷 2024-08-18 16:49:30

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

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

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

In my Perl CGI programs, I usually have

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

right after shebang line and "use strict;use warnings;". If you want, you may append $0 to file name. But this will not solve multiple programs problem, as several copies of one programs may be run simultaneously. I usually just have several output files, for every program group.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文