我希望能够查询我们的服务器访问日志文件以识别滥用模式。日志文件确实不太可查询,如果每次命中都是 MySQL 数据库中的一行,那么执行我想要的操作将相当容易。
我不想更改网络服务器或使用任何会减慢请求响应时间的模块。网络服务器经过优化,可以将条目写入文本日志,我想让它做到这一点。 IE。让 Web 服务器写入文件,并稍后在批处理过程中将文件条目移动到数据库条目。
PHP 是我最熟悉的服务器端语言,打开一个文件,逐行解析它,并将这些行插入数据库是很简单的。问题是,访问日志的写入速度就像机关枪一样。 PHP 无法在网络服务器尝试写入日志的同时解析日志。当 PHP 进行解析时,Web 服务器也不能耐心等待。
需要有某种方法可以让两者同时完成自己的工作,而不会导入重复的条目或丢失条目。
所以我有两个想法:首先,只处理轮换出来的日志,即access.log.1
。这使得实时性较差,但避免了两个程序竞争相同资源的冲突。仍然存在日志轮换的问题,即在 PHP 读取日志时尝试轮换日志,特别是因为它在循环时重用文件名。我需要某种方法来确保相同的日志不会因为名称冲突而再次被读取或丢失。
其次,我可以使用像管道一样的队列。我以前从未使用过管道,所以我不知道它们是如何工作的。如果:
- Web 服务器将其视为常规文件并像写入文件一样写入
- 网络服务器没有尝试在重新启动时将其替换为常规文件,并且
- 管道只会将文本条目保存在有序队列中,直到调用 PHP 并将条目拉出末尾为止,并且
- 将条目拉出末尾将其删除...
那么它可能正是我正在寻找的。问题是,PHP 是否可以调用,将内容从管道中拉出,然后结束,以便稍后由 cron 再次调用?或者 PHP 是否必须像守护进程一样连续运行才能使用管道。或者换句话说,如果管道的另一端没有任何东西,那么管道是否仍然可以容纳东西,就像文件一样?
或者是否有其他方法可以安全可靠地将日志读入数据库而不减慢页面服务时间?