Skip to content

Adding a Cronjob ​

This guide walks through creating a new scheduled command in Logidav, from writing the command class to registering it in the system crontab.

1. Create the Command Class ​

Place your command in the appropriate subdirectory of src/AppBundle/Command/. Commands are organized by domain: Sale/, Product/, Stock/, Payment/, Refund/, etc.

php
<?php
// src/AppBundle/Command/Product/SyncProductCatalogCommand.php

namespace AppBundle\Command\Product;

use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
use Symfony\Component\Console\Command\LockableTrait;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

class SyncProductCatalogCommand extends ContainerAwareCommand
{
    use LockableTrait;

    protected function configure()
    {
        $this
            ->setName('app:product:sync-catalog')
            ->setDescription('Synchronize product catalog from external source');
    }

    protected function execute(InputInterface $input, OutputInterface $output)
    {
        if (!$this->lock()) {
            $output->writeln('The command is already running in another process.');
            return 0;
        }

        try {
            $container = $this->getContainer();
            $logger = $container->get('logger');

            $logger->info('Starting product catalog sync');

            // Your business logic here
            $service = $container->get('app.service.product');
            $result = $service->syncCatalog();

            $logger->info('Product catalog sync completed', [
                'processed' => $result['processed'],
                'errors' => $result['errors'],
            ]);

            $output->writeln(sprintf('Sync complete: %d processed, %d errors',
                $result['processed'],
                $result['errors']
            ));
        } catch (\Exception $e) {
            $logger->error('Product catalog sync failed', [
                'error' => $e->getMessage(),
            ]);
            throw $e;
        } finally {
            $this->release();
        }

        return 0;
    }
}

WARNING

Always use LockableTrait on commands that run on cron. Without it, overlapping executions can cause duplicate processing, data corruption, or resource exhaustion. The lock is file-based and stored in the system temp directory.

2. Register as a Service ​

Add your command to src/AppBundle/Resources/config/services.yml:

yaml
services:
    app.command.product.sync_catalog:
        class: AppBundle\Command\Product\SyncProductCatalogCommand
        tags:
            - { name: console.command }

3. Add to System Crontab ​

The source of truth for all scheduled commands is the production crontab exported to docs/content/projects/logidav/reference/operations/system-crontab.md. Add the new entry to the system crontab, then export it with the Symfony command.

All cron entries use the run_job.sh wrapper, which provides JSON-structured logging and error capture:

bash
# Product catalog sync - every 10 minutes
*/10 * * * * /path/to/run_job.sh php bin/console app:product:sync-catalog -e=prod

Choose an appropriate schedule based on the command's requirements:

FrequencyCron ExpressionUse Case
Every minute* * * * *Real-time sync, urgent queues
Every 5 minutes*/5 * * * *Stock updates, order polling
Every 10 minutes*/10 * * * *Catalog sync, report refresh
Hourly0 * * * *Aggregations, cleanup
Daily0 2 * * *Full reindex, heavy reports

4. Export Documentation ​

After adding the crontab entry, export the cron documentation:

bash
php bin/console logidav:cron:document

Verify your new command appears in the exported crontab. This documentation is used by the operations team to understand what runs and when.

5. Test Locally ​

Run the command in the dev environment:

bash
php bin/console app:product:sync-catalog -e=dev

Check for output in the terminal and in the log file:

bash
tail -f var/logs/dev.log | grep "product catalog"

TIP

Use the -v, -vv, or -vvv flags for increasing verbosity during development. This is especially helpful for debugging data transformation issues.

Checklist ​

  • [ ] Command class created with LockableTrait
  • [ ] Service registered with console.command tag
  • [ ] Crontab entry exported with php bin/console logidav:cron:document
  • [ ] Cronjob catalog updated when command purpose, side effects, or risk classification changed
  • [ ] Tested locally in dev environment
  • [ ] Logs verified for correct output

See Also ​

Internal developer documentation for Menzzo systems.