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; } }