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)
{
$logger->addLogger(
new sfFileLogger($this->dispatcher, ...)
);
}
Hope this helps somebody.