<?php
class Logger {
private static $level = 0;
private static $file = '/tmp/app.log';
private static $levelMap = [
'NONE' => 0,
'ERROR' => 1,
'INFO' => 2,
'DEBUG' => 3
];
public static function setLevel($level = 'ERROR') {
self::$level = self::$levelMap[$level] ?? 0;
}
public static function log($level, $message) {
if ((self::$levelMap[self::$level] ?? 0) < (self::$levelMap[$level] ?? 0)) {
return false; // 級別不足,不記錄
}
$dir = dirname(self::$file);
if (!is_dir($dir)) {
mkdir($dir, 0755, true);
}
$fp = fopen(self::$file, 'a');
if ($fp) {
$time = date('Y-m-d H:i:s.u');
fwrite($fp, "[$level] [$time] $message\n");
fclose($fp);
}
return true;
}
public static function reset() {
if (file_exists(self::$file)) {
@unlink(self::$file);
}
}
// 靜態快捷方法
public static function error($msg) { self::log('ERROR', $msg); }
public static function info($msg) { self::log('INFO', $msg); }
public static function debug($msg) { self::log('DEBUG', $msg); }
}
?>
Logger::info('msg') 即可調用。setLevel('INFO') 時,DEBUG 不會寫入,ERROR/INFO 會寫入。mkdir(..., true) 遞迴建立日誌目錄,免去手動維護。date('u') 提供微秒精度,利於效能分析。fopen('a') 追加模式 + fclose(),避免檔案鎖死。<?php
require 'Logger.php';
Logger::setLevel('INFO'); // 只記錄 INFO 以上
Logger::error('DB connection failed');
Logger::info('User login: uid=1001');
Logger::debug('SQL: SELECT * FROM users'); // 不會寫入
// 動態切換級別
Logger::setLevel('DEBUG');
Logger::debug('Cache hit ratio: 92%');
// 清空日誌(測試用)
Logger::reset();
?>
原始片段存在變數名錯誤($ss-log-filename 全形連字號)、語法錯誤(NONE => 0 需加引號)、函數名拼寫不一致(daddslashes vs site_addslashes)、ss_times*****p_pretty() 未定義。本文已重構為可直接生產使用的類庫。
logrotate 或自訂邏輯)。request_id、trace_id 實現分散式追蹤。