You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

153 lines
4.4 KiB

<?php
/**
* 日志管理类
*/
class Logger {
private $logPath;
private $logLevel;
private $maxFileSize;
// 日志级别
const LEVEL_DEBUG = 'debug';
const LEVEL_INFO = 'info';
const LEVEL_WARNING = 'warning';
const LEVEL_ERROR = 'error';
// 日志级别优先级
private $levelPriority = [
self::LEVEL_DEBUG => 0,
self::LEVEL_INFO => 1,
self::LEVEL_WARNING => 2,
self::LEVEL_ERROR => 3,
];
/**
* 构造函数
* @param string $logPath 日志文件路径
* @param string $logLevel 日志级别
* @param int $maxFileSize 最大日志文件大小(字节)
*/
public function __construct($logPath, $logLevel = self::LEVEL_INFO, $maxFileSize = 10 * 1024 * 1024) {
$this->logPath = rtrim($logPath, '/') . '/';
$this->logLevel = $logLevel;
$this->maxFileSize = $maxFileSize;
// 确保日志目录存在
if (!is_dir($this->logPath)) {
mkdir($this->logPath, 0755, true);
}
}
/**
* 记录debug级别的日志
* @param string $message 日志消息
* @param array $context 上下文信息
*/
public function debug($message, $context = []) {
$this->log(self::LEVEL_DEBUG, $message, $context);
}
/**
* 记录info级别的日志
* @param string $message 日志消息
* @param array $context 上下文信息
*/
public function info($message, $context = []) {
$this->log(self::LEVEL_INFO, $message, $context);
}
/**
* 记录warning级别的日志
* @param string $message 日志消息
* @param array $context 上下文信息
*/
public function warning($message, $context = []) {
$this->log(self::LEVEL_WARNING, $message, $context);
}
/**
* 记录error级别的日志
* @param string $message 日志消息
* @param array $context 上下文信息
*/
public function error($message, $context = []) {
$this->log(self::LEVEL_ERROR, $message, $context);
}
/**
* 记录日志
* @param string $level 日志级别
* @param string $message 日志消息
* @param array $context 上下文信息
*/
private function log($level, $message, $context = []) {
// 检查日志级别是否需要记录
if ($this->levelPriority[$level] < $this->levelPriority[$this->logLevel]) {
return;
}
// 格式化日志消息
$formattedMessage = $this->formatMessage($level, $message, $context);
// 确定日志文件名
$logFile = $this->logPath . date('Y-m-d') . '.log';
// 检查日志文件大小,如果超过最大值则滚动
$this->rotateLog($logFile);
// 写入日志
file_put_contents($logFile, $formattedMessage, FILE_APPEND | LOCK_EX);
}
/**
* 格式化日志消息
* @param string $level 日志级别
* @param string $message 日志消息
* @param array $context 上下文信息
* @return string 格式化后的日志消息
*/
private function formatMessage($level, $message, $context = []) {
$timestamp = date('Y-m-d H:i:s');
$pid = getmypid();
$ip = $_SERVER['REMOTE_ADDR'] ?? '127.0.0.1';
// 替换上下文中的占位符
if (!empty($context)) {
foreach ($context as $key => $value) {
$message = str_replace('{' . $key . '}', (string)$value, $message);
}
}
return sprintf("[%s] [%s] [PID: %d] [IP: %s] %s\n", $timestamp, strtoupper($level), $pid, $ip, $message);
}
/**
* 滚动日志文件
* @param string $logFile 日志文件名
*/
private function rotateLog($logFile) {
if (file_exists($logFile) && filesize($logFile) > $this->maxFileSize) {
$backupFile = $logFile . '.' . date('His');
rename($logFile, $backupFile);
}
}
/**
* 设置日志级别
* @param string $level 日志级别
*/
public function setLevel($level) {
if (isset($this->levelPriority[$level])) {
$this->logLevel = $level;
}
}
/**
* 获取当前日志级别
* @return string 当前日志级别
*/
public function getLevel() {
return $this->logLevel;
}
}