因此,我多年来一直使用 cronolog 和以下指令:
<VirtualHost *:80>
SetEnv origin SND
ServerName sandman.net
CustomLog "|/usr/bin/cronolog [..]/logs/SND/log_%Y-%m.txt" combined
</VirtualHost>
问题是,由于存在大量虚拟主机,当 apache 生成 cronolog 时,我突然达到了打开文件描述符的最大值。
经过谷歌搜索(和在这里搜索),我没有找到解决方案,那么就没有解决方案了吗?如您所见,我将 Apache 中的 ENV 变量设置为该 vhost 的“SND”,我想要做的是这样的:
CustomLog "|/usr/bin/cronolog [..]/logs/${origin}/log_%Y-%m.txt" combined
<VirtualHost *:80>
SetEnv origin SND
ServerName sandman.net
</VirtualHost>
从理论上讲,这只会产生一个写入正确的 vhost 日志文件的 cronolog 进程。
但似乎管道命令在流程的任何阶段都不会解析 Apache 变量,这意味着我能想到的唯一解决方案是将 ${origin} 添加到 LogFormat,然后编写自己的日志轮换脚本,该脚本将解析(并忽略)vhost 变量,然后将日志行的其余部分写入适当的文件。但这样会减少开销吗?
还有其他建议吗?
答案1
cronolog
对于每个打开的日志文件,总会有一个实例。这里有一个解决方案:http://httpd.apache.org/docs/2.2/logs.html#virtualhost建议只需将 vhost 名称添加到日志文件,然后根据需要将其拆分为单独的文件。
您建议的其他可能解决方案:编写自己的程序/脚本,将日志拆分为每个虚拟主机日志。另外,将所有日志发送到 syslog 并在 syslog 主机上运行拆分程序可能是一个好主意。这样,apache 将只为每种日志类型打开一个文件描述符。当然,会有一些开销,但 apache 不会超出文件描述符限制。
答案2
也许您可以使用命名管道。
通常,gelraen 的建议非常好,但是如果你这样做,你将错过轮换(你可以从 syslog 调用 cronolog,但为了减少开销,可能需要一些额外的队列)
http://httpd.apache.org/docs/2.2/vhosts/fd-limits.html(摘自 gelraen)
除此之外,也许现在是分发虚拟主机的好时机。即使你买不起一台真正的机器,你也可以使用一台虚拟机。但我不认为把所有东西都放在一台服务器上是个好主意。