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