Extending CLogger - how to configure?

Hi!

I have extended CLogger and now I am struggeling how to set the config in a way it takes my class instead of CLogger.

Is there a way? Did someone do this before?

Thanks,

Hein

CLogger is not configurable because it is managed by the static class Yii (via YiiBase). The only way to replace the default CLogger with your own version is to rewrite the Yii class by extending YiiBase (it’s very simple).

Thanks qiang! I only wanted to override log() anyway, so maybe extending YiiBase is the better idea anyway.

Cheers,

Hein

Hmm, this gets bigger and bigger.

What I tried to do is this: I have a bunch of Yii::log() with level INFO. Usually I dont log these, so the route does not have the info category.

I noticed that the logs are in memory anyway. So I thought it would be nice to write all the info levels too, just if an error or warning was issued. I would have more logs on cases I have to look at and less if all works fine.

How would you do that? I thought of doing it in my LogFilter, but I realised that the filter is only called after getLogs(), so the info’s are gone already when the filter handles them.

Cheers,

Hein

I also need to extend the CLogger::log() method. Is there always no way (I’m using Yii 1.1, now) to configure it in config/main.php as




                'logger'=>array(

                        'class'=>'Logger',

                ),



It is not possible to configure the Yii::logger component as it is hard coded in YiiBase::log() and YiiBase::getLogger(), and in a private property $_logger.

So the only way I found is to overwrite these methods in the Yii class.

It is not satisfying as yiilite also has a Yii class, so I have also to put the overwritten methods in this file.


class Yii extends YiiBase

{

        private static $_logger;


        /**

         * Logs a message.

         * Messages logged by this method may be retrieved via {@link Logger::getLogs}

         * and may be recorded in different media, such as file, email, database, using

         * {@link CLogRouter}.

         * @param string message to be logged

         * @param string level of the message (e.g. 'trace', 'warning', 'error'). It is case-insensitive.

         * @param string category of the message (e.g. 'system.web'). It is case-insensitive.

         */

        public static function log($msg,$level=CLogger::LEVEL_INFO,$category='application')

        {

                if(self::$_logger===null)

                        self::$_logger=new Logger;

                self::$_logger->log($msg,$level,$category);

        }


        /**

         * @return Logger message logger

         */

        public static function getLogger()

        {

                if(self::$_logger!==null)

                        return self::$_logger;

                else

                        return self::$_logger=new Logger;

        }


}



Did anyone found another method ?

Do I need to create a mylog and a mylogger component ?

NB: there are also private properties in CLogger, that is not easy to extend it.

Did anyone solved this I would also like a custom logger to use for logging access etc in a different file then application.log

No need to override the logger for this. You can provide different LogRoutes for different destinations.

http://www.yiiframework.com/doc/guide/topics.logging#message-routing

Thanks for replying !

hmm I might miss something here but i don’t see how, is it by using categories ?

Anyway I just loaded log4php as a extension.

thanks


array(

    'class'=>'CFileLogRoute',

    'levels'=>'trace, info',

    'logFile'=>'yourlogfile.log',

    'logPath'=>'/your/path/to/logfile',

),

What exactly you try to do? Yii comes with a very sophisticated logging. You can configure to do pretty much everything.

EDIT: Fixed logPath/logFile

In fact, I must override the CLogger, because the LogRoute is executed at the end of the application running.

So, if at the beginning of the script the user is logged in and you run Yii::log, and then you log out the user, LogRouter will not save the user id… It is the same thing with others variables. For me it is a great problem if I want to use Yii::Log.

It is always the case with Yii 1.1.1

LogRouter saves the log routes at the end, that’s right. But that doesn’t affect all the log messages collected during the application cycle. So you only have to make sure you call Yii::log() before you log out the user.

I did not enough explain why I wanted to extend CLogger:

I wanted to log various things about user actions, without always write


Yii::log('user_id='.Yii->app()->user->id."::action=$action::message=$message", 'info');

and then parsing all the messages…

I thought that CLogger/CLogRouter was a good tool for storing user information and messages into a table.

CLogRouter does not save anything about user information.

Extending CLogRouter to log the user information is wrong because it saves all the messages at the end of the application.

I needed to extend the Yii::log() function itself.

CLogger is the class to extend.

Why not wrap that in a utility function?


function log($message,$level) {

  Yii::log(..whatever you want...);

}

Because I want to store user information with the message, and Yii::log() does not return any ID I could link to the user information and I do not want to store a string message as said.

Maybe I should not use Yii::log to store user information…

Did you read my suggestion? You can add any information you want in that helper method.


function log($message,$level) {

  Yii::log('user_id='.Yii->app()->user->id."::message=$message", $level);

}

Sorry, I quote myself:

So I wanted to log the user id into a separated column, to accelerate access.

do you resolve this problem? how?

I had to modify some Yii files, as I said at #6, and it is not satisfying.