Replace format t logging with log4cl in playlist-scheduler
Converts all 22 format t print statements to 7 targeted log4cl calls: - log:info for successful operations (playlist loaded, scheduler started) - log:warn for recoverable failures (DB fallback, save/delete errors) - log:error for actionable failures (liquidsoap unresponsive, missing playlist) Removes redundant startup/shutdown chatter and per-retry debug noise.
This commit is contained in:
parent
0da8101f63
commit
1e5a7e75f3
|
|
@ -50,8 +50,6 @@
|
||||||
;; Step 1: Reload the playlist file in Liquidsoap
|
;; Step 1: Reload the playlist file in Liquidsoap
|
||||||
(dotimes (attempt max-retries)
|
(dotimes (attempt max-retries)
|
||||||
(let ((result (liquidsoap-command "stream-queue_m3u.reload")))
|
(let ((result (liquidsoap-command "stream-queue_m3u.reload")))
|
||||||
(format t "~&[SCHEDULER] Reload attempt ~a/~a: ~a~%"
|
|
||||||
(1+ attempt) max-retries (string-trim '(#\Space #\Newline #\Return) result))
|
|
||||||
(when (liquidsoap-command-succeeded-p result)
|
(when (liquidsoap-command-succeeded-p result)
|
||||||
(setf reload-ok t)
|
(setf reload-ok t)
|
||||||
(return)))
|
(return)))
|
||||||
|
|
@ -62,8 +60,6 @@
|
||||||
(sleep 1)) ; Brief pause after reload before skipping
|
(sleep 1)) ; Brief pause after reload before skipping
|
||||||
(dotimes (attempt max-retries)
|
(dotimes (attempt max-retries)
|
||||||
(let ((result (liquidsoap-command "stream-queue_m3u.skip")))
|
(let ((result (liquidsoap-command "stream-queue_m3u.skip")))
|
||||||
(format t "~&[SCHEDULER] Skip attempt ~a/~a: ~a~%"
|
|
||||||
(1+ attempt) max-retries (string-trim '(#\Space #\Newline #\Return) result))
|
|
||||||
(when (liquidsoap-command-succeeded-p result)
|
(when (liquidsoap-command-succeeded-p result)
|
||||||
(setf skip-ok t)
|
(setf skip-ok t)
|
||||||
(return)))
|
(return)))
|
||||||
|
|
@ -76,30 +72,23 @@
|
||||||
(let ((playlist-path (merge-pathnames playlist-name (get-playlists-directory))))
|
(let ((playlist-path (merge-pathnames playlist-name (get-playlists-directory))))
|
||||||
(if (probe-file playlist-path)
|
(if (probe-file playlist-path)
|
||||||
(progn
|
(progn
|
||||||
(format t "~&[SCHEDULER] Loading playlist: ~a~%" playlist-name)
|
|
||||||
(copy-playlist-to-stream-queue playlist-path)
|
(copy-playlist-to-stream-queue playlist-path)
|
||||||
(load-queue-from-m3u-file)
|
(load-queue-from-m3u-file)
|
||||||
(multiple-value-bind (skip-ok reload-ok)
|
(multiple-value-bind (skip-ok reload-ok)
|
||||||
(liquidsoap-reload-and-skip)
|
(liquidsoap-reload-and-skip)
|
||||||
(cond
|
(if (and reload-ok skip-ok)
|
||||||
((and reload-ok skip-ok)
|
(log:info "Scheduler loaded ~a" playlist-name)
|
||||||
(format t "~&[SCHEDULER] Playlist ~a loaded and crossfade triggered successfully~%" playlist-name))
|
(log:error "Scheduler failed to switch to ~a (reload:~a skip:~a)"
|
||||||
(skip-ok
|
playlist-name reload-ok skip-ok)))
|
||||||
(format t "~&[SCHEDULER] WARNING: Reload failed but skip succeeded for ~a~%" playlist-name))
|
|
||||||
(reload-ok
|
|
||||||
(format t "~&[SCHEDULER] WARNING: Reload OK but skip failed for ~a - track may not change immediately~%" playlist-name))
|
|
||||||
(t
|
|
||||||
(format t "~&[SCHEDULER] ERROR: Both reload and skip failed for ~a - Liquidsoap may be unresponsive~%" playlist-name))))
|
|
||||||
t)
|
t)
|
||||||
(progn
|
(progn
|
||||||
(format t "~&[SCHEDULER] Error: Playlist not found: ~a~%" playlist-name)
|
(log:error "Scheduler playlist not found: ~a" playlist-name)
|
||||||
nil))))
|
nil))))
|
||||||
|
|
||||||
(defun scheduled-playlist-loader (hour playlist-name)
|
(defun scheduled-playlist-loader (hour playlist-name)
|
||||||
"Create a function that loads a specific playlist. Used by cl-cron jobs."
|
"Create a function that loads a specific playlist. Used by cl-cron jobs."
|
||||||
(lambda ()
|
(lambda ()
|
||||||
(when *scheduler-enabled*
|
(when *scheduler-enabled*
|
||||||
(format t "~&[SCHEDULER] Triggered at hour ~a UTC - loading ~a~%" hour playlist-name)
|
|
||||||
(load-scheduled-playlist playlist-name))))
|
(load-scheduled-playlist playlist-name))))
|
||||||
|
|
||||||
;;; Cron Job Management
|
;;; Cron Job Management
|
||||||
|
|
@ -107,30 +96,25 @@
|
||||||
(defun setup-playlist-cron-jobs ()
|
(defun setup-playlist-cron-jobs ()
|
||||||
"Set up cl-cron jobs for all scheduled playlists."
|
"Set up cl-cron jobs for all scheduled playlists."
|
||||||
(unless *scheduler-running*
|
(unless *scheduler-running*
|
||||||
(format t "~&[SCHEDULER] Setting up playlist schedule:~%")
|
|
||||||
(dolist (entry *playlist-schedule*)
|
(dolist (entry *playlist-schedule*)
|
||||||
(let ((hour (car entry))
|
(let ((hour (car entry))
|
||||||
(playlist (cdr entry)))
|
(playlist (cdr entry)))
|
||||||
(format t "~&[SCHEDULER] ~2,'0d:00 UTC -> ~a~%" hour playlist)
|
|
||||||
(cl-cron:make-cron-job
|
(cl-cron:make-cron-job
|
||||||
(scheduled-playlist-loader hour playlist)
|
(scheduled-playlist-loader hour playlist)
|
||||||
:minute 0
|
:minute 0
|
||||||
:hour hour)))
|
:hour hour)))
|
||||||
(setf *scheduler-running* t)
|
(setf *scheduler-running* t)))
|
||||||
(format t "~&[SCHEDULER] Playlist schedule configured~%")))
|
|
||||||
|
|
||||||
(defun start-playlist-scheduler ()
|
(defun start-playlist-scheduler ()
|
||||||
"Start the playlist scheduler. Sets up cron jobs and starts cl-cron."
|
"Start the playlist scheduler. Sets up cron jobs and starts cl-cron."
|
||||||
(setup-playlist-cron-jobs)
|
(setup-playlist-cron-jobs)
|
||||||
(cl-cron:start-cron)
|
(cl-cron:start-cron)
|
||||||
(format t "~&[SCHEDULER] Playlist scheduler started~%")
|
|
||||||
t)
|
t)
|
||||||
|
|
||||||
(defun stop-playlist-scheduler ()
|
(defun stop-playlist-scheduler ()
|
||||||
"Stop the playlist scheduler."
|
"Stop the playlist scheduler."
|
||||||
(cl-cron:stop-cron)
|
(cl-cron:stop-cron)
|
||||||
(setf *scheduler-running* nil)
|
(setf *scheduler-running* nil)
|
||||||
(format t "~&[SCHEDULER] Playlist scheduler stopped~%")
|
|
||||||
t)
|
t)
|
||||||
|
|
||||||
(defun restart-playlist-scheduler ()
|
(defun restart-playlist-scheduler ()
|
||||||
|
|
@ -150,10 +134,9 @@
|
||||||
(mapcar (lambda (row)
|
(mapcar (lambda (row)
|
||||||
(cons (first row) (second row)))
|
(cons (first row) (second row)))
|
||||||
rows))
|
rows))
|
||||||
(format t "~&[SCHEDULER] Loaded ~a schedule entries from database~%" (length rows)))))
|
(log:info "Scheduler loaded ~a entries from database" (length rows)))))
|
||||||
(error (e)
|
(error (e)
|
||||||
(format t "~&[SCHEDULER] Warning: Could not load schedule from DB: ~a~%" e)
|
(log:warn "Scheduler DB load failed, using defaults: ~a" e))))
|
||||||
(format t "~&[SCHEDULER] Using default schedule~%"))))
|
|
||||||
|
|
||||||
(defun save-schedule-entry-to-db (hour playlist-name)
|
(defun save-schedule-entry-to-db (hour playlist-name)
|
||||||
"Save or update a schedule entry in the database."
|
"Save or update a schedule entry in the database."
|
||||||
|
|
@ -172,7 +155,7 @@
|
||||||
(format nil "INSERT INTO playlist_schedule (hour, playlist, updated_at) VALUES (~a, '~a', NOW()) ON CONFLICT (hour) DO UPDATE SET playlist = '~a', updated_at = NOW()"
|
(format nil "INSERT INTO playlist_schedule (hour, playlist, updated_at) VALUES (~a, '~a', NOW()) ON CONFLICT (hour) DO UPDATE SET playlist = '~a', updated_at = NOW()"
|
||||||
hour playlist-name playlist-name)))
|
hour playlist-name playlist-name)))
|
||||||
(error (e2)
|
(error (e2)
|
||||||
(format t "~&[SCHEDULER] Warning: Could not save schedule entry: ~a~%" e2))))))
|
(log:warn "Scheduler could not save schedule entry: ~a" e2))))))
|
||||||
|
|
||||||
(defun delete-schedule-entry-from-db (hour)
|
(defun delete-schedule-entry-from-db (hour)
|
||||||
"Delete a schedule entry from the database."
|
"Delete a schedule entry from the database."
|
||||||
|
|
@ -180,7 +163,7 @@
|
||||||
(with-db
|
(with-db
|
||||||
(postmodern:query (:delete-from 'playlist_schedule :where (:= 'hour hour))))
|
(postmodern:query (:delete-from 'playlist_schedule :where (:= 'hour hour))))
|
||||||
(error (e)
|
(error (e)
|
||||||
(format t "~&[SCHEDULER] Warning: Could not delete schedule entry: ~a~%" e))))
|
(log:warn "Scheduler could not delete schedule entry: ~a" e))))
|
||||||
|
|
||||||
(defun add-scheduled-playlist (hour playlist-name)
|
(defun add-scheduled-playlist (hour playlist-name)
|
||||||
"Add or update a playlist in the schedule (persists to database)."
|
"Add or update a playlist in the schedule (persists to database)."
|
||||||
|
|
@ -352,17 +335,13 @@
|
||||||
|
|
||||||
(define-trigger db:connected ()
|
(define-trigger db:connected ()
|
||||||
"Start the playlist scheduler after database connection is established"
|
"Start the playlist scheduler after database connection is established"
|
||||||
(format t "~&[SCHEDULER] Database connected, starting playlist scheduler...~%")
|
|
||||||
(handler-case
|
(handler-case
|
||||||
(progn
|
(progn
|
||||||
;; Load schedule from database first
|
|
||||||
(load-schedule-from-db)
|
(load-schedule-from-db)
|
||||||
(start-playlist-scheduler)
|
(start-playlist-scheduler)
|
||||||
;; Load the current scheduled playlist on startup
|
|
||||||
(let ((current-playlist (get-current-scheduled-playlist)))
|
(let ((current-playlist (get-current-scheduled-playlist)))
|
||||||
(when current-playlist
|
(when current-playlist
|
||||||
(format t "~&[SCHEDULER] Loading current scheduled playlist: ~a~%" current-playlist)
|
|
||||||
(load-scheduled-playlist current-playlist)))
|
(load-scheduled-playlist current-playlist)))
|
||||||
(format t "~&[SCHEDULER] Scheduler auto-started successfully~%"))
|
(log:info "Playlist scheduler started"))
|
||||||
(error (e)
|
(error (e)
|
||||||
(format t "~&[SCHEDULER] Warning: Could not auto-start scheduler: ~a~%" e))))
|
(log:error "Scheduler failed to start: ~a" e))))
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue