Appearance
Schedule Observability
Structured Log Events
All log events are emitted via IAppLoggerService as structured JSON.
| Event key | Level | When | Key fields |
|---|---|---|---|
schedule.enqueued | INFO | Job accepted and enqueued | scheduledJobId, topic, kind, runAt/pattern, correlationId, clientRequestId |
schedule.fired | INFO | Worker callback entered | scheduledJobId, topic, attempt, maxAttempts, drift_seconds |
schedule.completed | INFO | Job finishes successfully | scheduledJobId, topic |
schedule.cancelled | INFO | cancel() completes | scheduledJobId, topic, cancelledAt |
schedule.no_listener | WARN | Fired but no listener registered for the topic | scheduledJobId, topic, attempt |
schedule.retry | WARN | Worker threw; BullMQ will retry | scheduledJobId, topic, attempt, maxAttempts, error |
schedule.failed.terminal | ERROR | maxAttempts exhausted | scheduledJobId, topic, attempts, lastError |
schedule.rescheduled | INFO | reschedule() completes | oldJobId, newJobId, topic |
schedule.reconciler.summary | INFO | Boot reconciler finishes | scanned, healed, skipped |
Metrics
All metrics use the app_ prefix following the project convention (via getAppMeter(appConfigService)).
| Metric name | Type | Labels | Description |
|---|---|---|---|
app_schedule_job_enqueued_total | Counter | topic, kind | Jobs successfully enqueued |
app_schedule_job_fired_total | Counter | topic | Worker callback entered |
app_schedule_job_failed_total | Counter | topic, terminal | Worker failures; terminal=true after last attempt |
app_schedule_job_no_listener_total | Counter | topic | Firings with no registered listener |
app_schedule_job_drift_seconds | Histogram | topic, kind | Seconds between originalScheduledAt and firedAt |
app_schedule_job_listener_duration_seconds | Histogram | topic | Wall-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 name | Kind | Where |
|---|---|---|
schedule.enqueue.one_shot | PRODUCER | ScheduleAtUseCase.execute |
schedule.enqueue.repeat | PRODUCER | ScheduleRepeatUseCase.execute |
schedule.cancel | PRODUCER | CancelScheduleUseCase.execute |
schedule.reschedule | PRODUCER | RescheduleUseCase.execute |
schedule.process | CONSUMER | ScheduleProcessor.process (root) |
schedule.listener.emit | INTERNAL | Inside process, wrapping emitArrived |
schedule.reconciler.bootstrap | INTERNAL | ScheduleReconcilerService.onApplicationBootstrap |
Standard attributes on enqueue spans: messaging.system="bullmq", messaging.destination="schedule", messaging.message.name=<topic>, schedule.kind, schedule.timezone, app.correlation_id.