sfTaskLoggerPlugin
1.0.2stable
for sf 1.4sf 1.3sf 1.2sf 1.1 MIT
The sfTaskLoggerPlugin allows you to run custom tasks and store the results. Results are stored in the database in a specific table and/or in a log file. Each task
has its own log file, which is stored in a specific directory depending on its namespace and name. (/log/task/:TASK_NAMESPACE/:TASK_NAME). It allows you to have a clean log history of all the CRON executed by your symfony project.
Developers
| Name |
Status |
Email |
Vernet Loïc |
lead |
rf.oohay <<ta>> lioc_frq
|
License
Plugin by Vernet Loïc aka COil. (qrf_coil[at]yahoo[dot]fr)
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
sfTaskLoggerPlugin
The sfTaskLoggerPlugin allows you to run custom tasks and store the results.
Results are stored in the database in a specific table and/or in a log file. Each task
has its own log file, witch is stored in a specific directory depending on its
namespace and name. (/log/tasks/:TASK_NAMESPACE/:TASK_NAME). It allows you
to have a clean log history of all the CRON executed by your symfony project.
The database record stores the following informations:
- Name of the task
- List of arguments of the task
- List of options of the task
- Count of processed records
- Count of NOT processed records
- Flag that tells if task is actually running
- Last record Id fully processed without error
- Process start time
- Process end time
- Flag that tells if task finished without error
- An error code for success or failure of the task
- The full console output of the task (optional)
- The log file path associated to the task
- Additional admin comments about the task and its results (may be modified in an admin generator module)
The plugin base task has several useful options:
config: The YAML config used by the plugin (explained in the next section)
check-running: Check that the task is not currently running
only-processed: Record into log or database only if there were things processed by the task
once-by-day: Check that the task was not already executed once today
The plugin is both Doctrine and
Propel friendly, it you are using Doctrine, the
/lib/config/doctrine/schema.yml will be used whereas using Propel
the /lib/config/schema.yml will be used. (BUT,I am sorry but I didn't test
the Propel version with the last 1.4 package, so feel free to report me issues
so I can fix them quickly)
Installation
Install the plugin:
$ symfony plugin:install sfTaskLoggerPlugin
(or download it and unzip in your /plugins directory)
Build the new plugin table and associated models:
$ symfony doctrine:build-all-reload
(or launch each "build" task individually)
Or for Propel:
$ symfony propel:build-all-load
At this point you should have
- A new table called
tl_tasks in your database
- A new set of model classes in
lib/model/sfTaskLoggerPlugin or lib/model/sfTaskLoggerPlugin
Clear you cache
$ symfony cc
Configuration
The plugin comes with a base task class witch is named sfBaseTaskLoggerTask
Therefore your tasks must extend this one. Because there is no auto-loading at
the task level, one must include it manually:
require_once(dirname(__FILE__). '/sfBaseTaskLoggerTask.class.php');
Of course you will have to change this path depending on where is located your
task. For example if it is located in the /lib/task folder of your project, use
the following code.
Generally you will want to extend all your tasks with a custom project task
so all of them will benefit from its generic methods, arguments or options
(thus, it must stay abstract). It would looks like this:
/**
* This the base task for all tasks of myProject.
*
* @author COil
* @since 01/09/2010
*/
require_once(dirname(__FILE__). '/../../plugins/sfTaskLoggerPlugin/lib/task/sfBaseTaskLoggerTask.class.php');
abstract class mySuperBaseTask extends sfBaseTaskLoggerTask
{
/**
* This function is callable by all the project tasks.
*/
public function superFunction()
{
}
}
Your final task should extends this custom task and look like this:
/**
* This a custom task
*
* @author Vernet Loïc aka COil <qrf_coil]at[yahoo[dot]fr>
* @since 1.0.0 - 7 aug 2009
*/
class sfMyTask extends mySuperBaseTask
{
// check the following section for functions to implement
}
Moreover the plugin comes with a default YAML configuration file, this file allows
you to tell if you want to log into the database, a file or both:
Copy the /plugins/sfTaskLoggerPlugin/config/plugin_sftl.yml into the config folder
of your application. Then this file will be used.
Now, you can add your own configurations. (copy paste the default one and rename the
key of the configuration) You should keep the default one witch is the basic
configuration provided by the plugin.
To use a specific config for a task, pass a config option to the task. (--config=myConfig)
where myConfig is the key of your configuration. If the config is invalid
an alert will be raised.
Usage
In your task (like sfMyTask above):
1 - Implement the configure() method as you would do with a standard task:
(don't forget to call the parent method to include generic parameters and options)
/**
* Main task configuration.
*/
protected function configure()
{
parent::configure();
$this->addArguments(array(
new sfCommandArgument('arg_1', sfCommandArgument::OPTIONAL, 'Test argument 1', 'arg_1_value'),
new sfCommandArgument('arg_2', sfCommandArgument::OPTIONAL, 'Test argument 2', 'arg_2_value'),
));
$this->namespace = 'sf_task_logger';
$this->name = 'sample';
$this->briefDescription = 'This is a sample task !';
$this->detailedDescription = <<<EOF
The task [sf_task_logger:sample|INFO] doesn't do that much.
It logs itself in the database and in the file system:
[./symfony sf_task_logger:sample --env=prod|INFO]
EOF;
}
Now there are 2 specific methods to implement:
2 - checkParameters()
(don't forget to call the parent method too)
/**
* Advanced check of task parameters.
*/
protected function checkParameters($arguments = array(), $options = array())
{
parent::checkParameters($arguments, $options);
if ($this->args['arg_1'] != 'arg_1_value')
{
throw new InvalidArgumentException('The value for argument 1 is not valid ! Check the help of the task.');
}
return true;
}
This method can be useful if you have advanced controls to do on task parameters or
arguments. Raise an InvalidArgumentException if there is at least an invalid parameter.
Don't forget to call at first the parent function so generic parameters can be
checked at the base task level. (or at your project base task level)
4 - doProcess()
/**
* Main task process.
*/
protected function doProcess($arguments = array(), $options = array())
{
try
{
$this->printAndLog(' - This is a log info !!');
$this->task->setErrorCode(self::ERROR_CODE_SUCCESS);
$this->setOk();
}
catch (Exception $e)
{
$this->task->setErrorCode(self::ERROR_CODE_FAILURE);
$this->setNOk($e);
}
}
This is the main method of your task process. $this->task is the database
object that will be saved. As you can see the setOk() and setNOk methods
allow to set the status flag automatically depending on the success or
failure of the task. We also set a status code that will give more details
than success or not about how ended the process.
If you want to resume a batch process from a given id, you can use the last_id_processed
field for this purpose.
Finally, if you want more control on the task process you can also re-implement the execute()
method of the base class witch is responsible for calling all others sub functions:
/**
* Global process of the task.
*
* @see sfTask
*/
protected function execute($arguments = array(), $options = array())
{
$this->createContext();
$this->config = $this->checkAndGetConfig($options['config']);
$this->checkConfig();
$this->setParameters($arguments, $options);
$this->initDatabaseManager();
$this->checkParameters($arguments, $options);
$this->initLogger();
$this->logStart();
$this->doProcess($arguments, $options);
$this->logEnd();
}
Notes
The plugin is bundled with a sample task: /lib/task/sfTaskLoggerSampleTask.class.php
witch can be run with the following command (replace "frontend" with a valid application
name of your project and "dev" with a valid environment):
> ./symfony task-logger:sample --application="frontend" --env="dev"
And also with a task: /lib/task/sfTaskLoggerPurgeRunningTask.class.php
to purge tasks who ended with a fatal error and witch stayed
with the running flag to "ON":
> ./symfony task-logger:purge --task="myProject:myTask" --application=backend --env="dev"
TODO
- Add an admin comment when purging batchs
- Include model functions to get the list of already executed task
- Include a Doctrine admin generator module
- Test Propel version
Support
Please report bugs on the symfony TRAC, I could also answer if you ask on the
symfony mailing list or IRC.
Changelog
(check the changelog tab)
See you. COil :)
This plugin is sponsored by SQL Technologies
