PHP应用运行过程中会产生各类日志,包括错误日志、访问日志、业务日志等,随着运行时间增长,日志文件会不断增大,不仅占用磁盘空间,还会影响日志查询和故障排查的效率,因此合理的日志归档和存储策略非常重要。

常见的PHP日志归档方法
1. 按时间切割归档
按时间切割是最常用的日志归档方式,通常以天、周、月为单位对日志进行切割,适合日志生成量波动不大的场景。
可以通过Linux的crontab定时任务配合日志切割工具实现,例如使用logrotate工具,配置示例如下:
# /etc/logrotate.d/php-log 配置文件内容
/var/log/php/*.log {
daily # 每天切割一次
rotate 30 # 保留30天的日志
compress # 切割后的日志进行gzip压缩
delaycompress # 延迟压缩,上一次切割的日志不立即压缩
missingok # 日志文件不存在时不报错
notifempty # 日志为空时不切割
create 0644 www www # 新建日志文件的权限和所有者
postrotate # 切割后执行的命令,重启php-fpm让日志写入新文件
systemctl reload php-fpm >/dev/null 2>&1 || true
endscript
}2. 按文件大小切割归档
当日志生成速度较快时,按时间切割可能导致单日日志文件过大,此时可以按文件大小进行切割,例如当日志文件达到100MB时就进行归档。
可以在PHP代码中实现按大小切割的逻辑,示例如下:
<?php
class LogArchiver {
private $logPath; // 日志文件路径
private $maxSize = 104857600; // 最大文件大小 100MB
private $archiveDir; // 归档目录
public function __construct($logPath, $archiveDir) {
$this->logPath = $logPath;
$this->archiveDir = $archiveDir;
// 归档目录不存在则创建
if (!is_dir($this->archiveDir)) {
mkdir($this->archiveDir, 0755, true);
}
}
// 写入日志方法
public function writeLog($content) {
// 检查当前日志文件大小
if (file_exists($this->logPath) && filesize($this->logPath) >= $this->maxSize) {
$this->archiveLog();
}
// 写入日志
file_put_contents($this->logPath, $content . PHP_EOL, FILE_APPEND);
}
// 归档日志方法
private function archiveLog() {
$fileName = basename($this->logPath);
$time = date('YmdHis');
$archiveName = $this->archiveDir . '/' . $fileName . '.' . $time . '.log';
// 移动当前日志到归档目录
rename($this->logPath, $archiveName);
// 压缩归档的日志
$this->compressLog($archiveName);
}
// 压缩日志方法
private function compressLog($filePath) {
$zip = new ZipArchive();
$zipPath = $filePath . '.zip';
if ($zip->open($zipPath, ZipArchive::CREATE) === TRUE) {
$zip->addFile($filePath, basename($filePath));
$zip->close();
// 压缩完成后删除原日志文件
unlink($filePath);
}
}
}
// 使用示例
$archiver = new LogArchiver('/var/log/php/app.log', '/var/log/php/archive');
$archiver->writeLog('测试日志内容');
?>PHP日志存储策略优化
1. 分级存储策略
根据日志的重要性和使用频率采用分级存储,近期的热日志存储在性能较好的SSD磁盘,超过3个月的冷日志可以迁移到容量更大、成本更低的机械硬盘,超过1年的归档日志可以转移到对象存储中。
| 日志类型 | 存储周期 | 存储介质 | 用途 |
|---|---|---|---|
| 当日日志 | 1天 | SSD磁盘 | 实时故障排查、实时监控 |
| 近期日志(1-3个月) | 3个月 | SSD磁盘 | 常规问题排查、业务分析 |
| 中期日志(3-12个月) | 9个月 | 机械硬盘 | 月度/季度业务复盘 |
| 长期归档日志(1年以上) | 按需保留 | 对象存储 | 合规审计、历史数据查询 |
2. 日志压缩与清理策略
归档后的日志应及时进行压缩,文本类日志的压缩率通常可以达到70%以上,能大幅降低存储占用。同时需要设置合理的日志清理规则,除了合规要求必须保留的日志外,超过存储周期的日志应自动删除,避免无用日志占用空间。
可以通过定时脚本实现过期日志的清理,示例如下:
#!/bin/bash
# 清理30天前的未压缩归档日志
find /var/log/php/archive -name "*.log" -mtime +30 -exec rm -f {} \;
# 清理365天前的压缩归档日志
find /var/log/php/archive -name "*.zip" -mtime +365 -exec rm -f {} \;3. 日志分类存储
不要将所有类型的日志写入同一个文件,应按照错误日志、访问日志、业务日志分类存储,每类日志单独设置归档规则和存储策略。比如错误日志的重要性更高,可以保留更长时间,访问日志生成量更大,可以缩短保留周期。
归档注意事项
- 归档操作应当避免影响PHP应用的正常运行,尽量在低峰期执行归档任务,切割日志时确保日志写入不中断。
- 归档后的日志文件应当添加清晰的命名标识,包含日志类型、切割时间等信息,方便后续查询。
- 重要的日志归档前建议进行完整性校验,避免归档过程中日志内容丢失。
- 如果使用了分布式部署的PHP应用,需要考虑多节点日志的集中归档,避免每个节点的日志分散管理。