<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006-2014 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// |
// +----------------------------------------------------------------------
namespace Think;
/**
* 日志处理类
* 今天开始处理日志类,据说 阿里的日志文件每天都是 TB 的量 计算的
*/
class Log {

// 日志级别 从上到下,由低到高
const EMERG = 'EMERG'; // 严重错误: 导致系统崩溃无法使用
const ALERT = 'ALERT'; // 警戒性错误: 必须被立即修改的错误
const CRIT = 'CRIT'; // 临界值错误: 超过临界值的错误,例如一天24小时,而输入的是25小时这样
const ERR = 'ERR'; // 一般错误: 一般性错误
const WARN = 'WARN'; // 警告性错误: 需要发出警告的错误
const NOTICE = 'NOTIC'; // 通知: 程序可以运行但是还不够完美的错误
const INFO = 'INFO'; // 信息: 程序输出信息
const DEBUG = 'DEBUG'; // 调试: 调试信息
const SQL = 'SQL'; // SQL:SQL语句 注意只在调试模式开启时有效
// 其实这个才是程序部分的精华
// 日志信息
static protected $log = array(); // 日志内存准备,这个应该跟靠谱一点的描述

// 日志存储
static protected $storage = null; // 是不是 跟着那个 protected static $storage = null
// 找到了,原理是个 具体操作存储日志的 class的实例化 的对象

// 日志初始化
static public function init($config=array()){ // 这个初始化,可不是系统默认自动的初始化
$type = isset($config['type']) ? $config['type'] : 'File'; // 日志类型,一般都是文件呢
$class = strpos($type,'\\')? $type: 'Think\\Log\\Driver\\'. ucwords(strtolower($type));
// 组合 class
// if 那个 包含 \ 这个的话,其实就是证明了 是完整的路径,
// 否则,变成了 驼峰命名法
unset($config['type']);// 去掉了 当前的 ,防止 被处理掉
self::$storage = new $class($config); // 处理了 这个
}// 这个 是这个

/**
* 记录日志 并且会过滤未经设置的级别
* @static
* @access public
* @param string $message 日志信息
* @param string $level 日志级别
* @param boolean $record 是否强制记录
* @return void
*/
static function record($message,$level=self::ERR,$record=false) {// 记录
// 如果,允许记录,或者 strpos self::ERR ERR 这里的 如果不是这个
if($record || false !== strpos(C('LOG_LEVEL'),$level)) {
// 'LOG_LEVEL' => 'EMERG,ALERT,CRIT,ERR',// 允许记录的日志级别
// 这里的让我懂了,其实,如果你不看这里的东西的话,so
self::$log[] = "{$level}: {$message}\r\n"; // 如:ERR:这个没什么位置。
}// 或者
}// 总结,按照他说的,就是,如果允许记录,或者,产生了,错误的日志的话,就会根据当前的日志基本 进行日志记录

/**
* 日志保存
* @static
* @access public
* @param integer $type 日志记录方式
* @param string $destination 写入目标
* @return void
* 保存日志
*/
static function save($type='',$destination='') { // 保存 到数据里面了
if(empty(self::$log)) return ;// 没数据了,搞啥呢?哈哈

if(empty($destination)){// 写入目标, 如果没有目标 位置
$destination = C('LOG_PATH').date('y_m_d').'.log'; // 促出的位置为 .log 类似
}
if(!self::$storage){// 如果没有这个 self ,存储的设置个
$type = $type ? : C('LOG_TYPE'); // 这个默认的三元运算符好用
$class = 'Think\\Log\\Driver\\'. ucwords($type);// 默认的
self::$storage = new $class();
}
$message = implode('',self::$log); // 将数组 转换成为 字符串,
// 弄了半天,其实就是个 各种数据准备
self::$storage->write($message,$destination);// 看来内置函数的高大尚上啊,其实好像就只有 sae 跟 普通文件 两种方式,感觉好像是很高大上的样子呢
// 保存后清空日志缓存
self::$log = array();
}
// 总结:数据准备---》外包----》打算房间,你觉得呢?有能跟上我的节奏的吗,哈哈

/**
* 日志直接写入
* @static
* @access public
* @param string $message 日志信息
* @param string $level 日志级别
* @param integer $type 日志记录方式
* @param string $destination 写入目标
* @return void
* 各个,你居然外包给我了,
*/
static function write($message,$level=self::ERR,$type='',$destination='') {
if(!self::$storage){
$type = $type ? : C('LOG_TYPE');
$class = 'Think\\Log\\Driver\\'. ucwords($type);
$config['log_path'] = C('LOG_PATH');
self::$storage = new $class($config);
}// 在来一遍,这个你就不能 弄个 外包吗,不简单吗
if(empty($destination)){
$destination = C('LOG_PATH').date('y_m_d').'.log';
}// 位置
self::$storage->write("{$level}: {$message}", $destination);
}// 总结,还是外包,有意思吗?基本上就是别名啊,不过是个组合版本的别名,牛叉吧

}