Web Scheduler
Planifier et automatiser les breakouts CSWeb directement depuis l'interface Web, sans éditer de crontab manuellement. Chaque dictionnaire peut avoir son propre planning et génère ses propres fichiers log.
Nouveauté v2.1 : Le Web Scheduler remplace la configuration manuelle via crontab. Un seul cron système (csweb:scheduler-run) pilote l'ensemble des schedules configurés via l'UI.
Vue d'ensemble
Principe
Le Web Scheduler introduit une table dédiée cspro_breakout_scheduler qui stocke la configuration de planification pour chaque dictionnaire. Un unique crontab système appelle la commande csweb:scheduler-run chaque minute, qui interroge les schedules due et lance les breakouts correspondants.
┌─────────────────────────────────────────────────┐
│ Interface Web (UI) │
│ │
│ ┌──────────────────────────────────────────┐ │
│ │ Page Data Settings │ │
│ │ ┌────────────────────────────────────┐ │ │
│ │ │ Onglet "Breakout Scheduler" │ │ │
│ │ │ - Add / Edit / Toggle / Delete │ │ │
│ │ │ - Cron expression par dict │ │ │
│ │ │ - Status, Last Run, Next Run │ │ │
│ │ └────────────────────────────────────┘ │ │
│ └──────────────────────────────────────────┘ │
└──────────────────────┬──────────────────────────┘
│ AJAX (REST)
v
┌─────────────────────────────────────────────────┐
│ Controller API (5 endpoints) │
│ GET /scheduler/schedules │
│ POST /scheduler/add │
│ PUT /scheduler/update | /scheduler/toggle │
│ DELETE /scheduler/{id} │
└──────────────────────┬──────────────────────────┘
│
v
┌─────────────────────────────────────────────────┐
│ Service BreakoutScheduler.php │
│ CRUD + getDueSchedules() + markRun() │
└──────────────────────┬──────────────────────────┘
│
v
┌─────────────────────────────────────────────────┐
│ Table MySQL : cspro_breakout_scheduler │
│ (FK vers cspro_dictionaries) │
└──────────────────────┬──────────────────────────┘
│
* * * * * (crontab)
│
v
┌─────────────────────────────────────────────────┐
│ csweb:scheduler-run (Commande Symfony) │
│ - Interroge getDueSchedules() │
│ - Lance csweb:process-cases-by-dict par dict │
│ - Écrit logs dans var/logs/breakout/ │
│ - Met à jour last_run, next_run, exit_code │
└─────────────────────────────────────────────────┘Avantages par rapport au cron manuel
| Fonctionnalité | Cron Manuel | Web Scheduler |
|---|---|---|
| Configuration | Éditer crontab SSH | Interface Web |
| Granularité | Par commande | Par dictionnaire |
| Logs | Un seul fichier | Un log par dict + timestamp |
| Monitoring | Aucun | Last Run, Next Run, Exit Code |
| Toggle on/off | Commenter/décommenter | Bouton toggle on/off |
| Historique | Non | Oui (table MySQL) |
Configuration Initiale
1. Activer le Crontab Système
Un seul cron suffit pour piloter tous les schedules :
# Éditer crontab
crontab -e
# Ajouter cette ligne (exécution chaque minute)
* * * * * php /var/www/html/bin/console csweb:scheduler-run --env=prod >> /var/log/scheduler.log 2>&1Avec Docker (Intégré)
Le Dockerfile CSWeb inclut déjà un cron intégré qui est démarré automatiquement par le docker-entrypoint.sh. Aucune configuration supplémentaire n'est nécessaire si vous utilisez l'image Docker officielle.
Le cron intégré exécute csweb:scheduler-run chaque minute via /etc/cron.d/csweb-scheduler.
Si vous préférez configurer le cron depuis l'hôte :
# Alternative : crontab sur l'hôte
* * * * * docker compose exec -T csweb php bin/console csweb:scheduler-run --env=prod >> /var/log/scheduler.log 2>&12. Migration de la base de données
Si vous upgrader depuis une version antérieure (schema version 7), la migration crée automatiquement la table cspro_breakout_scheduler :
# Accéder à la page d'upgrade
http://your-server/upgrade/upgrade.phpPour une nouvelle installation, la table est créée automatiquement lors du setup initial.
Utilisation de l'Interface Web
Accéder au Scheduler
- Se connecter à CSWeb avec un compte Administrateur
- Naviguer vers Settings > Data
- Cliquer sur l'onglet Breakout Scheduler
Ajouter un Schedule
- Cliquer sur Add Schedule
- Sélectionner le dictionnaire (seuls les dictionnaires configurés avec un schema breakout et non encore schedulés sont listés)
- Saisir l'expression cron (ex:
0 2 * * *pour tous les jours à 2h) - Cocher Enabled pour activer immédiatement
- Cliquer Save
Expressions Cron
Format standard : minute heure jour mois jour_semaine
| Expression | Signification |
|---|---|
0 2 * * * | Tous les jours à 2h00 |
0 */6 * * * | Toutes les 6 heures |
*/30 * * * * | Toutes les 30 minutes |
0 2 * * 1-5 | Lundi au vendredi à 2h00 |
0 0 1 * * | Premier jour du mois à minuit |
0 2 * * 0 | Chaque dimanche à 2h00 |
Tableau de suivi
La table affiche en temps réel :
| Colonne | Description |
|---|---|
| Dictionary | Nom et label du dictionnaire |
| Schedule (Cron) | Expression cron configurée |
| Status | Badge Active (vert) ou Inactive (gris) |
| Last Run | Date/heure de la dernière exécution |
| Next Run | Prochaine exécution prévue |
| Actions | Toggle, Edit, Run Now, Delete |
Actions disponibles
- Toggle (on/off) : Active ou désactive le schedule sans le supprimer
- Edit (crayon) : Modifier l'expression cron ou le statut enabled
- Run Now (play) : Lancer un breakout manuel immédiat pour ce dictionnaire
- Delete (corbeille) : Supprimer le schedule (avec confirmation via modal Bootstrap)
Logs par Dictionnaire
Chaque exécution génère un fichier log individuel dans var/logs/breakout/ :
var/logs/breakout/
EVAL_DICT_2026-03-19_02-00-01.log
EVAL_DICT_2026-03-20_02-00-00.log
KAIROS_DICT_2026-03-19_02-00-01.log
KAIROS_DICT_2026-03-20_02-00-00.logContenu d'un fichier log
Command: /usr/bin/php /var/www/html/bin/console csweb:process-cases-by-dict EVAL_DICT --env=prod
Started: 2026-03-19_02-00-01
Exit code: 0
--- STDOUT ---
Running blob breakout process.
Processing dictionary: EVAL_DICT- Running threads 0
creating a new blob breakout thread
...
--- STDERR ---
Consulter les logs via l'interface Web
L'onglet Breakout Logs dans la page Data Settings offre un viewer complet :
- Sidebar dictionnaires : filtrer les logs par dictionnaire avec recherche
- Table DataTable : tri par date, taille, type (manual/scheduled), pagination
- Modal viewer : visualisation du contenu du log (thème sombre, numéros de ligne, word wrap, scroll)
- Actions : télécharger ou supprimer chaque fichier log
Consulter les logs en CLI
# Derniers logs d'un dictionnaire
ls -la var/logs/breakout/EVAL_DICT_*.log
# Contenu du dernier log
cat var/logs/breakout/EVAL_DICT_$(ls -t var/logs/breakout/EVAL_DICT_*.log | head -1)
# Rechercher erreurs
grep -l "Exit code: [^0]" var/logs/breakout/*.logNettoyage automatique des logs
Ajouter un cron de nettoyage :
# Supprimer logs de plus de 30 jours
0 3 * * * find /var/www/html/var/logs/breakout -name "*.log" -mtime +30 -deleteArchitecture Technique
Table MySQL
CREATE TABLE `cspro_breakout_scheduler` (
`id` int unsigned NOT NULL AUTO_INCREMENT,
`dictionary_id` smallint unsigned NOT NULL,
`enabled` tinyint(1) NOT NULL DEFAULT 0,
`cron_expression` varchar(100) NOT NULL DEFAULT '0 2 * * *',
`last_run` timestamp NULL DEFAULT NULL,
`next_run` timestamp NULL DEFAULT NULL,
`last_exit_code` int DEFAULT NULL,
`last_log_file` varchar(255) DEFAULT NULL,
`modified_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`created_time` timestamp DEFAULT '1971-01-01 00:00:00',
PRIMARY KEY (`id`),
UNIQUE KEY `dictionary_id` (`dictionary_id`),
CONSTRAINT FOREIGN KEY (`dictionary_id`) REFERENCES `cspro_dictionaries`(`id`) ON DELETE CASCADE
);Note : La contrainte
UNIQUEsurdictionary_idgarantit un seul schedule par dictionnaire. La contrainteON DELETE CASCADEsupprime automatiquement le schedule si le dictionnaire est supprimé.
Endpoints API
| Methode | Route | Description |
|---|---|---|
| GET | /scheduler/schedules | Liste des schedules + dictionnaires non schedulés |
| POST | /scheduler/add | Ajouter un schedule |
| PUT | /scheduler/update | Modifier cron + enabled |
| PUT | /scheduler/toggle | Basculer enabled/disabled |
| DELETE | /scheduler/{id} | Supprimer un schedule |
Dépendance PHP
Le package dragonmantank/cron-expression (^3.3) est utilisé pour :
- Valider les expressions cron saisies par l'utilisateur
- Calculer la prochaine date d'exécution (
next_run)
Commande CLI : csweb:scheduler-run
La commande est conçue pour être appelée chaque minute par le crontab système.
php bin/console csweb:scheduler-run --env=prodFonctionnement
- Acquiert un lock (empêche les exécutions concurrentes via
LockableTrait) - Interroge
getDueSchedules(): tous les schedules oùenabled=1etnext_run <= NOW() - Pour chaque schedule due :
- Lance
csweb:process-cases-by-dict DICT_NAMEviaSymfony\Process - Capture stdout + stderr dans un fichier log
{DICT_NAME}_{datetime}.log - Appelle
markRun()pour mettre à jourlast_run,next_run,last_exit_code,last_log_file
- Lance
- Relache le lock
Timeout
Chaque processus de breakout a un timeout de 3600 secondes (1 heure). Si un breakout dépasse ce temps, il est interrompu.
Dépannage
Le scheduler ne s'exécute pas
- Vérifier que le crontab est actif :
crontab -l | grep scheduler- Vérifier les logs du scheduler :
tail -f /var/log/scheduler.log- Tester manuellement :
php bin/console csweb:scheduler-run --env=prod -vvvSchedule ajouté mais "Next Run" vide
Le next_run n'est calculé que si le schedule est enabled. Vérifier que le toggle est sur Active.
Erreur "Invalid cron expression"
L'expression cron doit respecter le format standard à 5 champs. Les extensions comme @daily ou @hourly ne sont pas supportées. Utiliser les équivalents numériques.
Lock : "The scheduler is already running"
Si un breakout précédent est encore en cours, le lock empêche une nouvelle exécution. Attendre la fin du processus ou vérifier :
# Voir si un processus scheduler est actif
ps aux | grep scheduler-runBonnes Pratiques
- Un seul crontab : Ne pas créer de crons manuels pour les dictionnaires gérés par le scheduler
- Expressions prudentes : Éviter
*/1 * * * *pour des breakouts lourds - préférer des intervalles de 30 min minimum - Nettoyage logs : Configurer un cron de cleanup pour
var/logs/breakout/ - Monitoring : Consulter régulièrement l'onglet Breakout Logs pour détecter les erreurs
Ressources
- Breakout Automatique - Méthodes alternatives (cron manuel, webhooks)
- Breakout Sélectif - Breakout à la demande
- CLI - scheduler-run - Référence de la commande
- CLI - process-cases-by-dict - Commande de breakout sous-jacente
- Monitoring - Surveillance des breakouts
- Backup & Restore - Sauvegardes automatiques