本文目录导读:

我来介绍几种在PHP项目中实现日志压缩的方法:
使用PHP内置的压缩函数
gzip压缩
<?php
class LogCompressor {
/**
* 压缩单个日志文件
*/
public function compressLogFile($sourceFile, $destinationFile = null) {
if (!file_exists($sourceFile)) {
throw new Exception("源文件不存在");
}
$destinationFile = $destinationFile ?? $sourceFile . '.gz';
$data = file_get_contents($sourceFile);
$compressed = gzencode($data, 9);
file_put_contents($destinationFile, $compressed);
// 可选:删除原文件
// unlink($sourceFile);
return $destinationFile;
}
/**
* 解压缩日志文件
*/
public function decompressLogFile($compressedFile, $destinationDir = null) {
if (!file_exists($compressedFile)) {
throw new Exception("压缩文件不存在");
}
$destinationDir = $destinationDir ?? dirname($compressedFile);
// 读取压缩文件
$compressed = file_get_contents($compressedFile);
$data = gzdecode($compressed);
// 生成解压后的文件名
$basename = basename($compressedFile, '.gz');
$destinationFile = $destinationDir . '/' . $basename;
file_put_contents($destinationFile, $data);
return $destinationFile;
}
}
bzip2压缩
<?php
function compressWithBzip2($sourceFile, $destinationFile = null) {
$destinationFile = $destinationFile ?? $sourceFile . '.bz2';
// 使用bzcompress
$data = file_get_contents($sourceFile);
$compressed = bzcompress($data, 9);
file_put_contents($destinationFile, $compressed);
return $destinationFile;
}
function decompressBzip2($compressedFile, $destinationFile = null) {
$data = file_get_contents($compressedFile);
$decompressed = bzdecompress($data);
$destinationFile = $destinationFile ?? preg_replace('/\.bz2$/', '', $compressedFile);
file_put_contents($destinationFile, $decompressed);
return $destinationFile;
}
批量压缩和归档
<?php
class LogArchiver {
private $logDir;
private $archiveDir;
public function __construct($logDir, $archiveDir) {
$this->logDir = rtrim($logDir, '/');
$this->archiveDir = rtrim($archiveDir, '/');
if (!is_dir($this->archiveDir)) {
mkdir($this->archiveDir, 0755, true);
}
}
/**
* 归档指定日期之前的日志
*/
public function archiveOldLogs($daysOld = 7) {
$files = glob($this->logDir . '/*.log');
$cutoff = time() - ($daysOld * 86400);
$archived = [];
foreach ($files as $file) {
if (filemtime($file) < $cutoff) {
$archiveName = basename($file) . '.' . date('Ymd') . '.gz';
$archivePath = $this->archiveDir . '/' . $archiveName;
// 压缩文件
if ($this->compressFile($file, $archivePath)) {
// 成功压缩后删除原文件
unlink($file);
$archived[] = $archiveName;
}
}
}
return $archived;
}
/**
* 压缩文件,使用流式处理避免内存问题
*/
private function compressFile($source, $destination) {
try {
$sfp = gzopen($destination, 'w9');
$fp = fopen($source, 'rb');
while (!feof($fp)) {
gzwrite($sfp, fread($fp, 8192));
}
fclose($fp);
gzclose($sfp);
return true;
} catch (Exception $e) {
error_log("压缩失败: " . $e->getMessage());
return false;
}
}
/**
* 创建tar归档并压缩
*/
public function createTarArchive($startDate, $endDate = null) {
$phar = new PharData(
$this->archiveDir . '/logs-' . date('Ymd') . '.tar.gz',
Phar::GZ
);
$files = glob($this->logDir . '/*.log');
foreach ($files as $file) {
$fileDate = date('Ymd', filemtime($file));
if ($fileDate >= $startDate &&
($endDate === null || $fileDate <= $endDate)) {
$phar->addFile($file, basename($file));
}
}
return $phar->getPath();
}
}
带日志轮转的压缩
<?php
class LogRotationCompressor {
private $logDir;
private $maxSize;
private $maxFiles;
public function __construct($logDir, $maxSize = 104857600, $maxFiles = 10) {
$this->logDir = rtrim($logDir, '/');
$this->maxSize = $maxSize; // 默认100MB
$this->maxFiles = $maxFiles;
}
/**
* 检查并压缩超过大小的日志
*/
public function checkAndRotate($logFile) {
if (!file_exists($logFile)) {
return false;
}
// 检查文件大小
if (filesize($logFile) < $this->maxSize) {
return false;
}
$basename = basename($logFile);
// 轮转并压缩
for ($i = $this->maxFiles - 1; $i > 0; $i--) {
$oldFile = $this->logDir . '/' . $basename . '.' . $i . '.gz';
$newFile = $this->logDir . '/' . $basename . '.' . ($i + 1) . '.gz';
if (file_exists($oldFile)) {
rename($oldFile, $newFile);
}
}
// 压缩当前日志
$destination = $this->logDir . '/' . $basename . '.1.gz';
$this->compressFile($logFile, $destination);
// 清空原日志文件
file_put_contents($logFile, '');
return true;
}
private function compressFile($source, $destination) {
$sfp = gzopen($destination, 'w9');
$fp = fopen($source, 'rb');
while (!feof($fp)) {
gzwrite($sfp, fread($fp, 8192));
}
fclose($fp);
gzclose($sfp);
return true;
}
}
使用exec执行系统命令
<?php
class SystemCommandCompressor {
/**
* 使用gzip命令压缩
*/
public function compressWithGzip($file) {
// 保留原文件
exec("gzip -c {$file} > {$file}.gz", $output, $returnVar);
if ($returnVar !== 0) {
throw new Exception("gzip压缩失败: " . implode("\n", $output));
}
return $file . '.gz';
}
/**
* 使用bzip2命令压缩
*/
public function compressWithBzip2($file) {
exec("bzip2 -z -k {$file}", $output, $returnVar);
if ($returnVar !== 0) {
throw new Exception("bzip2压缩失败: " . implode("\n", $output));
}
return $file . '.bz2';
}
/**
* 创建tar归档
*/
public function createTarArchive($files, $archiveName) {
$fileList = implode(' ', $files);
exec("tar -czf {$archiveName} {$fileList}", $output, $returnVar);
if ($returnVar !== 0) {
throw new Exception("tar归档失败: " . implode("\n", $output));
}
return $archiveName;
}
}
定时任务实现自动化压缩
创建压缩脚本 compress_logs.php
<?php
require_once 'LogArchiver.php';
$config = [
'log_dir' => '/var/log/myapp',
'archive_dir' => '/var/log/archives',
'days_old' => 7,
'max_file_size' => 104857600, // 100MB
];
$archiver = new LogArchiver($config['log_dir'], $config['archive_dir']);
// 归档旧日志
$archived = $archiver->archiveOldLogs($config['days_old']);
echo "已归档 " . count($archived) . " 个日志文件\n";
// 检查并轮转大文件
$rotator = new LogRotationCompressor(
$config['log_dir'],
$config['max_file_size']
);
$logFiles = glob($config['log_dir'] . '/*.log');
foreach ($logFiles as $logFile) {
if ($rotator->checkAndRotate($logFile)) {
echo "已轮转: " . basename($logFile) . "\n";
}
}
设置cron定时任务
# 每天凌晨2点执行日志压缩 0 2 * * * /usr/bin/php /path/to/compress_logs.php >> /var/log/log_compression.log 2>&1
使用建议
- 大文件处理:对于大日志文件,使用流式处理避免内存溢出
- 保留原文件:压缩完成后建议保留原文件一段时间,确认无问题再删除
- 错误处理:添加完善的错误处理和日志记录
- 性能考虑:使用适当压缩级别(通常6-9之间)
- 安全性:确保压缩和解压缩操作的目录权限正确
选择哪种方式取决于你的具体需求,内置函数适合简单场景,系统命令适合高性能需求,而类封装提供了更好的可维护性。
版权声明:足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播