Created
October 13, 2025 17:21
-
-
Save razametal/139cfe7e59fe146fb201f7016e4189e6 to your computer and use it in GitHub Desktop.
Monitor de OSCAM y PCSCD
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| cat <<'EOF' | sudo tee /usr/local/bin/oscam_pcscd_monitor.sh > /dev/null | |
| #!/bin/bash | |
| # | |
| # Monitor de oscam y pcscd | |
| # Reinicia pcscd y luego oscam si: | |
| # - pcscd no está activo | |
| # - oscam no está activo | |
| # - oscam está activo pero su API no responde (health check) | |
| # - el log de oscam muestra errores de lector en los últimos 30 s | |
| # | |
| # Autor: Guillermo Salas <[email protected]> | |
| # Fecha: 2025-08-05 | |
| # | |
| # -------------------------- | |
| # CONFIGURACIÓN | |
| # -------------------------- | |
| OSC_LOG="/var/log/oscam/oscam.log" | |
| ERR_PATTERNS=("Error getting card status" "Error Reader Exclusive" "Cannot open device:") | |
| MAX_AGE_SEC=30 | |
| LOCKFILE="/run/oscam_pcscd_monitor.lock" | |
| LOG="/var/log/oscam_pcscd_monitor.log" | |
| # -------------------------- | |
| # FUNCIONES | |
| # -------------------------- | |
| # Función para registrar eventos en el log | |
| log() { | |
| echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" >> "$LOG" | |
| } | |
| # Función Health check de la API de OSCam | |
| check_oscam_api() { | |
| log "Verificando la API de OSCam en http://localhost:8888/oscamapi.html" | |
| # Usamos curl para obtener solo el código de estado, con un timeout de 10s. | |
| # -o /dev/null descarta el contenido, -s es silencioso, -w "%{http_code}" imprime solo el código. | |
| local http_status | |
| http_status=$(curl --max-time 10 -o /dev/null -s -w "%{http_code}" http://localhost:8888/oscamapi.html) | |
| if [ "$http_status" -eq 401 ]; then | |
| log "API de OSCam responde correctamente (HTTP 401 Unauthorized)." | |
| return 0 # Éxito | |
| else | |
| log "La API de OSCam no responde como se espera. Código de estado recibido: $http_status" | |
| return 1 # Fallo | |
| fi | |
| } | |
| # Función para reiniciar los servicios de forma controlada | |
| restart_both() { | |
| log "Se detectó un problema. Procediendo a reiniciar los servicios." | |
| log "Reiniciando pcscd..." | |
| systemctl restart pcscd | |
| if systemctl is-active --quiet pcscd; then | |
| log "pcscd reiniciado con éxito." | |
| else | |
| log "ERROR: Falló el reinicio de pcscd." | |
| fi | |
| # Pequeña pausa para asegurar que pcscd esté completamente listo antes de reiniciar oscam | |
| sleep 5 | |
| log "Reiniciando oscam..." | |
| systemctl restart oscam | |
| if systemctl is-active --quiet oscam; then | |
| log "oscam reiniciado con éxito." | |
| else | |
| log "ERROR: Falló el reinicio de oscam." | |
| fi | |
| } | |
| # -------------------------- | |
| # BLOQUEO | |
| # -------------------------- | |
| exec 200>"$LOCKFILE" | |
| flock -n 200 || { log "Monitor ya en ejecución, saliendo."; exit 0; } | |
| RESTART_NEEDED=false | |
| # -------------------------- | |
| # 1. ¿pcscd está activo? | |
| # -------------------------- | |
| if ! systemctl is-active --quiet pcscd; then | |
| log "pcscd no está activo." | |
| RESTART_NEEDED=true | |
| fi | |
| # -------------------------- | |
| # 2. ¿oscam está activo Y responde? | |
| # -------------------------- | |
| if ! systemctl is-active --quiet oscam; then | |
| log "oscam no está activo." | |
| RESTART_NEEDED=true | |
| else | |
| # Si oscam está activo, verificamos su API | |
| if ! check_oscam_api; then | |
| log "El servicio oscam está 'activo' pero su API no responde. Se requiere reinicio." | |
| RESTART_NEEDED=true | |
| fi | |
| fi | |
| # -------------------------- | |
| # 3. ¿Hay errores recientes en el log? | |
| # -------------------------- | |
| if [[ -f "$OSC_LOG" ]]; then | |
| current_time=$(date +%s) | |
| while IFS= read -r line; do | |
| log_timestamp_str=$(echo "$line" | awk '{print $1" "$2}') | |
| log_time=$(date -d "$log_timestamp_str" +%s 2>/dev/null) | |
| if [[ -n "$log_time" && $((current_time - log_time)) -le $MAX_AGE_SEC ]]; then | |
| for pattern in "${ERR_PATTERNS[@]}"; do | |
| if echo "$line" | grep -qF "$pattern"; then | |
| log "Detectado error reciente en oscam.log: '$pattern'" | |
| RESTART_NEEDED=true | |
| break 2 | |
| fi | |
| done | |
| fi | |
| done < <(tail -n 1000 "$OSC_LOG") | |
| else | |
| log "Advertencia: no se encontró el log de oscam en $OSC_LOG" | |
| fi | |
| # -------------------------- | |
| # 4. Reiniciar si es necesario | |
| # -------------------------- | |
| if $RESTART_NEEDED; then | |
| restart_both | |
| else | |
| log "Estado de servicios OK. No se requiere acción." | |
| fi | |
| EOF | |
| # Dar permisos de ejecución: | |
| sudo chmod +x /usr/local/bin/oscam_pcscd_monitor.sh | |
| # Crear servicio en systemd para monitoreo y ejecución cada 30 minutos | |
| cat <<EOF > /etc/systemd/system/oscam_pcscd_monitor.service | |
| [Unit] | |
| Description=Monitor oscam y pcscd | |
| After=network.target | |
| [Service] | |
| Type=oneshot | |
| ExecStart=/usr/local/bin/oscam_pcscd_monitor.sh | |
| EOF | |
| cat <<EOF > /etc/systemd/system/oscam_pcscd_monitor.timer | |
| [Unit] | |
| Description=Ejecuta el monitor de oscam/pcscd cada 30 minutos | |
| Requires=oscam_pcscd_monitor.service | |
| [Timer] | |
| OnBootSec=10m | |
| OnUnitActiveSec=30m | |
| AccuracySec=1s | |
| [Install] | |
| WantedBy=timers.target | |
| EOF | |
| # Activar e iniciar el servicio | |
| systemctl daemon-reload | |
| systemctl enable oscam_pcscd_monitor.timer | |
| systemctl start oscam_pcscd_monitor.timer | |
| # Configurar la rotación de logs: | |
| cat <<EOF > /etc/logrotate.d/oscam_pcscd_monitor | |
| /var/log/oscam_pcscd_monitor.log { | |
| weekly | |
| rotate 7 | |
| compress | |
| delaycompress | |
| missingok | |
| notifempty | |
| create 640 root adm | |
| } | |
| EOF |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment