CodeIgniter框架源码笔记(9)——日志记录类Log.php
2016-07-27 20:23
766 查看
日志记录类Log结构:
$_log_path:日志存放路径
$_file_permissions:写入的日志文件权限,默认为0644,即rw-r--r--
$_threshold:允许写日志的阀值,默认为1
0 = Disables logging, Error logging TURNED OFF
1 = Error Messages (including PHP errors)
2 = Debug Messages
3 = Informational Messages
4 = All Messages
$_threshold_array :也是允许写日志的阀值,但与$_threshold有些不同。
比如设置配置文件$config['log_threshold'] = 3,这个值会读到$_threshold属性中。那么写日志允许的level可以是1,2,3
可是如果设置$config['log_threshold'] = array(3),那么系统会把这个3读到$_threshold_array数组中,写日志level只允许3,其它的1和2不允许
$_date_fmt :日志的时间格式,由$config['log_date_format']决定。默认'Y-m-d H:i:s'。主要作于$date->format的参数
$_file_ext:日志文件扩展名
$_enabled:标记字段。标记是否有权限写日志。
$_levels:预定义的level级别数组
$config['log_path']:赋值给$this->_log_path,如果没有设置,系统默认用APPPATH.'logs/'。
$config['log_file_extension']:赋值给$this->_file_ext,如果没有设置,则默认日志文件扩展名为'php'。
$config['log_threshold']:config['log_threshold']为整型数字时,赋值给$this->_threshold; config['log_threshold']为数组时,赋值给$this->_threshold_array
$config['log_date_format']:日志的日志格式,赋值给$this->_date_fmt
$config['log_file_permissions']:赋给$this->_file_permissions
2、判断日志文件目录是否存在,如果不存在则创建。这里再次用了OR的短路技巧。
section1 OR section2 相当于if(! section1 ){ section2 }
file_exists($this->_log_path) OR mkdir($this->_log_path, 0755, TRUE);
3、调用公共库common.php中的is_really_writable()函数判断目录是否有写权限,如果没有就设置$this->_enabled=FALSE
源码注释:
1、目录没有写权限时。$this->_enabled===FALSE时。
2、阀值与Log记录等级不匹配时。
$_threshold和$_threshold_array 都是允许写日志的阀值,但两者之间有些不同。
比如设置配置文件$config['log_threshold'] = 3,这个值会读到$_threshold属性中。那么写日志允许的level可以是1,2,3
可是如果设置$config['log_threshold'] = array(3),那么系统会把这个3读到$_threshold_array数组中,写日志level只允许3,其它的1和2不允许。
来看这句强大的if语句
if ( ! $fp = @fopen($filepath, 'ab'))
{
return FALSE;
}
如果以上条件都不满足,那么该方法就计算得到日志文件名,计算文件内容,最后写入,并更改文件权限为$this->_file_permissions
对于新创建并且后缀为php的文件,系统首先在前面加上"<?php defined('BASEPATH') OR exit('No direct script access allowed'); ?>\n\n"
源码注释:
$_log_path:日志存放路径
$_file_permissions:写入的日志文件权限,默认为0644,即rw-r--r--
$_threshold:允许写日志的阀值,默认为1
0 = Disables logging, Error logging TURNED OFF
1 = Error Messages (including PHP errors)
2 = Debug Messages
3 = Informational Messages
4 = All Messages
$_threshold_array :也是允许写日志的阀值,但与$_threshold有些不同。
比如设置配置文件$config['log_threshold'] = 3,这个值会读到$_threshold属性中。那么写日志允许的level可以是1,2,3
可是如果设置$config['log_threshold'] = array(3),那么系统会把这个3读到$_threshold_array数组中,写日志level只允许3,其它的1和2不允许
$_date_fmt :日志的时间格式,由$config['log_date_format']决定。默认'Y-m-d H:i:s'。主要作于$date->format的参数
$_file_ext:日志文件扩展名
$_enabled:标记字段。标记是否有权限写日志。
$_levels:预定义的level级别数组
一、构造函数
1、在构造函数中,获取配置文件中关于日志的配置选项,主要有:$config['log_path']:赋值给$this->_log_path,如果没有设置,系统默认用APPPATH.'logs/'。
$config['log_file_extension']:赋值给$this->_file_ext,如果没有设置,则默认日志文件扩展名为'php'。
$config['log_threshold']:config['log_threshold']为整型数字时,赋值给$this->_threshold; config['log_threshold']为数组时,赋值给$this->_threshold_array
$config['log_date_format']:日志的日志格式,赋值给$this->_date_fmt
$config['log_file_permissions']:赋给$this->_file_permissions
2、判断日志文件目录是否存在,如果不存在则创建。这里再次用了OR的短路技巧。
section1 OR section2 相当于if(! section1 ){ section2 }
file_exists($this->_log_path) OR mkdir($this->_log_path, 0755, TRUE);
3、调用公共库common.php中的is_really_writable()函数判断目录是否有写权限,如果没有就设置$this->_enabled=FALSE
源码注释:
public function __construct() { //获取配置文件中关于日志的配置选项 $config =& get_config(); //确定日志文件存放路径 $this->_log_path = ($config['log_path'] !== '') ? $config['log_path'] : APPPATH.'logs/'; //确定日志文件扩展名 $this->_file_ext = (isset($config['log_file_extension']) && $config['log_file_extension'] !== '') ? ltrim($config['log_file_extension'], '.') : 'php'; //判断日志文件目录是否存在,如果不存在则创建。 file_exists($this->_log_path) OR mkdir($this->_log_path, 0755, TRUE); //目录是否有写权限,如果没有就设置$this->_enabled=FALSE if ( ! is_dir($this->_log_path) OR ! is_really_writable($this->_log_path)) { $this->_enabled = FALSE; } //config['log_threshold']为整型数字时,赋值给$this->_threshold; config['log_threshold'] if (is_numeric($config['log_threshold'])) { $this->_threshold = (int) $config['log_threshold']; } //为数组时,赋值给$this->_threshold_array elseif (is_array($config['log_threshold'])) { //将$this->_threshold置为0,也就是让$this->_threshold失效 $this->_threshold = 0; $this->_threshold_array = array_flip($config['log_threshold']); } //确定日志日期格式 if ( ! empty($config['log_date_format'])) { $this->_date_fmt = $config['log_date_format']; } //确定创建的日志文件权限 if ( ! empty($config['log_file_permissions']) && is_int($config['log_file_permissions'])) { $this->_file_permissions = $config['log_file_permissions']; } }
二、写日志方法write_log()
该方法以下几种情况下不写:1、目录没有写权限时。$this->_enabled===FALSE时。
2、阀值与Log记录等级不匹配时。
$_threshold和$_threshold_array 都是允许写日志的阀值,但两者之间有些不同。
比如设置配置文件$config['log_threshold'] = 3,这个值会读到$_threshold属性中。那么写日志允许的level可以是1,2,3
可是如果设置$config['log_threshold'] = array(3),那么系统会把这个3读到$_threshold_array数组中,写日志level只允许3,其它的1和2不允许。
来看这句强大的if语句
if (( ! isset($this->_levels[$level]) OR ($this->_levels[$level] > $this->_threshold)) && ! isset($this->_threshold_array[$this->_levels[$level]])) { return FALSE; }3、文件打开失败时。
if ( ! $fp = @fopen($filepath, 'ab'))
{
return FALSE;
}
如果以上条件都不满足,那么该方法就计算得到日志文件名,计算文件内容,最后写入,并更改文件权限为$this->_file_permissions
对于新创建并且后缀为php的文件,系统首先在前面加上"<?php defined('BASEPATH') OR exit('No direct script access allowed'); ?>\n\n"
源码注释:
public function write_log($level, $msg)
{
//目录没有写权限时,返回FALSE退出
if ($this->_enabled === FALSE)
{
return FALSE;
}
$level = strtoupper($level);
//写日志的level级别大于阀值设置值,同时level级别也不能匹配阀值数组中设置的值,返回FALSE退出
if (( ! isset($this->_levels[$level]) OR ($this->_levels[$level] > $this->_threshold)) && ! isset($this->_threshold_array[$this->_levels[$level]])) { return FALSE; }
//设置文件全路径及名称
$filepath = $this->_log_path.'log-'.date('Y-m-d').'.'.$this->_file_ext;
$message = '';
//新创建并且后缀为php的文件,系统首先在前面加上"<?php defined('BASEPATH') OR exit('No direct script access allowed'); ?>\n\n"
if ( ! file_exists($filepath))
{
$newfile = TRUE;
// Only add protection to php files
if ($this->_file_ext === 'php')
{
$message .= "<?php defined('BASEPATH') OR exit('No direct script access allowed'); ?>\n\n";
}
}
//无法打开文件,返回FALSE退出
if ( ! $fp = @fopen($filepath, 'ab'))
{
return FALSE;
}
// Instantiating DateTime with microseconds appended to initial date is needed for proper support of this format
//实例化时间
if (strpos($this->_date_fmt, 'u') !== FALSE)
{
$microtime_full = microtime(TRUE);
$microtime_short = sprintf("%06d", ($microtime_full - floor($microtime_full)) * 1000000);
$date = new DateTime(date('Y-m-d H:i:s.'.$microtime_short, $microtime_full));
$date = $date->format($this->_date_fmt);
}
else
{
$date = date($this->_date_fmt);
}
//合成日志内容
$message .= $level.' - '.$date.' --> '.$msg."\n";
flock($fp, LOCK_EX);
//写文件
for ($written = 0, $length = strlen($message); $written < $length; $written += $result)
{
if (($result = fwrite($fp, substr($message, $written))) === FALSE)
{
break;
}
}
flock($fp, LOCK_UN);
fclose($fp);
//更改文件权限
if (isset($newfile) && $newfile === TRUE)
{
chmod($filepath, $this->_file_permissions);
}
return is_int($result);
}
相关文章推荐
- CodeIgniter框架源码笔记(8)——性能调试:基准测试类Benchmark.php
- getLayoutParams()和setLayoutParams()方法源码,有需要的朋友可以参考下。
- Sphinx的安装和yii框架的使用
- FragmentPagerAdapter
- Silex:security(一)
- ThinkPHP判断post,get操作
- PHP-编译运行过程以及opcode缓存的笔记
- 初识IntPtr
- Yii 利用CConsoleCommand 实现计划任务
- Ubuntu 用vsftpd 配置FTP服务器
- PHP 安全三板斧:过滤、验证和转义之转义篇 & Blade模板引擎避免XSS攻击原理探究
- 编译安装php之安装libiconv-1.14.tar.gz出错解决方法
- Yii2中request的使用方法
- php的cookie和session相同主域名共享
- SPL(2)--- ArraryIterator迭代器
- phpexcel
- PHP创建和添加压缩文件
- 基于CTP的程序化交易系统开发(三)
- 基于CTP的程序化交易系统开发(二)
- 基于CTP的程序化交易系统开发(一)