1

我有一个在我的 ubunutu 服务器上运行的 php 脚本。该脚本在无限循环中运行,运行查询并收集统计信息……它是其他一些服务的监视器。每隔 60 秒,收集的统计信息会作为 json 对象转储到 .js 文件中。.js 文件在其他地方受到监控,对于我的问题而言并不重要。

当我运行我的脚本时,我将 stdout 和 stderr 都重定向到一个日志文件。在大多数情况下,没有标准或错误输出,因此日志将保持为空。

显然,尽管有时会有输出。我昨晚遇到的问题是脚本由于某种原因失败,并且日志文件最终填满了整个分区并破坏了服务器的稳定性。

我所做的..或尝试做的是添加一个简单的检查,即每 60 秒(当转储统计信息时)脚本检查日志文件的大小..如果它的大小大于 X mb,基本上清空文件并允许继续记录。目的是如果脚本再次遇到问题,日志文件不会填满整个分区。

我可以成功检测到日志文件大小,当它达到我设置的大小时我可以成功清除它,但是下一次有 STDOUT 或 STDERR 写入时,之前的所有数据都会一次性转储。

对此的任何帮助将不胜感激。


通过以下方式调用脚本:

php checker.php &> log

但尝试过

php checker.php > log 2>&1

并在脚本开头重定向流

close(STDOUT);
fclose(STDERR);
$STDOUT = fopen($LOG_FILE_LOCATION, 'wb');
$STDERR = fopen($LOG_FILE_LOCATION, 'wb');

每种方式产生相同的输出。

代码清除日志文件

function CheckLogFilesize($file)
{
    global $LOG_FILE_LOCATION;
    global $MAX_LOG_SIZE_MB;
    $max_log_size_bytes = $MAX_LOG_SIZE_MB * 1024 * 1024;

    $size = exec('stat -c %s ' . $file);

    // If log file size is too large.. reset it.
    if (intval($size) > $max_log_size_bytes)
    {
        flush();

        // Clear the log
        $fp = fopen($file, 'w');
        fwrite($fp, '');
        fclose($fp);
    }
}

谢谢

4

3 回答 3

1

如果我必须这样做,我会检测日志文件的大小,如果它大于阈值,则将文件移动到另一个文件名(例如 old-log.txt)。在这种情况下,您将拥有最多 2 个日志文件,总大小为阈值的 2 倍。

优点是在达到阈值后您仍然有一些旧的日志条目。如果您只是清除文件,您会看到您尝试在空文件中查找信息

编辑:

看看 PHP 中的 ob_* 命令。他们可能会帮助您清除缓冲区

ob_start()在评论中你可以找到更多关于标准输出的信息

...
ob_start();
// keep writing log until done
ob_end_clean(); // or use ob_end_flush();

一些伪代码...

于 2012-05-30T05:50:50.760 回答
1

如果您要重定向stdout到日志文件,您甚至可以尝试访问unlink()该文件,但它不起作用,因为您stdout仍然连接到它。

一种方法是在启动进程之前清除日志文件,并在文件超过一定大小时停止进程。然后让你的脚本在 shell 脚本循环中运行(只有当进程存在代码 = 0 时才会终止,即没有错误);当脚本停止时,它将立即再次启动。

通常,守护进程会打开它们自己的日志文件,因此您可以向它们发送HUP信号以重新打开它们的日志文件,从而避免完全重启。

于 2012-05-30T06:02:47.027 回答
1

编辑

弄清楚了:

function get_log_size() {
    clearstatcache();
    return filesize("/tmp/log.log");
}

foreach (range(1, 1000000) as $interval) {
    echo $interval . "\n";
    usleep(10000);
    if ($interval % 50 == 0) {
        fwrite(STDERR, "mod 50 fail test");
    }
    $size = get_log_size();
    echo $size . " bytes\n";
    if ($size > 100) {
        $file = "/tmp/log.log";
        $fp = fopen($file, 'w');
        fclose($fp);
        print "Truncated\n";
    }

}

开始于

php test.php >> /tmp/log.log 2>&1

注意>>而不是>。您必须使用附加模式

的示例输出tail -f /tmp/log.log

λ ~/ tail -f /tmp/log.log

1
2 bytes
2
12 bytes
3
23 bytes
4
34 bytes
5
45 bytes
6
56 bytes
7
67 bytes
8
78 bytes
9
89 bytes
10
101 bytes
Truncated
11
13 bytes
12
25 bytes
13
37 bytes
14
49 bytes
15
61 bytes
16
73 bytes
17
85 bytes
18
97 bytes
19
109 bytes
Truncated
20
13 bytes
21
25 bytes
22
37 bytes
23
49 bytes
24
61 bytes
25
73 bytes
26
85 bytes
27
97 bytes
28
109 bytes
Truncated
于 2012-05-30T06:04:38.577 回答