Add Messenger monitor command, uploads backup, hourly cron
- MonitorMessengerCommand: checks failed messages, emails admin with details - Backup script: add /public/uploads tar.gz alongside DB dump - Ansible: cron every hour for messenger monitor - TASK_CHECKUP: mark infrastructure tasks done Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -55,5 +55,5 @@
|
|||||||
- [ ] Ajouter des tests pour le flow d'inscription via invitation
|
- [ ] Ajouter des tests pour le flow d'inscription via invitation
|
||||||
|
|
||||||
### Infrastructure
|
### Infrastructure
|
||||||
- [x] Configurer les crons pour les backups automatiques de la base de données (toutes les 30 min, rétention 7 jours)
|
- [x] Configurer les crons pour les backups automatiques (DB + uploads, toutes les 30 min, rétention 1 jour)
|
||||||
- [ ] Ajouter le monitoring des queues Messenger (failed messages)
|
- [x] Ajouter le monitoring des queues Messenger (commande + cron toutes les heures + email admin)
|
||||||
|
|||||||
@@ -12,12 +12,23 @@ docker compose -f /var/www/e-ticket/docker-compose-prod.yml exec -T database pg_
|
|||||||
|
|
||||||
# Check if backup was created
|
# Check if backup was created
|
||||||
if [ -f "${BACKUP_DIR}/${FILENAME}" ] && [ -s "${BACKUP_DIR}/${FILENAME}" ]; then
|
if [ -f "${BACKUP_DIR}/${FILENAME}" ] && [ -s "${BACKUP_DIR}/${FILENAME}" ]; then
|
||||||
echo "[$(date)] Backup OK: ${FILENAME} ($(du -h "${BACKUP_DIR}/${FILENAME}" | cut -f1))"
|
echo "[$(date)] DB Backup OK: ${FILENAME} ($(du -h "${BACKUP_DIR}/${FILENAME}" | cut -f1))"
|
||||||
else
|
else
|
||||||
echo "[$(date)] ERROR: Backup failed"
|
echo "[$(date)] ERROR: DB Backup failed"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Backup uploads
|
||||||
|
UPLOADS_FILENAME="uploads_${DATE}.tar.gz"
|
||||||
|
tar -czf "${BACKUP_DIR}/${UPLOADS_FILENAME}" -C /var/www/e-ticket/public uploads 2>/dev/null
|
||||||
|
|
||||||
|
if [ -f "${BACKUP_DIR}/${UPLOADS_FILENAME}" ]; then
|
||||||
|
echo "[$(date)] Uploads Backup OK: ${UPLOADS_FILENAME} ($(du -h "${BACKUP_DIR}/${UPLOADS_FILENAME}" | cut -f1))"
|
||||||
|
else
|
||||||
|
echo "[$(date)] WARNING: Uploads backup failed"
|
||||||
|
fi
|
||||||
|
|
||||||
# Remove backups older than KEEP_DAYS days
|
# Remove backups older than KEEP_DAYS days
|
||||||
find "${BACKUP_DIR}" -name "e_ticket_*.sql.gz" -mtime +${KEEP_DAYS} -delete
|
find "${BACKUP_DIR}" -name "e_ticket_*.sql.gz" -mtime +${KEEP_DAYS} -delete
|
||||||
|
find "${BACKUP_DIR}" -name "uploads_*.tar.gz" -mtime +${KEEP_DAYS} -delete
|
||||||
echo "[$(date)] Cleaned backups older than ${KEEP_DAYS} days"
|
echo "[$(date)] Cleaned backups older than ${KEEP_DAYS} days"
|
||||||
|
|||||||
@@ -189,6 +189,13 @@
|
|||||||
job: "/var/backups/e-ticket/backup.sh >> /var/log/e-ticket-backup.log 2>&1"
|
job: "/var/backups/e-ticket/backup.sh >> /var/log/e-ticket-backup.log 2>&1"
|
||||||
user: bot
|
user: bot
|
||||||
|
|
||||||
|
- name: Configure messenger monitor cron (every hour)
|
||||||
|
cron:
|
||||||
|
name: "e-ticket messenger monitor"
|
||||||
|
minute: "0"
|
||||||
|
job: "docker compose -f /var/www/e-ticket/docker-compose-prod.yml exec -T php php bin/console app:monitor:messenger --env=prod >> /var/log/e-ticket-messenger.log 2>&1"
|
||||||
|
user: bot
|
||||||
|
|
||||||
post_tasks:
|
post_tasks:
|
||||||
- name: Disable maintenance mode
|
- name: Disable maintenance mode
|
||||||
command: make maintenance_off
|
command: make maintenance_off
|
||||||
|
|||||||
72
src/Command/MonitorMessengerCommand.php
Normal file
72
src/Command/MonitorMessengerCommand.php
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Command;
|
||||||
|
|
||||||
|
use App\Entity\MessengerLog;
|
||||||
|
use App\Service\MailerService;
|
||||||
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
|
use Symfony\Component\Console\Attribute\AsCommand;
|
||||||
|
use Symfony\Component\Console\Command\Command;
|
||||||
|
use Symfony\Component\Console\Input\InputInterface;
|
||||||
|
use Symfony\Component\Console\Output\OutputInterface;
|
||||||
|
use Symfony\Component\Console\Style\SymfonyStyle;
|
||||||
|
|
||||||
|
#[AsCommand(
|
||||||
|
name: 'app:monitor:messenger',
|
||||||
|
description: 'Check for failed Messenger messages and notify admin',
|
||||||
|
)]
|
||||||
|
class MonitorMessengerCommand extends Command
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
private EntityManagerInterface $em,
|
||||||
|
private MailerService $mailer,
|
||||||
|
) {
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function execute(InputInterface $input, OutputInterface $output): int
|
||||||
|
{
|
||||||
|
$io = new SymfonyStyle($input, $output);
|
||||||
|
|
||||||
|
$failedMessages = $this->em->getRepository(MessengerLog::class)->findBy(
|
||||||
|
['status' => 'failed'],
|
||||||
|
['createdAt' => 'DESC'],
|
||||||
|
50,
|
||||||
|
);
|
||||||
|
|
||||||
|
$count = \count($failedMessages);
|
||||||
|
|
||||||
|
if (0 === $count) {
|
||||||
|
$io->success('No failed messages.');
|
||||||
|
|
||||||
|
return Command::SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
$io->warning($count.' failed message(s) found.');
|
||||||
|
|
||||||
|
$html = '<h2>'.$count.' message(s) en echec</h2><table style="width:100%;border-collapse:collapse;">';
|
||||||
|
$html .= '<tr style="background:#111827;color:#fff;"><th style="padding:8px;text-align:left;">Classe</th><th style="padding:8px;">Date</th><th style="padding:8px;">Erreur</th></tr>';
|
||||||
|
|
||||||
|
foreach ($failedMessages as $log) {
|
||||||
|
$html .= '<tr style="border-bottom:1px solid #eee;">';
|
||||||
|
$html .= '<td style="padding:8px;font-weight:bold;">'.$log->getMessageClass().'</td>';
|
||||||
|
$html .= '<td style="padding:8px;">'.$log->getCreatedAt()->format('d/m/Y H:i').'</td>';
|
||||||
|
$html .= '<td style="padding:8px;font-size:12px;color:#666;">'.mb_substr($log->getErrorMessage() ?? '', 0, 200).'</td>';
|
||||||
|
$html .= '</tr>';
|
||||||
|
}
|
||||||
|
$html .= '</table>';
|
||||||
|
|
||||||
|
$this->mailer->sendEmail(
|
||||||
|
'contact@e-cosplay.fr',
|
||||||
|
'[E-Ticket] '.$count.' message(s) Messenger en echec',
|
||||||
|
$html,
|
||||||
|
'E-Ticket <contact@e-cosplay.fr>',
|
||||||
|
null,
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
|
||||||
|
$io->info('Notification sent to contact@e-cosplay.fr');
|
||||||
|
|
||||||
|
return Command::SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user