yii自定义日志格式(加入用户ID,IP前缀)

RT,yii中有比较全面的日志系统设计。要自定义日志输出,只要继承LogFilter类,覆盖/重写/自定义相关方法即可。

这里用“实现每条日志加入用户ID,IP前缀”功能为例。

1.思路:自定义LogFilter类继承CLogFilter类,重写format方法

2.代码:

–自定义类LXDefaultLogFilter

class LXDefaultLogFilter extends CLogFilter  
{
    public $prefixClientIp = true;
    public function filter(&$logs)
    {
        if (!empty($logs))
        {
            $this->format($logs);
        }
        return $logs;
    }

    protected function format(&$logs)
    {
        $prefix='';
        if($this->prefixSession && ($id=session_id())!=='')
            $prefix.="[$id]";
        if($this->prefixClientIp)
            $prefix.="[".$this->getRealIpAddr()."]";
        if($this->prefixUser && ($user=Yii::app()->getComponent('user',false))!==null)
            $prefix.='['.$user->getName().']['.$user->getId().']';
        if($prefix!=='')
        {
            foreach($logs as &$log)
                $log[0]=$prefix.' '.$log[0];
        }
    }

    public function getRealIpAddr()
    {
        if (!empty($_SERVER['HTTP_CLIENT_IP']))   //check ip from share internet
        {
            $ip=$_SERVER['HTTP_CLIENT_IP'];
        }
        elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR']))   //to check ip is pass from proxy
        {
            $ip=$_SERVER['HTTP_X_FORWARDED_FOR'];
        }
        else if(!empty($_SERVER['REMOTE_ADDR']))
        {
            $ip=$_SERVER['REMOTE_ADDR'];
        }else{
            $ip='0.0.0.0';
        }
        return $ip;
    }
}

稍微讲解一下这个类:

  • format,其实是覆盖了父类的fomat方法。父类的format方法代码为:
protected function format(&$logs)  
{
    $prefix='';
    if($this->prefixSession && ($id=session_id())!=='')
        $prefix.="[$id]";
    if($this->prefixUser && ($user=Yii::app()->getComponent('user',false))!==null)
        $prefix.='['.$user->getName().']['.$user->getId().']';
    if($prefix!=='')
    {
        foreach($logs as &$log)
            $log[0]=$prefix.' '.$log[0];
    }
}
  • getRealIpAddr方法其实就是取得当前请求者的ip的

–在config文件main.php中给log组件加上该自定义过滤器

...
array(  
'class'=>'CFileLogRoute',  
'levels'=>'error',  
'maxFileSize' => 1024 * 5,  
"logPath"=>$logsPath,
"logFile"=>$logPrefix."error.log",
"filter"=> array(
    'class' => "LXDefaultLogFilter",
    'prefixSession' => false,
    'prefixUser' => true,
    'logUser' => true,
),
...