php开发的日志工具类,日志工具类 - iLoveLNMP - OSCHINA - 中文开源技术交流社区

date_default_timezone_set("Asia/ShangHai");

/**

* 日志通用类

*

* 使用示例:

* require 'LogUtil.php';

* LogUtil::get_instance()->debug('debug msg');

* output:

* [2013-11-01 18:31:03][DEBUG][127.0.0.1][LogUtil.php:151][/LogUtil.php][debug msg]

* wei.chungwei@gmail.com

* 2013-11-01

*/

class LogUtil {

private static $_instance;

private $_log_dir = "./"; // 日志路径,默认是当前路径

private $_log_max_size = 1 << 30; // 单个日志文件大小,默认1G

private $_log_max_num = 1; // 日志数量,必须大于等于1,调试状态建议设为1

private function __construct() {}

public static function get_instance() {

if (!isset(self::$_instance)) {

$c = __CLASS__;

self::$_instance = new $c;

}

return self::$_instance;

}

public function __clone(){

trigger_error('Clone is not allowed.', E_USER_ERROR);

}

public function free() {

self::$_instance = null;

}

public function debug($msg) {

$time = time();

$log_name = $this->get_log_name($time);

$this->check_file_size($time, $log_file);

$log_msg = $this->format_log_msg($msg, $time, "DEBUG");

$this->write_log($time, $log_name, $log_msg);

}

public function fatal($msg) {

$time = time();

$log_name = $this->get_log_name($time);

$this->check_file_size($time, $log_file);

$log_msg = $this->format_log_msg($msg, $time, "FATAL");

$this->write_log($time, $log_name, $log_msg);

$this->free();

}

public function warn($msg) {

$time = time();

$log_name = $this->get_log_name($time);

$this->check_file_size($time, $log_file);

$log_msg = $this->format_log_msg($msg, $time, "WARN");

$this->write_log($time, $log_name, $log_msg);

}

public function info($msg) {

$time = time();

$log_name = $this->get_log_name($time);

$this->check_file_size($time, $log_name);

$log_msg = $this->format_log_msg($msg, $time, "INFO");

$this->write_log($time, $log_name, $log_msg);

}

/**

* 获取日志文件名称

* 文件名称格式=当前日期+随机数.log

* 以避免单个日志文件过大

*/

private function get_log_name($time) {

$seq_num = rand(1, $this->_log_max_num);

return $this->_log_dir . date("Y-m-d", $time) . "-{$seq_num}.log";

}

/**

* 格式化日志信息

*/

private function format_log_msg($msg, $time, $priority) {

$datetime = date("Y-m-d H:i:s", $time);

$priority = strtoupper(trim($priority));

$ip = get_user_ip();

$arr_trace = debug_backtrace();

$trace = end($arr_trace);

$file = basename($trace['file']);

$line = $trace['line'];

$uri = isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : '';

return "[{$datetime}] [{$priority}] [{$ip}] [{$file}:{$line}] [{$uri}] [{$msg}]" . PHP_EOL;

}

/**

* 检测单个日志文件大小,大于1G则重命名该日志文件

* 这样可以避免对大文件的读写过慢

*/

private function check_file_size($time, $log_name) {

try {

if (file_exists($log_name) && filesize($log_name) >= $this->_log_max_size) {

// if log size >= 1GB(default),

// then rename this file and make it readonly

$rename_log_file = $this->_log_dir . date("Y-m-d H:i:s", $time) . '.log';

rename($log_name, $rename_log_file);

chmod($rename_log_file, 0444); // 只有可读权限

}

} catch (Exception $e) {

die('error accoured at ' . basename(__FILE__) . ':' . __LINE__ . " with msg : " . $e->getMessage());

}

}

/**

* 将日志信息写入文件

*/

private function write_log($time, $log_name, $log_msg = "") {

try {

if ($fp = fopen($log_name, 'a')) {

// 以下代码对文件加锁,1ms内加锁失败,继续枷锁;

// 超过1ms则让出锁给其他进程

$start_time = microtime();

do {

$lock = flock($fp, LOCK_EX);

if(!$lock) {

usleep(rand(10, 30000));

}

} while ((!$lock) && ((microtime() - $start_time) < 1000));

if ($lock) {

fwrite($fp, $log_msg);

flock($fp, LOCK_UN);

}

fclose($fp);

chmod($log_name, 0666);

} else {

die("open {$log_name} failed at " . basename(__FILE__) . " line " . __LINE__);

}

clearstatcache();

} catch (Exception $e) {

die('error accoured at ' . basename(__FILE__) . ':' . __LINE__ . " with msg : " . $e->getMessage());

}

}

}

/**

* 获取用户ip

*/

function get_user_ip() {

if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {

$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];

} elseif (isset($_SERVER['HTTP_CLIENTIP'])) {

$ip = $_SERVER['HTTP_CLIENTIP'];

} elseif (isset($_SERVER['REMOTE_ADDR'])) {

$ip = $_SERVER['REMOTE_ADDR'];

} elseif (getenv('HTTP_X_FORWARDED_FOR')) {

$ip = getenv('HTTP_X_FORWARDED_FOR');

} elseif (getenv('HTTP_CLIENTIP')) {

$ip = getenv('HTTP_CLIENTIP');

} elseif (getenv('REMOTE_ADDR')) {

$ip = getenv('REMOTE_ADDR');

} else {

$ip = '127.0.0.1';

}

$pos = strpos($ip, ',');

if( $pos > 0 ) {

$ip = substr($ip, 0, $pos);

}

return trim($ip);

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值