Skip to content

Schedule Observability ​

Structured Log Events ​

All log events are emitted via IAppLoggerService as structured JSON.

Event keyLevelWhenKey fields
schedule.enqueuedINFOJob accepted and enqueuedscheduledJobId, topic, kind, runAt/pattern, correlationId, clientRequestId
schedule.firedINFOWorker callback enteredscheduledJobId, topic, attempt, maxAttempts, drift_seconds
schedule.completedINFOJob finishes successfullyscheduledJobId, topic
schedule.cancelledINFOcancel() completesscheduledJobId, topic, cancelledAt
schedule.no_listenerWARNFired but no listener registered for the topicscheduledJobId, topic, attempt
schedule.retryWARNWorker threw; BullMQ will retryscheduledJobId, topic, attempt, maxAttempts, error
schedule.failed.terminalERRORmaxAttempts exhaustedscheduledJobId, topic, attempts, lastError
schedule.rescheduledINFOreschedule() completesoldJobId, newJobId, topic
schedule.reconciler.summaryINFOBoot reconciler finishesscanned, healed, skipped

Metrics ​

All metrics use the app_ prefix following the project convention (via getAppMeter(appConfigService)).

Metric nameTypeLabelsDescription
app_schedule_job_enqueued_totalCountertopic, kindJobs successfully enqueued
app_schedule_job_fired_totalCountertopicWorker callback entered
app_schedule_job_failed_totalCountertopic, terminalWorker failures; terminal=true after last attempt
app_schedule_job_no_listener_totalCountertopicFirings with no registered listener
app_schedule_job_drift_secondsHistogramtopic, kindSeconds between originalScheduledAt and firedAt
app_schedule_job_listener_duration_secondsHistogramtopicWall-clock time of emitAsync (all listeners)

Tracing Spans ​

Spans are created via TracingService.runInSpan. W3C traceparent is stored in the BullMQ job data so that the worker span can be linked to the original enqueue span.

Span nameKindWhere
schedule.enqueue.one_shotPRODUCERScheduleAtUseCase.execute
schedule.enqueue.repeatPRODUCERScheduleRepeatUseCase.execute
schedule.cancelPRODUCERCancelScheduleUseCase.execute
schedule.reschedulePRODUCERRescheduleUseCase.execute
schedule.processCONSUMERScheduleProcessor.process (root)
schedule.listener.emitINTERNALInside process, wrapping emitArrived
schedule.reconciler.bootstrapINTERNALScheduleReconcilerService.onApplicationBootstrap

Standard attributes on enqueue spans: messaging.system="bullmq", messaging.destination="schedule", messaging.message.name=<topic>, schedule.kind, schedule.timezone, app.correlation_id.