cmdx 1.1.1 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (193) hide show
  1. checksums.yaml +4 -4
  2. data/.DS_Store +0 -0
  3. data/.cursor/prompts/docs.md +4 -1
  4. data/.cursor/prompts/llms.md +20 -0
  5. data/.cursor/prompts/rspec.md +4 -1
  6. data/.cursor/prompts/yardoc.md +3 -2
  7. data/.cursor/rules/cursor-instructions.mdc +56 -1
  8. data/.irbrc +6 -0
  9. data/.rubocop.yml +29 -18
  10. data/.ruby-version +1 -1
  11. data/CHANGELOG.md +6 -128
  12. data/LLM.md +3317 -0
  13. data/README.md +68 -44
  14. data/docs/attributes/coercions.md +162 -0
  15. data/docs/attributes/defaults.md +90 -0
  16. data/docs/attributes/definitions.md +281 -0
  17. data/docs/attributes/naming.md +78 -0
  18. data/docs/attributes/validations.md +309 -0
  19. data/docs/basics/chain.md +56 -249
  20. data/docs/basics/context.md +56 -289
  21. data/docs/basics/execution.md +114 -0
  22. data/docs/basics/setup.md +37 -334
  23. data/docs/callbacks.md +89 -467
  24. data/docs/deprecation.md +91 -174
  25. data/docs/getting_started.md +212 -202
  26. data/docs/internationalization.md +11 -647
  27. data/docs/interruptions/exceptions.md +23 -198
  28. data/docs/interruptions/faults.md +71 -151
  29. data/docs/interruptions/halt.md +109 -186
  30. data/docs/logging.md +44 -256
  31. data/docs/middlewares.md +113 -426
  32. data/docs/outcomes/result.md +81 -228
  33. data/docs/outcomes/states.md +33 -221
  34. data/docs/outcomes/statuses.md +21 -311
  35. data/docs/tips_and_tricks.md +120 -70
  36. data/docs/workflows.md +99 -283
  37. data/lib/cmdx/.DS_Store +0 -0
  38. data/lib/cmdx/attribute.rb +229 -0
  39. data/lib/cmdx/attribute_registry.rb +94 -0
  40. data/lib/cmdx/attribute_value.rb +193 -0
  41. data/lib/cmdx/callback_registry.rb +69 -77
  42. data/lib/cmdx/chain.rb +56 -73
  43. data/lib/cmdx/coercion_registry.rb +52 -68
  44. data/lib/cmdx/coercions/array.rb +19 -18
  45. data/lib/cmdx/coercions/big_decimal.rb +20 -24
  46. data/lib/cmdx/coercions/boolean.rb +26 -25
  47. data/lib/cmdx/coercions/complex.rb +21 -22
  48. data/lib/cmdx/coercions/date.rb +25 -23
  49. data/lib/cmdx/coercions/date_time.rb +24 -25
  50. data/lib/cmdx/coercions/float.rb +25 -22
  51. data/lib/cmdx/coercions/hash.rb +31 -32
  52. data/lib/cmdx/coercions/integer.rb +30 -24
  53. data/lib/cmdx/coercions/rational.rb +29 -24
  54. data/lib/cmdx/coercions/string.rb +19 -22
  55. data/lib/cmdx/coercions/symbol.rb +37 -0
  56. data/lib/cmdx/coercions/time.rb +26 -25
  57. data/lib/cmdx/configuration.rb +49 -108
  58. data/lib/cmdx/context.rb +222 -44
  59. data/lib/cmdx/deprecator.rb +61 -0
  60. data/lib/cmdx/errors.rb +42 -252
  61. data/lib/cmdx/exceptions.rb +39 -0
  62. data/lib/cmdx/faults.rb +78 -39
  63. data/lib/cmdx/freezer.rb +51 -0
  64. data/lib/cmdx/identifier.rb +30 -0
  65. data/lib/cmdx/locale.rb +52 -0
  66. data/lib/cmdx/log_formatters/json.rb +21 -22
  67. data/lib/cmdx/log_formatters/key_value.rb +20 -22
  68. data/lib/cmdx/log_formatters/line.rb +15 -22
  69. data/lib/cmdx/log_formatters/logstash.rb +22 -23
  70. data/lib/cmdx/log_formatters/raw.rb +16 -22
  71. data/lib/cmdx/middleware_registry.rb +70 -74
  72. data/lib/cmdx/middlewares/correlate.rb +90 -54
  73. data/lib/cmdx/middlewares/runtime.rb +58 -0
  74. data/lib/cmdx/middlewares/timeout.rb +48 -68
  75. data/lib/cmdx/railtie.rb +12 -45
  76. data/lib/cmdx/result.rb +229 -314
  77. data/lib/cmdx/task.rb +194 -366
  78. data/lib/cmdx/utils/call.rb +49 -0
  79. data/lib/cmdx/utils/condition.rb +71 -0
  80. data/lib/cmdx/utils/format.rb +61 -0
  81. data/lib/cmdx/validator_registry.rb +63 -72
  82. data/lib/cmdx/validators/exclusion.rb +38 -67
  83. data/lib/cmdx/validators/format.rb +48 -49
  84. data/lib/cmdx/validators/inclusion.rb +43 -74
  85. data/lib/cmdx/validators/length.rb +91 -154
  86. data/lib/cmdx/validators/numeric.rb +87 -162
  87. data/lib/cmdx/validators/presence.rb +37 -50
  88. data/lib/cmdx/version.rb +1 -1
  89. data/lib/cmdx/worker.rb +178 -0
  90. data/lib/cmdx/workflow.rb +85 -81
  91. data/lib/cmdx.rb +19 -13
  92. data/lib/generators/cmdx/install_generator.rb +14 -13
  93. data/lib/generators/cmdx/task_generator.rb +25 -50
  94. data/lib/generators/cmdx/templates/install.rb +11 -46
  95. data/lib/generators/cmdx/templates/task.rb.tt +3 -2
  96. data/lib/locales/en.yml +18 -4
  97. data/src/cmdx-logo.png +0 -0
  98. metadata +32 -116
  99. data/docs/ai_prompts.md +0 -393
  100. data/docs/basics/call.md +0 -317
  101. data/docs/configuration.md +0 -344
  102. data/docs/parameters/coercions.md +0 -396
  103. data/docs/parameters/defaults.md +0 -335
  104. data/docs/parameters/definitions.md +0 -446
  105. data/docs/parameters/namespacing.md +0 -378
  106. data/docs/parameters/validations.md +0 -405
  107. data/docs/testing.md +0 -553
  108. data/lib/cmdx/callback.rb +0 -53
  109. data/lib/cmdx/chain_inspector.rb +0 -56
  110. data/lib/cmdx/chain_serializer.rb +0 -63
  111. data/lib/cmdx/coercion.rb +0 -57
  112. data/lib/cmdx/coercions/virtual.rb +0 -29
  113. data/lib/cmdx/core_ext/hash.rb +0 -83
  114. data/lib/cmdx/core_ext/module.rb +0 -98
  115. data/lib/cmdx/core_ext/object.rb +0 -125
  116. data/lib/cmdx/correlator.rb +0 -122
  117. data/lib/cmdx/error.rb +0 -60
  118. data/lib/cmdx/fault.rb +0 -140
  119. data/lib/cmdx/immutator.rb +0 -52
  120. data/lib/cmdx/lazy_struct.rb +0 -246
  121. data/lib/cmdx/log_formatters/pretty_json.rb +0 -40
  122. data/lib/cmdx/log_formatters/pretty_key_value.rb +0 -38
  123. data/lib/cmdx/log_formatters/pretty_line.rb +0 -41
  124. data/lib/cmdx/logger.rb +0 -49
  125. data/lib/cmdx/logger_ansi.rb +0 -68
  126. data/lib/cmdx/logger_serializer.rb +0 -116
  127. data/lib/cmdx/middleware.rb +0 -70
  128. data/lib/cmdx/parameter.rb +0 -312
  129. data/lib/cmdx/parameter_evaluator.rb +0 -231
  130. data/lib/cmdx/parameter_inspector.rb +0 -66
  131. data/lib/cmdx/parameter_registry.rb +0 -106
  132. data/lib/cmdx/parameter_serializer.rb +0 -59
  133. data/lib/cmdx/result_ansi.rb +0 -71
  134. data/lib/cmdx/result_inspector.rb +0 -71
  135. data/lib/cmdx/result_logger.rb +0 -59
  136. data/lib/cmdx/result_serializer.rb +0 -104
  137. data/lib/cmdx/rspec/matchers.rb +0 -28
  138. data/lib/cmdx/rspec/result_matchers/be_executed.rb +0 -42
  139. data/lib/cmdx/rspec/result_matchers/be_failed_task.rb +0 -94
  140. data/lib/cmdx/rspec/result_matchers/be_skipped_task.rb +0 -94
  141. data/lib/cmdx/rspec/result_matchers/be_state_matchers.rb +0 -59
  142. data/lib/cmdx/rspec/result_matchers/be_status_matchers.rb +0 -57
  143. data/lib/cmdx/rspec/result_matchers/be_successful_task.rb +0 -87
  144. data/lib/cmdx/rspec/result_matchers/have_bad_outcome.rb +0 -51
  145. data/lib/cmdx/rspec/result_matchers/have_caused_failure.rb +0 -58
  146. data/lib/cmdx/rspec/result_matchers/have_chain_index.rb +0 -59
  147. data/lib/cmdx/rspec/result_matchers/have_context.rb +0 -86
  148. data/lib/cmdx/rspec/result_matchers/have_empty_metadata.rb +0 -54
  149. data/lib/cmdx/rspec/result_matchers/have_good_outcome.rb +0 -52
  150. data/lib/cmdx/rspec/result_matchers/have_metadata.rb +0 -114
  151. data/lib/cmdx/rspec/result_matchers/have_preserved_context.rb +0 -66
  152. data/lib/cmdx/rspec/result_matchers/have_received_thrown_failure.rb +0 -64
  153. data/lib/cmdx/rspec/result_matchers/have_runtime.rb +0 -78
  154. data/lib/cmdx/rspec/result_matchers/have_thrown_failure.rb +0 -76
  155. data/lib/cmdx/rspec/task_matchers/be_well_formed_task.rb +0 -62
  156. data/lib/cmdx/rspec/task_matchers/have_callback.rb +0 -85
  157. data/lib/cmdx/rspec/task_matchers/have_cmd_setting.rb +0 -68
  158. data/lib/cmdx/rspec/task_matchers/have_executed_callbacks.rb +0 -92
  159. data/lib/cmdx/rspec/task_matchers/have_middleware.rb +0 -46
  160. data/lib/cmdx/rspec/task_matchers/have_parameter.rb +0 -181
  161. data/lib/cmdx/task_deprecator.rb +0 -52
  162. data/lib/cmdx/task_processor.rb +0 -246
  163. data/lib/cmdx/task_serializer.rb +0 -57
  164. data/lib/cmdx/utils/ansi_color.rb +0 -73
  165. data/lib/cmdx/utils/log_timestamp.rb +0 -36
  166. data/lib/cmdx/utils/monotonic_runtime.rb +0 -34
  167. data/lib/cmdx/utils/name_affix.rb +0 -52
  168. data/lib/cmdx/validator.rb +0 -57
  169. data/lib/generators/cmdx/templates/workflow.rb.tt +0 -7
  170. data/lib/generators/cmdx/workflow_generator.rb +0 -84
  171. data/lib/locales/ar.yml +0 -35
  172. data/lib/locales/cs.yml +0 -35
  173. data/lib/locales/da.yml +0 -35
  174. data/lib/locales/de.yml +0 -35
  175. data/lib/locales/el.yml +0 -35
  176. data/lib/locales/es.yml +0 -35
  177. data/lib/locales/fi.yml +0 -35
  178. data/lib/locales/fr.yml +0 -35
  179. data/lib/locales/he.yml +0 -35
  180. data/lib/locales/hi.yml +0 -35
  181. data/lib/locales/it.yml +0 -35
  182. data/lib/locales/ja.yml +0 -35
  183. data/lib/locales/ko.yml +0 -35
  184. data/lib/locales/nl.yml +0 -35
  185. data/lib/locales/no.yml +0 -35
  186. data/lib/locales/pl.yml +0 -35
  187. data/lib/locales/pt.yml +0 -35
  188. data/lib/locales/ru.yml +0 -35
  189. data/lib/locales/sv.yml +0 -35
  190. data/lib/locales/th.yml +0 -35
  191. data/lib/locales/tr.yml +0 -35
  192. data/lib/locales/vi.yml +0 -35
  193. data/lib/locales/zh.yml +0 -35
data/docs/logging.md CHANGED
@@ -3,51 +3,14 @@
3
3
  CMDx provides comprehensive automatic logging for task execution with structured data, customizable formatters, and intelligent severity mapping. All task results are logged after completion with rich metadata for debugging and monitoring.
4
4
 
5
5
  ## Table of Contents
6
- - [TLDR](#tldr)
7
- - [Log Formatters](#log-formatters)
8
- - [Standard Formatters](#standard-formatters)
9
- - [Stylized Formatters](#stylized-formatters)
10
- - [Sample Output](#sample-output)
11
- - [Configuration](#configuration)
12
- - [Global Configuration](#global-configuration)
13
- - [Task-Specific Configuration](#task-specific-configuration)
14
- - [Severity Mapping](#severity-mapping)
15
- - [Manual Logging](#manual-logging)
16
- - [Error Handling](#error-handling)
17
- - [Advanced Usage](#advanced-usage)
18
- - [Custom Formatters](#custom-formatters)
19
- - [Multi-Destination Logging](#multi-destination-logging)
20
- - [Log Data Structure](#log-data-structure)
21
6
 
22
- ## TLDR
7
+ - [Formatters](#formatters)
8
+ - [Structure](#structure)
9
+ - [Usage](#usage)
23
10
 
24
- ```ruby
25
- # Automatic logging - no setup required
26
- class ProcessOrderTask < CMDx::Task
27
- def call
28
- # Task execution automatically logged with metadata
29
- end
30
- end
31
-
32
- # Custom formatter
33
- cmd_settings!(log_formatter: CMDx::LogFormatters::Json.new)
34
-
35
- # Manual logging within tasks
36
- logger.info "Processing order", order_id: context.order_id
37
-
38
- # Global configuration
39
- CMDx.configure do |config|
40
- config.logger = Logger.new("log/cmdx.log")
41
- config.log_formatter = CMDx::LogFormatters::Json.new
42
- end
43
- ```
44
-
45
- ## Log Formatters
11
+ ## Formatters
46
12
 
47
- > [!NOTE]
48
- > All formatters automatically include execution metadata. Choose based on your environment: stylized for development, standard for production.
49
-
50
- ### Standard Formatters
13
+ CMDx supports multiple log formatters to integrate with various logging systems:
51
14
 
52
15
  | Formatter | Use Case | Output Style |
53
16
  |-----------|----------|--------------|
@@ -57,223 +20,34 @@ end
57
20
  | `Logstash` | ELK stack | JSON with @version/@timestamp |
58
21
  | `Raw` | Minimal output | Message content only |
59
22
 
60
- ### Stylized Formatters
61
-
62
- > [!TIP]
63
- > Stylized formatters include ANSI color codes for better terminal readability in development environments.
64
-
65
- | Formatter | Description |
66
- |-----------|-------------|
67
- | `PrettyLine` | Colorized line format (default) |
68
- | `PrettyJson` | Multi-line JSON with syntax highlighting |
69
- | `PrettyKeyValue` | Colorized key=value pairs |
70
-
71
- ## Sample Output
72
-
73
- ```ruby
74
- # Success (INFO level)
75
- I, [2022-07-17T18:43:15.000000 #3784] INFO -- CreateOrderTask:
76
- index=0 chain_id=018c2b95-b764-7615-a924-cc5b910ed1e5 type=Task
77
- class=CreateOrderTask status=success metadata={order_id: 123} runtime=0.45
78
-
79
- # Skipped (WARN level)
80
- W, [2022-07-17T18:43:15.000000 #3784] WARN -- ValidatePaymentTask:
81
- index=1 status=skipped metadata={reason: "Order already processed"} runtime=0.02
82
-
83
- # Failed (ERROR level)
84
- E, [2022-07-17T18:43:15.000000 #3784] ERROR -- ProcessPaymentTask:
85
- index=2 status=failed metadata={error_code: "INSUFFICIENT_FUNDS"} runtime=0.15
86
-
87
- # Workflow failure chain
88
- E, [2022-07-17T18:43:15.000000 #3784] ERROR -- OrderWorkflow:
89
- caused_failure={index: 2, class: "ProcessPaymentTask", status: "failed"}
90
- threw_failure={index: 1, class: "ValidatePaymentTask", status: "failed"}
91
- ```
92
-
93
- ## Configuration
94
-
95
- ### Global Configuration
96
-
97
- ```ruby
98
- CMDx.configure do |config|
99
- config.logger = Logger.new("log/cmdx.log")
100
- config.log_formatter = CMDx::LogFormatters::Json.new
101
- config.log_level = Logger::INFO
102
- end
103
- ```
104
-
105
- ### Task-Specific Configuration
106
-
107
- ```ruby
108
- class SendEmailTask < CMDx::Task
109
- cmd_settings!(
110
- logger: Rails.logger,
111
- log_formatter: CMDx::LogFormatters::Logstash.new,
112
- log_level: Logger::WARN
113
- )
114
-
115
- def call
116
- # Task implementation
117
- end
118
- end
119
-
120
- # Base class configuration
121
- class ApplicationTask < CMDx::Task
122
- cmd_settings!(
123
- logger: Logger.new("log/tasks.log"),
124
- log_formatter: CMDx::LogFormatters::Json.new
125
- )
126
- end
127
- ```
128
-
129
- ## Severity Mapping
23
+ Sample output:
130
24
 
131
- > [!IMPORTANT]
132
- > CMDx automatically maps result statuses to log severity levels. Manual overrides are not recommended as they break monitoring conventions.
25
+ ```log
26
+ <!-- Success (INFO level) -->
27
+ I, [2022-07-17T18:43:15.000000 #3784] INFO -- GenerateInvoice:
28
+ index=0 chain_id="018c2b95-b764-7615-a924-cc5b910ed1e5" type="Task"
29
+ class="GenerateInvoice" state="complete" status="success" metadata={runtime: 187}
133
30
 
134
- | Status | Log Level | When Used |
135
- |--------|-----------|-----------|
136
- | `success` | `INFO` | Normal completion |
137
- | `skipped` | `WARN` | Intentional skip via business logic |
138
- | `failed` | `ERROR` | Task failure or exception |
31
+ <!-- Skipped (WARN level) -->
32
+ W, [2022-07-17T18:43:15.000000 #3784] WARN -- ValidateCustomer:
33
+ index=1 state="interrupted" status="skipped" reason="Customer already validated"
139
34
 
140
- ## Manual Logging
35
+ <!-- Failed (ERROR level) -->
36
+ E, [2022-07-17T18:43:15.000000 #3784] ERROR -- CalculateTax:
37
+ index=2 state="interrupted" status="failed" metadata={error_code: "TAX_SERVICE_UNAVAILABLE"}
141
38
 
142
- ```ruby
143
- class ProcessOrderTask < CMDx::Task
144
- def call
145
- # Structured logging with metadata
146
- logger.info "Starting order processing", order_id: context.order_id
147
-
148
- # Performance-optimized debug logging
149
- logger.debug { "Order details: #{context.order.inspect}" }
150
-
151
- # Exception context
152
- begin
153
- validate_inventory
154
- rescue StandardError => e
155
- logger.error "Inventory validation failed", {
156
- exception: e.class.name,
157
- order_id: context.order_id,
158
- message: e.message
159
- }
160
- raise
161
- end
162
-
163
- # Success with metadata
164
- logger.info "Order processed successfully", {
165
- order_id: context.order_id,
166
- amount: context.order.total
167
- }
168
- end
169
- end
39
+ <!-- Failed Chain -->
40
+ E, [2022-07-17T18:43:15.000000 #3784] ERROR -- BillingWorkflow:
41
+ caused_failure={index: 2, class: "CalculateTax", status: "failed"}
42
+ threw_failure={index: 1, class: "ValidateCustomer", status: "failed"}
170
43
  ```
171
44
 
172
- ## Error Handling
173
-
174
- > [!WARNING]
175
- > Logger configuration errors are handled gracefully, falling back to STDOUT with PrettyLine formatter to ensure execution continuity.
176
-
177
- ### Configuration Error Recovery
178
-
179
- ```ruby
180
- # Invalid logger configuration
181
- CMDx.configure do |config|
182
- config.logger = Logger.new("/invalid/path/cmdx.log") # Permission denied
183
- end
184
-
185
- # CMDx automatically falls back to:
186
- # Logger.new(STDOUT, formatter: CMDx::LogFormatters::PrettyLine.new)
187
- ```
188
-
189
- ### Formatter Error Handling
190
-
191
- ```ruby
192
- class BrokenFormatter
193
- def call(severity, time, task, message)
194
- raise StandardError, "Formatter error"
195
- end
196
- end
197
-
198
- class TestTask < CMDx::Task
199
- cmd_settings!(log_formatter: BrokenFormatter.new)
200
-
201
- def call
202
- # Execution continues with fallback formatter
203
- # Error logged to STDERR for debugging
204
- end
205
- end
206
- ```
207
-
208
- ### Log Level Validation
209
-
210
- ```ruby
211
- # Invalid log levels default to INFO
212
- CMDx.configure do |config|
213
- config.log_level = "INVALID" # → Logger::INFO
214
- end
215
-
216
- # Valid levels: DEBUG, INFO, WARN, ERROR, FATAL
217
- ```
218
-
219
- ## Advanced Usage
220
-
221
- ### Custom Formatters
222
-
223
- ```ruby
224
- class AlertFormatter
225
- def call(severity, time, task, message)
226
- emoji = case severity
227
- when 'INFO' then '✅'
228
- when 'WARN' then '⚠️'
229
- when 'ERROR' then '❌'
230
- else '📝'
231
- end
232
-
233
- "[#{time.strftime('%H:%M:%S')}] #{emoji} #{task.class.name}: #{message}\n"
234
- end
235
- end
236
-
237
- class NotificationTask < CMDx::Task
238
- cmd_settings!(log_formatter: AlertFormatter.new)
239
-
240
- def call
241
- # Uses custom emoji-based formatting
242
- end
243
- end
244
- ```
245
-
246
- ### Multi-Destination Logging
247
-
248
45
  > [!TIP]
249
- > Combine multiple loggers to output to both console and files simultaneously during development.
46
+ > Logging can be used as low-level eventing system, ingesting all tasks performed within a small action or long running request. This ie where correlation is especially handy.
250
47
 
251
- ```ruby
252
- class MultiLogger
253
- def initialize(*loggers)
254
- @loggers = loggers
255
- end
48
+ ## Structure
256
49
 
257
- %w[debug info warn error fatal].each do |level|
258
- define_method(level) do |message = nil, **metadata, &block|
259
- @loggers.each { |logger| logger.send(level, message, **metadata, &block) }
260
- end
261
- end
262
- end
263
-
264
- # Configuration
265
- CMDx.configure do |config|
266
- config.logger = MultiLogger.new(
267
- Logger.new(STDOUT, formatter: CMDx::LogFormatters::PrettyLine.new),
268
- Logger.new("log/cmdx.log", formatter: CMDx::LogFormatters::Json.new)
269
- )
270
- end
271
- ```
272
-
273
- ## Log Data Structure
274
-
275
- > [!NOTE]
276
- > All log entries include comprehensive execution metadata for debugging and monitoring. Field availability depends on the execution context.
50
+ All log entries include comprehensive execution metadata. Field availability depends on execution context and outcome.
277
51
 
278
52
  ### Core Fields
279
53
 
@@ -282,7 +56,6 @@ end
282
56
  | `severity` | Log level | `INFO`, `WARN`, `ERROR` |
283
57
  | `timestamp` | ISO 8601 execution time | `2022-07-17T18:43:15.000000` |
284
58
  | `pid` | Process ID | `3784` |
285
- | `origin` | Source identifier | `CMDx` |
286
59
 
287
60
  ### Task Information
288
61
 
@@ -291,9 +64,9 @@ end
291
64
  | `index` | Execution sequence position | `0`, `1`, `2` |
292
65
  | `chain_id` | Unique execution chain ID | `018c2b95-b764-7615...` |
293
66
  | `type` | Execution unit type | `Task`, `Workflow` |
294
- | `class` | Task class name | `ProcessOrderTask` |
67
+ | `class` | Task class name | `GenerateInvoiceTask` |
295
68
  | `id` | Unique task instance ID | `018c2b95-b764-7615...` |
296
- | `tags` | Custom categorization | `["priority", "payment"]` |
69
+ | `tags` | Custom categorization | `["billing", "financial"]` |
297
70
 
298
71
  ### Execution Data
299
72
 
@@ -303,16 +76,31 @@ end
303
76
  | `status` | Business outcome | `success`, `skipped`, `failed` |
304
77
  | `outcome` | Final classification | `success`, `interrupted` |
305
78
  | `metadata` | Custom task data | `{order_id: 123, amount: 99.99}` |
306
- | `runtime` | Execution time (seconds) | `0.45` |
307
79
 
308
- ### Failure Chain (Workflows)
80
+ ### Failure Chain
309
81
 
310
82
  | Field | Description |
311
83
  |-------|-------------|
84
+ | `reason` | Reason given for the stoppage |
85
+ | `caused` | Cause exception details |
312
86
  | `caused_failure` | Original failing task details |
313
87
  | `threw_failure` | Task that propagated the failure |
314
88
 
89
+ ## Usage
90
+
91
+ Tasks have access to the frameworks logger.
92
+
93
+ ```ruby
94
+ class ProcessSubscription < CMDx::Task
95
+ def work
96
+ logger.debug { "Activated feature flags: #{Features.active_flags}" }
97
+ # Your logic here...
98
+ logger.info("Subscription processed")
99
+ end
100
+ end
101
+ ```
102
+
315
103
  ---
316
104
 
317
- - **Prev:** [Workflows](workflows.md)
105
+ - **Prev:** [Middlewares](middlewares.md)
318
106
  - **Next:** [Internationalization (i18n)](internationalization.md)