Class: LogStruct::Integrations::GoodJob::LogSubscriber

Inherits:
ActiveSupport::LogSubscriber
  • Object
show all
Extended by:
T::Sig
Defined in:
lib/log_struct/integrations/good_job/log_subscriber.rb

Overview

LogSubscriber for GoodJob ActiveSupport notifications

This subscriber captures GoodJob's ActiveSupport notifications and converts them into structured LogStruct::Log::GoodJob entries. It provides detailed logging for job lifecycle events, performance metrics, and error tracking.

Supported Events:

  • job.enqueue - Job queued for execution
  • job.start - Job execution started
  • job.finish - Job completed successfully
  • job.error - Job failed with error
  • job.retry - Job retry initiated
  • job.schedule - Job scheduled for future execution

Event Data Captured:

  • Job identification (ID, class, queue)
  • Execution context (arguments, priority, scheduled time)
  • Performance metrics (execution time, wait time)
  • Error information (class, message, backtrace)
  • Process and thread information

Instance Method Summary collapse

Instance Method Details

#enqueue(event) ⇒ void

This method returns an undefined value.

Job enqueued event

Parameters:

  • event (::ActiveSupport::Notifications::Event)


42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/log_struct/integrations/good_job/log_subscriber.rb', line 42

def enqueue(event)
  payload = T.let(event.payload, T::Hash[Symbol, T.untyped])
  job = payload[:job]
  base_fields = build_base_fields(job, payload)
  ts = event.time ? Time.at(event.time) : Time.now

  logger.info(Log::GoodJob::Enqueue.new(
    **base_fields.to_kwargs,
    scheduled_at: (job&.scheduled_at ? Time.at(job.scheduled_at.to_i) : nil),
    duration_ms: event.duration.to_f,
    enqueue_caller: job&.enqueue_caller_location,
    timestamp: ts
  ))
end

#error(event) ⇒ void

This method returns an undefined value.

Job failed with error event

Parameters:

  • event (::ActiveSupport::Notifications::Event)


101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/log_struct/integrations/good_job/log_subscriber.rb', line 101

def error(event)
  payload = T.let(event.payload, T::Hash[Symbol, T.untyped])
  job = payload[:job]
  execution = payload[:execution] || payload[:good_job_execution]
  exception = payload[:exception] || payload[:error]
  ts = event.time ? Time.at(event.time) : Time.now
  base_fields = build_base_fields(job, payload)

  logger.error(Log::GoodJob::Error.new(
    **base_fields.to_kwargs,
    exception_executions: execution&.exception_executions,
    error_class: exception&.class&.name,
    error_message: exception&.message,
    backtrace: exception&.backtrace,
    duration_ms: event.duration.to_f,
    process_id: ::Process.pid,
    thread_id: Thread.current.object_id.to_s(36),
    timestamp: ts
  ))
end

#finish(event) ⇒ void

This method returns an undefined value.

Job completed successfully event

Parameters:

  • event (::ActiveSupport::Notifications::Event)


81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/log_struct/integrations/good_job/log_subscriber.rb', line 81

def finish(event)
  payload = T.let(event.payload, T::Hash[Symbol, T.untyped])
  job = payload[:job]
  base_fields = build_base_fields(job, payload)
  start_ts = event.time ? Time.at(event.time) : Time.now
  end_ts = event.end ? Time.at(event.end) : Time.now

  logger.info(Log::GoodJob::Finish.new(
    **base_fields.to_kwargs,
    duration_ms: event.duration.to_f,
    finished_at: end_ts,
    process_id: ::Process.pid,
    thread_id: Thread.current.object_id.to_s(36),
    result: payload[:result]&.to_s,
    timestamp: start_ts
  ))
end

#schedule(event) ⇒ void

This method returns an undefined value.

Job scheduled for future execution event

Parameters:

  • event (::ActiveSupport::Notifications::Event)


124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# File 'lib/log_struct/integrations/good_job/log_subscriber.rb', line 124

def schedule(event)
  payload = T.let(event.payload, T::Hash[Symbol, T.untyped])
  job = payload[:job]
  base_fields = build_base_fields(job, payload)
  ts = event.time ? Time.at(event.time) : Time.now

  logger.info(Log::GoodJob::Schedule.new(
    **base_fields.to_kwargs,
    scheduled_at: (job&.scheduled_at ? Time.at(job.scheduled_at.to_i) : nil),
    priority: job&.priority,
    cron_key: job&.cron_key,
    duration_ms: event.duration.to_f,
    timestamp: ts
  ))
end

#start(event) ⇒ void

This method returns an undefined value.

Job execution started event

Parameters:

  • event (::ActiveSupport::Notifications::Event)


59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/log_struct/integrations/good_job/log_subscriber.rb', line 59

def start(event)
  payload = T.let(event.payload, T::Hash[Symbol, T.untyped])
  job = payload[:job]
  execution = payload[:execution] || payload[:good_job_execution]
  base_fields = build_base_fields(job, payload)
  ts = event.time ? Time.at(event.time) : Time.now

  logger.info(Log::GoodJob::Start.new(
    **base_fields.to_kwargs,
    wait_ms: begin
      wt = execution&.wait_time || calculate_wait_time(execution)
      wt ? (wt.to_f * 1000.0) : nil
    end,
    scheduled_at: (job&.scheduled_at ? Time.at(job.scheduled_at.to_i) : nil),
    process_id: ::Process.pid,
    thread_id: Thread.current.object_id.to_s(36),
    timestamp: ts
  ))
end