sfTaskLoggerPlugin - 1.0.3

The sfTaskLoggerPlugin allow you to run tasks and store the results in both database and/or a log file.

You are currently browsing
the website for symfony 1

Visit the Symfony2 website


« Back to the Plugins Home

Signin


Forgot your password?
Create an account

Tools

Stats

advanced search
Information Readme Releases Changelog Contribute
Show source

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, which 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 (can be modified with the 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. (I am sorry but I didn't test the Propel version with the last 1.4 package, so feel free to report me issues if you use it with Propel. Neither the admin generator module is available.)

Installation

  • Install the plugin:

    $ symfony plugin:install sfTaskLoggerPlugin
    

    (download it and unzip in your /plugins directory or use svn http://svn.symfony-project.com/plugins/sfTaskLoggerPlugin/tags/sfTaskLoggerPlugin_1_0_4/)

  • Build the new plugin table and associated models:

    $ ./symfony doctrine:build --all-classes --db --and-load --env=dev
    

    (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/doctrine/sfTaskLoggerPlugin
  • Clear you cache

    $ symfony cc
    

Configuration

The plugin comes with a base task class which 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 which 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 which 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();
}

Admin generator module

The plugin comes with a handy admin generator module (Doctrine, symfony >= 1.2) in order to manage the main tl_task table.

Add the module tl_task to the enabled module list of the settings.yml file of your application.

    enabled_modules:  [default, tl_task]

After having generated all the model files of the plugin, edit the /lib/model/doctrine/sfTaskLoggerPlugin/tlTaskTable.class.php class and make it extend the class PlugintlTaskTableExtended:

/**
 * tlTaskTable
 *
 * This class has been auto-generated by the Doctrine ORM Framework
 */
class tlTaskTable extends PlugintlTaskTableExtended
{
    /**
     * Returns an instance of this class.
     *
     * @return object tlTaskTable
     */
    public static function getInstance()
    {
        return Doctrine_Core::getTable('tlTask');
    }
}

Then call the module, you_backend.php/tl_task ! That's it ! ;)

The plugin comes with a route tl_task for this admin generator module.

Notes

The plugin is bundled with a sample task: /lib/task/sfTaskLoggerSampleTask.class.php which 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 which stayed with the running flag to "ON":

> ./symfony task-logger:purge --task="myProject:myTask" --application=backend --env="dev"

Console output

You may want to have your console output disabled when running cron tasks, for example because of some server related configuration - in this case, add the --quiet option to your cli command line:

 ./symfony task-logger:sample --application=frontend --env="prod" --quiet

TODO

  • V1.1.0: Advanced features to keep a state of "processed objects"
  • V1.0.5: Test the Propel version

Support

Send me an email or report bugs on the symfony TRAC, I could also answer if you ask on the symfony mailing list.

Changelog

(check the changelog tab)


See you. COil :)


This plugin is sponsored by SQL Technologies

SQL Technologies