Imagine you have a business method in your model which needs to be accessed by two environments: once from a symfony task and once from the web. So far so good, now what if this business method should be able to log contents somewhere visibly, in case of the command line task to console and to a file and in case of the web application to the default logging mechanisms used there?
Getting the logger in web context is easy, all you have to do is
- $logger = sfContext::getInstance()->getLogger();
but its a little harder to do for the command line task.
By default no symfony context is created for a command line task and even if it is created, the above call returns an instance of
sfNoLogger. Logging in command applications happens through the
sfTask::logSection() method, which basically throws an event at the created dispatcher in
SYMFONYDIR/lib/command/cli.php. There you can also see that an instance of
sfCommandLogger is created, but there is no way to get your fingers at this instance, because its purely local.
So what can we do? Parametricizing the business method with the
sfTask instance and using the
logSection() is obviously no solution, because this would break in web context where no such sfTask instance exists…
My solution was a bit more straight forward – I simply decided to not use the task-supplied logging schema at all, but created my own logger like this:
- $dispatcher = new sfEventDispatcher();
- $logger = new sfAggregateLogger($dispatcher);
- $logger->addLogger(new sfCommandLogger($dispatcher));
- // optionally add another file logger
- if ($logToFile)
- new sfFileLogger($this->dispatcher, …)
Hope this helps somebody.