Class: Fractor::Workflow::WorkflowExecutionLogger

Inherits:
Object
  • Object
show all
Defined in:
lib/fractor/workflow/execution/workflow_execution_logger.rb

Overview

Handles all logging operations for workflow execution. Provides a clean separation of logging concerns from execution logic. NOTE: This is different from the WorkflowLogger in logger.rb which is a structured logging wrapper. This class extracts logging logic from the executor.

Instance Method Summary collapse

Constructor Details

#initialize(context_logger) ⇒ WorkflowExecutionLogger

Initialize the logger with a context logger.

Parameters:

  • context_logger (Logger, nil)

    The logger from the workflow context



13
14
15
# File 'lib/fractor/workflow/execution/workflow_execution_logger.rb', line 13

def initialize(context_logger)
  @logger = context_logger
end

Instance Method Details

#added_to_dead_letter_queue(job_name, error, dlq_size) ⇒ Object

Log work added to dead letter queue.

Parameters:

  • job_name (String)

    Name of the job

  • error (Exception)

    The error that occurred

  • dlq_size (Integer)

    Current size of the dead letter queue



228
229
230
231
232
233
234
235
236
237
238
# File 'lib/fractor/workflow/execution/workflow_execution_logger.rb', line 228

def added_to_dead_letter_queue(job_name, error, dlq_size)
  return unless @logger

  @logger.warn(
    "Work added to Dead Letter Queue",
    job: job_name,
    error: error.class.name,
    message: error.message,
    dlq_size: dlq_size,
  )
end

#circuit_breaker_open(job_name, failure_count, threshold, last_failure: nil) ⇒ Object

Log circuit breaker open.

Parameters:

  • job_name (String)

    Name of the job

  • failure_count (Integer)

    Number of failures

  • threshold (Integer)

    Failure threshold

  • last_failure (Time, nil) (defaults to: nil)

    Time of last failure



210
211
212
213
214
215
216
217
218
219
220
221
# File 'lib/fractor/workflow/execution/workflow_execution_logger.rb', line 210

def circuit_breaker_open(job_name, failure_count, threshold,
last_failure: nil)
  return unless @logger

  @logger.error(
    "Circuit breaker open",
    job: job_name,
    failure_count: failure_count,
    threshold: threshold,
    last_failure: last_failure,
  )
end

#circuit_breaker_state(job_name, state, failure_count:, threshold:) ⇒ Object

Log circuit breaker state.

Parameters:

  • job_name (String)

    Name of the job

  • state (Symbol)

    Current circuit breaker state

  • failure_count (Integer)

    Number of failures

  • threshold (Integer)

    Failure threshold



191
192
193
194
195
196
197
198
199
200
201
202
# File 'lib/fractor/workflow/execution/workflow_execution_logger.rb', line 191

def circuit_breaker_state(job_name, state, failure_count:, threshold:)
  return unless @logger
  return if state == :closed

  @logger.warn(
    "Circuit breaker state",
    job: job_name,
    state: state,
    failure_count: failure_count,
    threshold: threshold,
  )
end

#fallback_execution(job_name, fallback_job_name, original_error) ⇒ Object

Log fallback job execution.

Parameters:

  • job_name (String)

    Name of the original job

  • fallback_job_name (String)

    Name of the fallback job

  • original_error (Exception)

    The error that triggered fallback



158
159
160
161
162
163
164
165
166
167
# File 'lib/fractor/workflow/execution/workflow_execution_logger.rb', line 158

def fallback_execution(job_name, fallback_job_name, original_error)
  return unless @logger

  @logger.warn(
    "Executing fallback job",
    job: job_name,
    fallback_job: fallback_job_name,
    original_error: original_error.message,
  )
end

#fallback_failed(job_name, fallback_job_name, error) ⇒ Object

Log fallback job failure.

Parameters:

  • job_name (String)

    Name of the original job

  • fallback_job_name (String)

    Name of the fallback job

  • error (Exception)

    The error that occurred in fallback



174
175
176
177
178
179
180
181
182
183
# File 'lib/fractor/workflow/execution/workflow_execution_logger.rb', line 174

def fallback_failed(job_name, fallback_job_name, error)
  return unless @logger

  @logger.error(
    "Fallback job failed",
    job: job_name,
    fallback_job: fallback_job_name,
    error: error.message,
  )
end

#job_complete(job_name, duration) ⇒ Object

Log job completion.

Parameters:

  • job_name (String)

    Name of the job

  • duration (Float)

    Execution duration in seconds



68
69
70
71
72
73
74
75
76
# File 'lib/fractor/workflow/execution/workflow_execution_logger.rb', line 68

def job_complete(job_name, duration)
  return unless @logger

  @logger.info(
    "Job complete",
    job: job_name,
    duration_ms: (duration * 1000).round(2),
  )
end

#job_error(job_name, error, has_fallback: false) ⇒ Object

Log job error.

Parameters:

  • job_name (String)

    Name of the job

  • error (Exception)

    The error that occurred

  • has_fallback (Boolean) (defaults to: false)

    Whether a fallback job is available



83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/fractor/workflow/execution/workflow_execution_logger.rb', line 83

def job_error(job_name, error, has_fallback: false)
  return unless @logger

  # Log at WARN level if fallback is available (error is handled),
  # otherwise log at ERROR level (error causes workflow failure)
  log_method = has_fallback ? @logger.method(:warn) : @logger.method(:error)

  log_method.call(
    "Job '#{job_name}' encountered error: #{error}",
    job: job_name,
    error: error.class.name,
  )
end

#job_start(job_name, worker_class) ⇒ Object

Log job start.

Parameters:

  • job_name (String)

    Name of the job

  • worker_class (String)

    Class name of the worker



54
55
56
57
58
59
60
61
62
# File 'lib/fractor/workflow/execution/workflow_execution_logger.rb', line 54

def job_start(job_name, worker_class)
  return unless @logger

  @logger.info(
    "Job starting",
    job: job_name,
    worker: worker_class,
  )
end

#retry_attempt(job_name, attempt, max_attempts, delay, last_error: nil) ⇒ Object

Log retry attempt.

Parameters:

  • job_name (String)

    Name of the job

  • attempt (Integer)

    Current attempt number

  • max_attempts (Integer)

    Maximum number of attempts

  • delay (Float)

    Delay before this retry in seconds

  • last_error (Exception, nil) (defaults to: nil)

    Last error that occurred



104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/fractor/workflow/execution/workflow_execution_logger.rb', line 104

def retry_attempt(job_name, attempt, max_attempts, delay, last_error: nil)
  return unless @logger

  @logger.warn(
    "Job retry attempt",
    job: job_name,
    attempt: attempt,
    max_attempts: max_attempts,
    delay_seconds: delay,
    last_error: last_error&.message,
  )
end

#retry_exhausted(job_name, attempts, total_time, errors) ⇒ Object

Log retry exhausted.

Parameters:

  • job_name (String)

    Name of the job

  • attempts (Integer)

    Total number of attempts made

  • total_time (Float)

    Total time spent retrying in seconds

  • errors (Array<Exception>)

    All errors that occurred



141
142
143
144
145
146
147
148
149
150
151
# File 'lib/fractor/workflow/execution/workflow_execution_logger.rb', line 141

def retry_exhausted(job_name, attempts, total_time, errors)
  return unless @logger

  @logger.error(
    "Job retry attempts exhausted",
    job: job_name,
    total_attempts: attempts,
    total_time: total_time,
    errors: errors,
  )
end

#retry_success(job_name, attempt, total_attempts, total_time) ⇒ Object

Log retry success.

Parameters:

  • job_name (String)

    Name of the job

  • attempt (Integer)

    Successful attempt number

  • total_attempts (Integer)

    Total number of attempts made

  • total_time (Float)

    Total time spent retrying in seconds



123
124
125
126
127
128
129
130
131
132
133
# File 'lib/fractor/workflow/execution/workflow_execution_logger.rb', line 123

def retry_success(job_name, attempt, total_attempts, total_time)
  return unless @logger

  @logger.info(
    "Job retry succeeded",
    job: job_name,
    successful_attempt: attempt,
    total_attempts: total_attempts,
    total_time: total_time,
  )
end

#workflow_complete(workflow_name, duration, jobs_completed:, jobs_failed:) ⇒ Object

Log workflow completion.

Parameters:

  • workflow_name (String)

    Name of the workflow

  • duration (Float)

    Execution duration in seconds

  • jobs_completed (Integer)

    Number of jobs completed

  • jobs_failed (Integer)

    Number of jobs failed



37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/fractor/workflow/execution/workflow_execution_logger.rb', line 37

def workflow_complete(workflow_name, duration, jobs_completed:,
jobs_failed:)
  return unless @logger

  @logger.info(
    "Workflow complete",
    workflow: workflow_name,
    duration_ms: (duration * 1000).round(2),
    jobs_completed: jobs_completed,
    jobs_failed: jobs_failed,
  )
end

#workflow_start(workflow_name, correlation_id) ⇒ Object

Log workflow start.

Parameters:

  • workflow_name (String)

    Name of the workflow

  • correlation_id (String, nil)

    Correlation ID for tracking



21
22
23
24
25
26
27
28
29
# File 'lib/fractor/workflow/execution/workflow_execution_logger.rb', line 21

def workflow_start(workflow_name, correlation_id)
  return unless @logger

  @logger.info(
    "Workflow starting",
    workflow: workflow_name,
    correlation_id: correlation_id,
  )
end