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
// 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;
}
}
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:
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:
# 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:
| Frequency | Cron Expression | Use Case |
|---|---|---|
| Every minute | * * * * * | Real-time sync, urgent queues |
| Every 5 minutes | */5 * * * * | Stock updates, order polling |
| Every 10 minutes | */10 * * * * | Catalog sync, report refresh |
| Hourly | 0 * * * * | Aggregations, cleanup |
| Daily | 0 2 * * * | Full reindex, heavy reports |
4. Export Documentation
After adding the crontab entry, export the cron documentation:
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:
php bin/console app:product:sync-catalog -e=dev
Check for output in the terminal and in the log file:
tail -f var/logs/dev.log | grep "product catalog"
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.commandtag - 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
- Architecture: Bundle Responsibilities for command design patterns
- Adding a Queue Processor if your cronjob processes queued tasks
- CI/CD Pipeline for how tests run on your new command