cmdx 0.4.0 → 1.0.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 (126) hide show
  1. checksums.yaml +4 -4
  2. data/.DS_Store +0 -0
  3. data/.cursor/rules/cursor-instructions.mdc +6 -0
  4. data/.rubocop.yml +16 -1
  5. data/.ruby-version +1 -1
  6. data/CHANGELOG.md +42 -1
  7. data/README.md +72 -25
  8. data/docs/ai_prompts.md +309 -0
  9. data/docs/basics/call.md +225 -14
  10. data/docs/basics/chain.md +271 -0
  11. data/docs/basics/context.md +232 -33
  12. data/docs/basics/setup.md +76 -12
  13. data/docs/callbacks.md +273 -0
  14. data/docs/configuration.md +158 -28
  15. data/docs/getting_started.md +134 -22
  16. data/docs/interruptions/exceptions.md +189 -11
  17. data/docs/interruptions/faults.md +187 -44
  18. data/docs/interruptions/halt.md +179 -35
  19. data/docs/logging.md +194 -53
  20. data/docs/middlewares.md +735 -0
  21. data/docs/outcomes/result.md +296 -10
  22. data/docs/outcomes/states.md +212 -19
  23. data/docs/outcomes/statuses.md +284 -18
  24. data/docs/parameters/coercions.md +402 -29
  25. data/docs/parameters/defaults.md +249 -25
  26. data/docs/parameters/definitions.md +238 -72
  27. data/docs/parameters/namespacing.md +250 -27
  28. data/docs/parameters/validations.md +193 -168
  29. data/docs/testing.md +550 -0
  30. data/docs/tips_and_tricks.md +95 -43
  31. data/docs/workflows.md +319 -0
  32. data/lib/cmdx/.DS_Store +0 -0
  33. data/lib/cmdx/callback.rb +69 -0
  34. data/lib/cmdx/callback_registry.rb +106 -0
  35. data/lib/cmdx/chain.rb +190 -0
  36. data/lib/cmdx/chain_inspector.rb +149 -0
  37. data/lib/cmdx/chain_serializer.rb +175 -0
  38. data/lib/cmdx/coercions/array.rb +37 -0
  39. data/lib/cmdx/coercions/big_decimal.rb +33 -0
  40. data/lib/cmdx/coercions/boolean.rb +41 -1
  41. data/lib/cmdx/coercions/complex.rb +31 -0
  42. data/lib/cmdx/coercions/date.rb +39 -0
  43. data/lib/cmdx/coercions/date_time.rb +39 -0
  44. data/lib/cmdx/coercions/float.rb +31 -0
  45. data/lib/cmdx/coercions/hash.rb +42 -0
  46. data/lib/cmdx/coercions/integer.rb +32 -0
  47. data/lib/cmdx/coercions/rational.rb +31 -0
  48. data/lib/cmdx/coercions/string.rb +31 -0
  49. data/lib/cmdx/coercions/time.rb +39 -0
  50. data/lib/cmdx/coercions/virtual.rb +31 -0
  51. data/lib/cmdx/configuration.rb +217 -9
  52. data/lib/cmdx/context.rb +173 -2
  53. data/lib/cmdx/core_ext/hash.rb +72 -0
  54. data/lib/cmdx/core_ext/module.rb +94 -0
  55. data/lib/cmdx/core_ext/object.rb +105 -0
  56. data/lib/cmdx/correlator.rb +217 -0
  57. data/lib/cmdx/error.rb +210 -8
  58. data/lib/cmdx/errors.rb +256 -1
  59. data/lib/cmdx/fault.rb +177 -2
  60. data/lib/cmdx/faults.rb +158 -2
  61. data/lib/cmdx/immutator.rb +121 -2
  62. data/lib/cmdx/lazy_struct.rb +261 -18
  63. data/lib/cmdx/log_formatters/json.rb +46 -0
  64. data/lib/cmdx/log_formatters/key_value.rb +46 -0
  65. data/lib/cmdx/log_formatters/line.rb +54 -0
  66. data/lib/cmdx/log_formatters/logstash.rb +64 -0
  67. data/lib/cmdx/log_formatters/pretty_json.rb +57 -0
  68. data/lib/cmdx/log_formatters/pretty_key_value.rb +51 -0
  69. data/lib/cmdx/log_formatters/pretty_line.rb +60 -0
  70. data/lib/cmdx/log_formatters/raw.rb +54 -0
  71. data/lib/cmdx/logger.rb +85 -0
  72. data/lib/cmdx/logger_ansi.rb +93 -7
  73. data/lib/cmdx/logger_serializer.rb +116 -0
  74. data/lib/cmdx/middleware.rb +74 -0
  75. data/lib/cmdx/middleware_registry.rb +106 -0
  76. data/lib/cmdx/middlewares/correlate.rb +266 -0
  77. data/lib/cmdx/middlewares/timeout.rb +232 -0
  78. data/lib/cmdx/parameter.rb +228 -1
  79. data/lib/cmdx/parameter_inspector.rb +61 -0
  80. data/lib/cmdx/parameter_registry.rb +125 -0
  81. data/lib/cmdx/parameter_serializer.rb +83 -0
  82. data/lib/cmdx/parameter_validator.rb +62 -0
  83. data/lib/cmdx/parameter_value.rb +109 -1
  84. data/lib/cmdx/parameters_inspector.rb +59 -0
  85. data/lib/cmdx/parameters_serializer.rb +102 -0
  86. data/lib/cmdx/railtie.rb +123 -3
  87. data/lib/cmdx/result.rb +399 -20
  88. data/lib/cmdx/result_ansi.rb +105 -9
  89. data/lib/cmdx/result_inspector.rb +76 -0
  90. data/lib/cmdx/result_logger.rb +90 -3
  91. data/lib/cmdx/result_serializer.rb +137 -0
  92. data/lib/cmdx/rspec/result_matchers.rb +917 -0
  93. data/lib/cmdx/rspec/task_matchers.rb +570 -0
  94. data/lib/cmdx/task.rb +409 -34
  95. data/lib/cmdx/task_serializer.rb +74 -2
  96. data/lib/cmdx/utils/ansi_color.rb +95 -0
  97. data/lib/cmdx/utils/log_timestamp.rb +48 -0
  98. data/lib/cmdx/utils/monotonic_runtime.rb +71 -4
  99. data/lib/cmdx/utils/name_affix.rb +78 -0
  100. data/lib/cmdx/validators/custom.rb +82 -0
  101. data/lib/cmdx/validators/exclusion.rb +94 -0
  102. data/lib/cmdx/validators/format.rb +102 -8
  103. data/lib/cmdx/validators/inclusion.rb +104 -0
  104. data/lib/cmdx/validators/length.rb +128 -0
  105. data/lib/cmdx/validators/numeric.rb +128 -0
  106. data/lib/cmdx/validators/presence.rb +93 -7
  107. data/lib/cmdx/version.rb +7 -1
  108. data/lib/cmdx/workflow.rb +394 -0
  109. data/lib/cmdx.rb +25 -64
  110. data/lib/generators/cmdx/install_generator.rb +37 -1
  111. data/lib/generators/cmdx/task_generator.rb +69 -1
  112. data/lib/generators/cmdx/templates/install.rb +8 -12
  113. data/lib/generators/cmdx/workflow_generator.rb +109 -0
  114. metadata +54 -15
  115. data/docs/basics/run.md +0 -34
  116. data/docs/batch.md +0 -53
  117. data/docs/example.md +0 -82
  118. data/docs/hooks.md +0 -59
  119. data/lib/cmdx/batch.rb +0 -43
  120. data/lib/cmdx/parameters.rb +0 -34
  121. data/lib/cmdx/run.rb +0 -38
  122. data/lib/cmdx/run_inspector.rb +0 -26
  123. data/lib/cmdx/run_serializer.rb +0 -16
  124. data/lib/cmdx/task_hook.rb +0 -18
  125. data/lib/generators/cmdx/batch_generator.rb +0 -30
  126. /data/lib/generators/cmdx/templates/{batch.rb.tt → workflow.rb.tt} +0 -0
@@ -2,8 +2,54 @@
2
2
 
3
3
  module CMDx
4
4
  module LogFormatters
5
+ # JSON log formatter for CMDx logging system.
6
+ #
7
+ # Formats log entries as single-line JSON objects containing task execution metadata
8
+ # including severity, timestamp, process ID, and serialized task information.
9
+ # Ideal for structured logging systems that need to parse log data programmatically.
10
+ #
11
+ # @example Basic usage with global logger configuration
12
+ # CMDx.configure do |config|
13
+ # config.logger = Logger.new($stdout, formatter: CMDx::LogFormatters::Json.new)
14
+ # end
15
+ #
16
+ # @example Task-specific formatter configuration
17
+ # class ProcessOrderTask < CMDx::Task
18
+ # task_settings!(log_format: CMDx::LogFormatters::Json.new)
19
+ #
20
+ # def call
21
+ # logger.info "Processing order #{order_id}"
22
+ # end
23
+ # end
24
+ #
25
+ # @example Sample JSON output
26
+ # {"severity":"INFO","pid":1234,"timestamp":"2022-07-17T18:43:15.000000","index":0,"chain_id":"018c2b95-b764-7615","type":"Task","class":"ProcessOrderTask","id":"018c2b95-b764-7615","tags":[],"state":"complete","status":"success","outcome":"success","metadata":{},"runtime":15,"origin":"CMDx"}
27
+ #
28
+ # @see CMDx::LogFormatters::PrettyJson For human-readable JSON formatting
29
+ # @see CMDx::LoggerSerializer For details on serialized data structure
5
30
  class Json
6
31
 
32
+ # Formats a log entry as a single-line JSON string.
33
+ #
34
+ # Combines task execution metadata with severity, process ID, and timestamp
35
+ # information to create a comprehensive JSON log entry suitable for
36
+ # structured logging systems and log aggregation tools.
37
+ #
38
+ # @param severity [String] Log severity level (DEBUG, INFO, WARN, ERROR, FATAL)
39
+ # @param time [Time] Timestamp when the log entry was created
40
+ # @param task [CMDx::Task] Task instance being logged
41
+ # @param message [Object] Log message or data to be included
42
+ #
43
+ # @return [String] Single-line JSON string with newline terminator
44
+ #
45
+ # @example Success log entry
46
+ # formatter = CMDx::LogFormatters::Json.new
47
+ # output = formatter.call("INFO", Time.now, task, "Order processed")
48
+ # # => {"severity":"INFO","pid":1234,...}\n
49
+ #
50
+ # @example Error log entry with metadata
51
+ # output = formatter.call("ERROR", Time.now, task, error_details)
52
+ # # => {"severity":"ERROR","pid":1234,"caused_failure":{...},...}\n
7
53
  def call(severity, time, task, message)
8
54
  m = LoggerSerializer.call(severity, time, task, message).merge!(
9
55
  severity:,
@@ -2,8 +2,54 @@
2
2
 
3
3
  module CMDx
4
4
  module LogFormatters
5
+ # Key-value log formatter for CMDx logging system.
6
+ #
7
+ # Formats log entries as space-separated key=value pairs on a single line.
8
+ # Provides a compact, structured format that is easily parseable by log
9
+ # processing tools while remaining human-readable for basic inspection.
10
+ #
11
+ # @example Basic usage with global logger configuration
12
+ # CMDx.configure do |config|
13
+ # config.logger = Logger.new($stdout, formatter: CMDx::LogFormatters::KeyValue.new)
14
+ # end
15
+ #
16
+ # @example Task-specific formatter configuration
17
+ # class ProcessOrderTask < CMDx::Task
18
+ # task_settings!(log_format: CMDx::LogFormatters::KeyValue.new)
19
+ #
20
+ # def call
21
+ # logger.info "Processing order #{order_id}"
22
+ # end
23
+ # end
24
+ #
25
+ # @example Sample key-value output
26
+ # severity=INFO pid=1234 timestamp=2022-07-17T18:43:15.000000 index=0 chain_id=018c2b95-b764-7615 type=Task class=ProcessOrderTask id=018c2b95-b764-7615 tags=[] state=complete status=success outcome=success metadata={} runtime=15 origin=CMDx
27
+ #
28
+ # @see CMDx::LogFormatters::PrettyKeyValue For ANSI-colorized key-value formatting
29
+ # @see CMDx::LoggerSerializer For details on serialized data structure
5
30
  class KeyValue
6
31
 
32
+ # Formats a log entry as space-separated key=value pairs.
33
+ #
34
+ # Combines task execution metadata with severity, process ID, and timestamp
35
+ # information to create a compact key-value log entry suitable for
36
+ # structured logging systems that prefer flat field formats.
37
+ #
38
+ # @param severity [String] Log severity level (DEBUG, INFO, WARN, ERROR, FATAL)
39
+ # @param time [Time] Timestamp when the log entry was created
40
+ # @param task [CMDx::Task] Task instance being logged
41
+ # @param message [Object] Log message or data to be included
42
+ #
43
+ # @return [String] Single-line key=value formatted string with newline terminator
44
+ #
45
+ # @example Success log entry
46
+ # formatter = CMDx::LogFormatters::KeyValue.new
47
+ # output = formatter.call("INFO", Time.now, task, "Order processed")
48
+ # # => "severity=INFO pid=1234 timestamp=... status=success\n"
49
+ #
50
+ # @example Error log entry with failure metadata
51
+ # output = formatter.call("ERROR", Time.now, task, error_details)
52
+ # # => "severity=ERROR pid=1234 ... caused_failure={...} threw_failure={...}\n"
7
53
  def call(severity, time, task, message)
8
54
  m = LoggerSerializer.call(severity, time, task, message).merge!(
9
55
  severity:,
@@ -2,8 +2,62 @@
2
2
 
3
3
  module CMDx
4
4
  module LogFormatters
5
+ # Line log formatter for CMDx logging system.
6
+ #
7
+ # Formats log entries in a traditional single-line format similar to Ruby's
8
+ # standard Logger output. Combines severity indicators, timestamps, process
9
+ # information, and task details in a compact, readable format suitable for
10
+ # standard logging environments.
11
+ #
12
+ # @example Basic usage with global logger configuration
13
+ # CMDx.configure do |config|
14
+ # config.logger = Logger.new($stdout, formatter: CMDx::LogFormatters::Line.new)
15
+ # end
16
+ #
17
+ # @example Task-specific formatter configuration
18
+ # class ProcessOrderTask < CMDx::Task
19
+ # task_settings!(log_format: CMDx::LogFormatters::Line.new)
20
+ #
21
+ # def call
22
+ # logger.info "Processing order #{order_id}"
23
+ # end
24
+ # end
25
+ #
26
+ # @example Sample line output
27
+ # I, [2022-07-17T18:43:15.000000 #1234] INFO -- ProcessOrderTask: state=complete status=success outcome=success runtime=15
28
+ #
29
+ # @example Error line output with failure details
30
+ # E, [2022-07-17T18:43:15.000000 #1234] ERROR -- ProcessOrderTask: state=interrupted status=failed outcome=failed caused_failure={...}
31
+ #
32
+ # @see CMDx::LogFormatters::PrettyLine For ANSI-colorized line formatting
33
+ # @see CMDx::LoggerSerializer For details on serialized data structure
34
+ # @see CMDx::Utils::LogTimestamp For timestamp formatting
5
35
  class Line
6
36
 
37
+ # Formats a log entry as a traditional single-line log entry.
38
+ #
39
+ # Creates a log entry in the format: "SEVERITY_INITIAL, [TIMESTAMP #PID] SEVERITY -- CLASS: MESSAGE"
40
+ # where MESSAGE contains key=value pairs of task execution metadata.
41
+ #
42
+ # @param severity [String] Log severity level (DEBUG, INFO, WARN, ERROR, FATAL)
43
+ # @param time [Time] Timestamp when the log entry was created
44
+ # @param task [CMDx::Task] Task instance being logged
45
+ # @param message [Object] Log message or data to be included
46
+ #
47
+ # @return [String] Single-line formatted log entry with newline terminator
48
+ #
49
+ # @example Success log entry
50
+ # formatter = CMDx::LogFormatters::Line.new
51
+ # output = formatter.call("INFO", Time.now, task, "Order processed")
52
+ # # => "I, [2022-07-17T18:43:15.000000 #1234] INFO -- ProcessOrderTask: state=complete status=success\n"
53
+ #
54
+ # @example Debug log entry with detailed metadata
55
+ # output = formatter.call("DEBUG", Time.now, task, debug_info)
56
+ # # => "D, [2022-07-17T18:43:15.000000 #1234] DEBUG -- ProcessOrderTask: index=0 chain_id=... metadata={...}\n"
57
+ #
58
+ # @example Error log entry with failure chain
59
+ # output = formatter.call("ERROR", Time.now, task, error_details)
60
+ # # => "E, [2022-07-17T18:43:15.000000 #1234] ERROR -- ProcessOrderTask: status=failed caused_failure={...} threw_failure={...}\n"
7
61
  def call(severity, time, task, message)
8
62
  t = Utils::LogTimestamp.call(time.utc)
9
63
  m = LoggerSerializer.call(severity, time, task, message)
@@ -2,8 +2,72 @@
2
2
 
3
3
  module CMDx
4
4
  module LogFormatters
5
+ # Logstash log formatter for CMDx logging system.
6
+ #
7
+ # Formats log entries as JSON objects compatible with Logstash and the ELK stack
8
+ # (Elasticsearch, Logstash, Kibana). Includes Logstash-specific fields like
9
+ # @version and @timestamp for seamless integration with log aggregation pipelines.
10
+ #
11
+ # @example Basic usage with global logger configuration
12
+ # CMDx.configure do |config|
13
+ # config.logger = Logger.new($stdout, formatter: CMDx::LogFormatters::Logstash.new)
14
+ # end
15
+ #
16
+ # @example Task-specific formatter configuration for ELK stack
17
+ # class ProcessOrderTask < CMDx::Task
18
+ # task_settings!(log_format: CMDx::LogFormatters::Logstash.new)
19
+ #
20
+ # def call
21
+ # logger.info "Processing order #{order_id}"
22
+ # end
23
+ # end
24
+ #
25
+ # @example Sample Logstash JSON output
26
+ # {"@version":"1","@timestamp":"2022-07-17T18:43:15.000000","severity":"INFO","pid":1234,"index":0,"chain_id":"018c2b95-b764-7615","type":"Task","class":"ProcessOrderTask","id":"018c2b95-b764-7615","tags":[],"state":"complete","status":"success","outcome":"success","metadata":{},"runtime":15,"origin":"CMDx"}
27
+ #
28
+ # @example Logstash configuration for CMDx logs
29
+ # input {
30
+ # file {
31
+ # path => "/var/log/cmdx/*.log"
32
+ # codec => "json"
33
+ # }
34
+ # }
35
+ # filter {
36
+ # if [origin] == "CMDx" {
37
+ # # Process CMDx-specific fields
38
+ # }
39
+ # }
40
+ #
41
+ # @see CMDx::LogFormatters::Json For standard JSON formatting without Logstash fields
42
+ # @see CMDx::LoggerSerializer For details on serialized data structure
43
+ # @see https://www.elastic.co/guide/en/logstash/current/event-api.html Logstash Event API
5
44
  class Logstash
6
45
 
46
+ # Formats a log entry as a Logstash-compatible JSON string.
47
+ #
48
+ # Creates a JSON object with Logstash-specific metadata fields (@version, @timestamp)
49
+ # combined with task execution data, severity, and process information for
50
+ # seamless integration with ELK stack log processing pipelines.
51
+ #
52
+ # @param severity [String] Log severity level (DEBUG, INFO, WARN, ERROR, FATAL)
53
+ # @param time [Time] Timestamp when the log entry was created
54
+ # @param task [CMDx::Task] Task instance being logged
55
+ # @param message [Object] Log message or data to be included
56
+ #
57
+ # @return [String] Single-line Logstash-compatible JSON string with newline terminator
58
+ #
59
+ # @example Success log entry for Logstash
60
+ # formatter = CMDx::LogFormatters::Logstash.new
61
+ # output = formatter.call("INFO", Time.now, task, "Order processed")
62
+ # # => {"@version":"1","@timestamp":"2022-07-17T18:43:15.000000","severity":"INFO",...}\n
63
+ #
64
+ # @example Error log entry with failure chain for ELK analysis
65
+ # output = formatter.call("ERROR", Time.now, task, error_details)
66
+ # # => {"@version":"1","severity":"ERROR","caused_failure":{...},"threw_failure":{...},...}\n
67
+ #
68
+ # @note The @version field is always set to "1" following Logstash conventions
69
+ # @note The @timestamp field uses ISO 8601 format for Elasticsearch compatibility
70
+ # @note All CMDx logs include an "origin" field set to "CMDx" for easy filtering
7
71
  def call(severity, time, task, message)
8
72
  m = LoggerSerializer.call(severity, time, task, message).merge!(
9
73
  severity:,
@@ -2,8 +2,65 @@
2
2
 
3
3
  module CMDx
4
4
  module LogFormatters
5
+ # Pretty JSON log formatter for CMDx logging system.
6
+ #
7
+ # Formats log entries as human-readable, multi-line JSON objects with proper
8
+ # indentation and formatting. Contains the same structured data as the JSON
9
+ # formatter but optimized for development environments and manual inspection.
10
+ #
11
+ # @example Basic usage with global logger configuration
12
+ # CMDx.configure do |config|
13
+ # config.logger = Logger.new($stdout, formatter: CMDx::LogFormatters::PrettyJson.new)
14
+ # end
15
+ #
16
+ # @example Task-specific formatter configuration
17
+ # class ProcessOrderTask < CMDx::Task
18
+ # task_settings!(log_format: CMDx::LogFormatters::PrettyJson.new)
19
+ #
20
+ # def call
21
+ # logger.info "Processing order #{order_id}"
22
+ # end
23
+ # end
24
+ #
25
+ # @example Sample pretty JSON output
26
+ # {
27
+ # "severity": "INFO",
28
+ # "pid": 1234,
29
+ # "timestamp": "2022-07-17T18:43:15.000000",
30
+ # "index": 0,
31
+ # "chain_id": "018c2b95-b764-7615",
32
+ # "type": "Task",
33
+ # "class": "ProcessOrderTask",
34
+ # "state": "complete",
35
+ # "status": "success",
36
+ # "outcome": "success"
37
+ # }
38
+ #
39
+ # @see CMDx::LogFormatters::Json For compact single-line JSON formatting
40
+ # @see CMDx::LoggerSerializer For details on serialized data structure
5
41
  class PrettyJson
6
42
 
43
+ # Formats a log entry as a pretty-printed JSON string.
44
+ #
45
+ # Combines task execution metadata with severity, process ID, and timestamp
46
+ # information to create a human-readable JSON log entry with proper
47
+ # indentation and formatting for development and debugging purposes.
48
+ #
49
+ # @param severity [String] Log severity level (DEBUG, INFO, WARN, ERROR, FATAL)
50
+ # @param time [Time] Timestamp when the log entry was created
51
+ # @param task [CMDx::Task] Task instance being logged
52
+ # @param message [Object] Log message or data to be included
53
+ #
54
+ # @return [String] Multi-line pretty-formatted JSON string with newline terminator
55
+ #
56
+ # @example Success log entry
57
+ # formatter = CMDx::LogFormatters::PrettyJson.new
58
+ # output = formatter.call("INFO", Time.now, task, "Order processed")
59
+ # # => Multi-line formatted JSON output
60
+ #
61
+ # @example Error log entry with nested metadata
62
+ # output = formatter.call("ERROR", Time.now, task, error_details)
63
+ # # => Pretty-formatted JSON with nested failure information
7
64
  def call(severity, time, task, message)
8
65
  m = LoggerSerializer.call(severity, time, task, message).merge!(
9
66
  severity:,
@@ -2,8 +2,59 @@
2
2
 
3
3
  module CMDx
4
4
  module LogFormatters
5
+ # Pretty key-value log formatter for CMDx logging system.
6
+ #
7
+ # Formats log entries as space-separated key=value pairs with ANSI color
8
+ # highlighting for improved readability in terminal environments. Provides
9
+ # the same structured data as KeyValue formatter with enhanced visual presentation.
10
+ #
11
+ # @example Basic usage with global logger configuration
12
+ # CMDx.configure do |config|
13
+ # config.logger = Logger.new($stdout, formatter: CMDx::LogFormatters::PrettyKeyValue.new)
14
+ # end
15
+ #
16
+ # @example Task-specific formatter configuration
17
+ # class ProcessOrderTask < CMDx::Task
18
+ # task_settings!(log_format: CMDx::LogFormatters::PrettyKeyValue.new)
19
+ #
20
+ # def call
21
+ # logger.info "Processing order #{order_id}"
22
+ # end
23
+ # end
24
+ #
25
+ # @example Sample pretty key-value output (with ANSI colors)
26
+ # severity=INFO pid=1234 timestamp=2022-07-17T18:43:15.000000 index=0 chain_id=018c2b95-b764-7615 type=Task class=ProcessOrderTask state=complete status=success outcome=success runtime=15
27
+ # # Colors applied: severity levels, status values, class names, etc.
28
+ #
29
+ # @see CMDx::LogFormatters::KeyValue For plain key-value formatting without colors
30
+ # @see CMDx::LoggerAnsi For ANSI color definitions
31
+ # @see CMDx::LoggerSerializer For details on serialized data structure
5
32
  class PrettyKeyValue
6
33
 
34
+ # Formats a log entry as ANSI-colorized key=value pairs.
35
+ #
36
+ # Combines task execution metadata with severity, process ID, and timestamp
37
+ # information to create a visually enhanced key-value log entry with ANSI
38
+ # color codes for improved readability in terminal environments.
39
+ #
40
+ # @param severity [String] Log severity level (DEBUG, INFO, WARN, ERROR, FATAL)
41
+ # @param time [Time] Timestamp when the log entry was created
42
+ # @param task [CMDx::Task] Task instance being logged
43
+ # @param message [Object] Log message or data to be included
44
+ #
45
+ # @return [String] Single-line ANSI-colorized key=value formatted string with newline terminator
46
+ #
47
+ # @example Success log entry with colors
48
+ # formatter = CMDx::LogFormatters::PrettyKeyValue.new
49
+ # output = formatter.call("INFO", Time.now, task, "Order processed")
50
+ # # => ANSI-colored "severity=INFO pid=1234 ... status=success\n"
51
+ #
52
+ # @example Error log entry with colored failure indicators
53
+ # output = formatter.call("ERROR", Time.now, task, error_details)
54
+ # # => ANSI-colored "severity=ERROR ... status=failed\n" (red highlighting)
55
+ #
56
+ # @note ANSI colors are automatically applied to key elements like severity levels,
57
+ # status values, class names, and metadata for enhanced visual distinction
7
58
  def call(severity, time, task, message)
8
59
  m = LoggerSerializer.call(severity, time, task, message, ansi_colorize: true).merge!(
9
60
  severity:,
@@ -2,8 +2,68 @@
2
2
 
3
3
  module CMDx
4
4
  module LogFormatters
5
+ # Pretty line log formatter for CMDx logging system.
6
+ #
7
+ # Formats log entries in a traditional single-line format enhanced with ANSI color
8
+ # highlighting for improved readability in terminal environments. Provides the same
9
+ # structured format as Line formatter with visual enhancements for severity levels,
10
+ # status indicators, and task information.
11
+ #
12
+ # @example Basic usage with global logger configuration
13
+ # CMDx.configure do |config|
14
+ # config.logger = Logger.new(STDOUT, formatter: CMDx::LogFormatters::PrettyLine.new)
15
+ # end
16
+ #
17
+ # @example Task-specific formatter configuration
18
+ # class ProcessOrderTask < CMDx::Task
19
+ # task_settings!(log_format: CMDx::LogFormatters::PrettyLine.new)
20
+ #
21
+ # def call
22
+ # logger.info "Processing order #{order_id}"
23
+ # end
24
+ # end
25
+ #
26
+ # @example Sample pretty line output (with ANSI colors)
27
+ # I, [2022-07-17T18:43:15.000000 #1234] INFO -- ProcessOrderTask: state=complete status=success outcome=success runtime=15
28
+ # # Colors applied: INFO in blue, success in green, class name highlighted
29
+ #
30
+ # @example Error pretty line output with colored failure indicators
31
+ # E, [2022-07-17T18:43:15.000000 #1234] ERROR -- ProcessOrderTask: state=interrupted status=failed outcome=failed
32
+ # # Colors applied: ERROR in red, failed in red, class name highlighted
33
+ #
34
+ # @see CMDx::LogFormatters::Line For plain line formatting without colors
35
+ # @see CMDx::LoggerAnsi For ANSI color definitions
36
+ # @see CMDx::LoggerSerializer For details on serialized data structure
37
+ # @see CMDx::Utils::LogTimestamp For timestamp formatting
5
38
  class PrettyLine
6
39
 
40
+ # Formats a log entry as an ANSI-colorized single-line log entry.
41
+ #
42
+ # Creates a log entry in the format: "[COLORED_SEVERITY_INITIAL], [TIMESTAMP #PID] [COLORED_SEVERITY] -- CLASS: [COLORED_MESSAGE]"
43
+ # where colors are applied to severity indicators, status values, and other key elements.
44
+ #
45
+ # @param severity [String] Log severity level (DEBUG, INFO, WARN, ERROR, FATAL)
46
+ # @param time [Time] Timestamp when the log entry was created
47
+ # @param task [CMDx::Task] Task instance being logged
48
+ # @param message [Object] Log message or data to be included
49
+ #
50
+ # @return [String] Single-line ANSI-colorized log entry with newline terminator
51
+ #
52
+ # @example Success log entry with colors
53
+ # formatter = CMDx::LogFormatters::PrettyLine.new
54
+ # output = formatter.call("INFO", Time.now, task, "Order processed")
55
+ # # => ANSI-colored "I, [2022-07-17T18:43:15.000000 #1234] INFO -- ProcessOrderTask: state=complete status=success\n"
56
+ #
57
+ # @example Warning log entry with colored indicators
58
+ # output = formatter.call("WARN", Time.now, task, "Order delayed")
59
+ # # => ANSI-colored "W, [2022-07-17T18:43:15.000000 #1234] WARN -- ProcessOrderTask: state=interrupted status=skipped\n"
60
+ #
61
+ # @example Error log entry with red highlighting
62
+ # output = formatter.call("ERROR", Time.now, task, error_details)
63
+ # # => ANSI-colored "E, [2022-07-17T18:43:15.000000 #1234] ERROR -- ProcessOrderTask: status=failed caused_failure={...}\n"
64
+ #
65
+ # @note This is the default formatter for CMDx when no specific formatter is configured
66
+ # @note ANSI colors are automatically applied based on severity levels and status values
7
67
  def call(severity, time, task, message)
8
68
  i = LoggerAnsi.call(severity[0])
9
69
  s = LoggerAnsi.call(severity)
@@ -2,8 +2,62 @@
2
2
 
3
3
  module CMDx
4
4
  module LogFormatters
5
+ # Raw log formatter for CMDx logging system.
6
+ #
7
+ # Outputs only the raw message content without any additional formatting,
8
+ # timestamps, severity indicators, or task metadata. Provides the simplest
9
+ # possible log output containing just the inspected message content.
10
+ #
11
+ # @example Basic usage with global logger configuration
12
+ # CMDx.configure do |config|
13
+ # config.logger = Logger.new($stdout, formatter: CMDx::LogFormatters::Raw.new)
14
+ # end
15
+ #
16
+ # @example Task-specific formatter configuration
17
+ # class ProcessOrderTask < CMDx::Task
18
+ # task_settings!(log_format: CMDx::LogFormatters::Raw.new)
19
+ #
20
+ # def call
21
+ # logger.info "Processing order #{order_id}"
22
+ # logger.debug({ order_details: order.attributes })
23
+ # end
24
+ # end
25
+ #
26
+ # @example Sample raw output
27
+ # "Processing order 12345"
28
+ # {:order_details=>{:id=>12345, :status=>"pending"}}
29
+ #
30
+ # @see CMDx::LogFormatters::Line For structured log formatting with metadata
31
+ # @see CMDx::LogFormatters::Json For JSON-formatted output
5
32
  class Raw
6
33
 
34
+ # Formats a log entry as raw message content only.
35
+ #
36
+ # Outputs only the message parameter using Ruby's inspect method,
37
+ # ignoring all other log context including severity, timestamp, and task information.
38
+ # Useful for debugging scenarios where only the message content is relevant.
39
+ #
40
+ # @param _severity [String] Log severity level (ignored)
41
+ # @param _time [Time] Timestamp when the log entry was created (ignored)
42
+ # @param _task [CMDx::Task] Task instance being logged (ignored)
43
+ # @param message [Object] Log message or data to be output
44
+ #
45
+ # @return [String] Raw message content with inspect formatting and newline terminator
46
+ #
47
+ # @example String message output
48
+ # formatter = CMDx::LogFormatters::Raw.new
49
+ # output = formatter.call("INFO", Time.now, task, "Order processed")
50
+ # # => "\"Order processed\"\n"
51
+ #
52
+ # @example Hash message output
53
+ # data = { order_id: 12345, status: "completed" }
54
+ # output = formatter.call("DEBUG", Time.now, task, data)
55
+ # # => "{:order_id=>12345, :status=>\"completed\"}\n"
56
+ #
57
+ # @example Array message output
58
+ # items = ["item1", "item2", "item3"]
59
+ # output = formatter.call("INFO", Time.now, task, items)
60
+ # # => "[\"item1\", \"item2\", \"item3\"]\n"
7
61
  def call(_severity, _time, _task, message)
8
62
  message.inspect << "\n"
9
63
  end
data/lib/cmdx/logger.rb CHANGED
@@ -1,10 +1,95 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module CMDx
4
+ # Logger configuration and setup module for CMDx tasks.
5
+ #
6
+ # The Logger module provides centralized logger configuration and initialization
7
+ # for CMDx tasks. It handles logger setup, formatter assignment, log level
8
+ # configuration, and progname assignment based on task settings.
9
+ #
10
+ # @example Basic logger usage
11
+ # class ProcessOrderTask < CMDx::Task
12
+ # def call
13
+ # logger.info "Processing order #{order_id}"
14
+ # logger.debug { "Order details: #{order.inspect}" }
15
+ # end
16
+ # end
17
+ #
18
+ # @example Task-specific logger configuration
19
+ # class ProcessOrderTask < CMDx::Task
20
+ # task_settings!(
21
+ # logger: Rails.logger,
22
+ # log_formatter: CMDx::LogFormatters::Json.new,
23
+ # log_level: Logger::INFO
24
+ # )
25
+ # end
26
+ #
27
+ # @example Global logger configuration
28
+ # CMDx.configure do |config|
29
+ # config.logger = Logger.new($stdout)
30
+ # config.log_formatter = CMDx::LogFormatters::PrettyLine.new
31
+ # config.log_level = Logger::WARN
32
+ # end
33
+ #
34
+ # @example Custom logger with specific formatter
35
+ # logger = Logger.new(STDOUT)
36
+ # logger.formatter = CMDx::LogFormatters::Logstash.new
37
+ # logger.level = Logger::DEBUG
38
+ #
39
+ # class MyTask < CMDx::Task
40
+ # task_settings!(logger: logger)
41
+ # end
42
+ #
43
+ # @see CMDx::LogFormatters Log formatting options
44
+ # @see CMDx::ResultLogger Result-specific logging functionality
45
+ # @see CMDx::Task Task logging integration
4
46
  module Logger
5
47
 
6
48
  module_function
7
49
 
50
+ # Configures and returns a logger instance for a task.
51
+ #
52
+ # Retrieves the logger from task settings and applies additional configuration
53
+ # including formatter, log level, and progname if specified in task settings.
54
+ # Returns nil if no logger is configured.
55
+ #
56
+ # @param task [CMDx::Task] The task instance to configure logging for
57
+ # @return [::Logger, nil] Configured logger instance or nil if not set
58
+ #
59
+ # @example Basic logger retrieval
60
+ # task = ProcessOrderTask.new
61
+ # logger = Logger.call(task)
62
+ # logger.info "Task started" if logger
63
+ #
64
+ # @example Logger with custom formatter
65
+ # class MyTask < CMDx::Task
66
+ # task_settings!(
67
+ # logger: Logger.new(STDOUT),
68
+ # log_formatter: CMDx::LogFormatters::Json.new
69
+ # )
70
+ # end
71
+ #
72
+ # task = MyTask.new
73
+ # logger = Logger.call(task) # Logger with JSON formatter applied
74
+ #
75
+ # @example Logger with custom level
76
+ # class MyTask < CMDx::Task
77
+ # task_settings!(
78
+ # logger: Logger.new(STDOUT),
79
+ # log_level: Logger::DEBUG
80
+ # )
81
+ # end
82
+ #
83
+ # task = MyTask.new
84
+ # logger = Logger.call(task) # Logger with DEBUG level applied
85
+ #
86
+ # @example No logger configured
87
+ # class MyTask < CMDx::Task
88
+ # # No logger setting
89
+ # end
90
+ #
91
+ # task = MyTask.new
92
+ # logger = Logger.call(task) # => nil
8
93
  def call(task)
9
94
  logger = task.task_setting(:logger)
10
95