cmdx 0.5.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.
- checksums.yaml +4 -4
- data/.DS_Store +0 -0
- data/.cursor/rules/cursor-instructions.mdc +6 -0
- data/.rubocop.yml +16 -1
- data/.ruby-version +1 -1
- data/CHANGELOG.md +31 -1
- data/README.md +72 -25
- data/docs/ai_prompts.md +309 -0
- data/docs/basics/call.md +225 -14
- data/docs/basics/chain.md +271 -0
- data/docs/basics/context.md +232 -33
- data/docs/basics/setup.md +76 -12
- data/docs/callbacks.md +273 -0
- data/docs/configuration.md +158 -28
- data/docs/getting_started.md +134 -22
- data/docs/interruptions/exceptions.md +189 -11
- data/docs/interruptions/faults.md +187 -44
- data/docs/interruptions/halt.md +179 -35
- data/docs/logging.md +194 -53
- data/docs/middlewares.md +735 -0
- data/docs/outcomes/result.md +296 -10
- data/docs/outcomes/states.md +203 -31
- data/docs/outcomes/statuses.md +275 -30
- data/docs/parameters/coercions.md +402 -29
- data/docs/parameters/defaults.md +249 -25
- data/docs/parameters/definitions.md +238 -72
- data/docs/parameters/namespacing.md +250 -27
- data/docs/parameters/validations.md +193 -168
- data/docs/testing.md +550 -0
- data/docs/tips_and_tricks.md +95 -43
- data/docs/workflows.md +319 -0
- data/lib/cmdx/.DS_Store +0 -0
- data/lib/cmdx/callback.rb +69 -0
- data/lib/cmdx/callback_registry.rb +106 -0
- data/lib/cmdx/chain.rb +190 -0
- data/lib/cmdx/chain_inspector.rb +149 -0
- data/lib/cmdx/chain_serializer.rb +175 -0
- data/lib/cmdx/coercions/array.rb +37 -0
- data/lib/cmdx/coercions/big_decimal.rb +33 -0
- data/lib/cmdx/coercions/boolean.rb +41 -1
- data/lib/cmdx/coercions/complex.rb +31 -0
- data/lib/cmdx/coercions/date.rb +39 -0
- data/lib/cmdx/coercions/date_time.rb +39 -0
- data/lib/cmdx/coercions/float.rb +31 -0
- data/lib/cmdx/coercions/hash.rb +42 -0
- data/lib/cmdx/coercions/integer.rb +32 -0
- data/lib/cmdx/coercions/rational.rb +31 -0
- data/lib/cmdx/coercions/string.rb +31 -0
- data/lib/cmdx/coercions/time.rb +39 -0
- data/lib/cmdx/coercions/virtual.rb +31 -0
- data/lib/cmdx/configuration.rb +217 -9
- data/lib/cmdx/context.rb +173 -2
- data/lib/cmdx/core_ext/hash.rb +72 -0
- data/lib/cmdx/core_ext/module.rb +94 -0
- data/lib/cmdx/core_ext/object.rb +105 -0
- data/lib/cmdx/correlator.rb +217 -0
- data/lib/cmdx/error.rb +210 -8
- data/lib/cmdx/errors.rb +256 -1
- data/lib/cmdx/fault.rb +177 -2
- data/lib/cmdx/faults.rb +158 -2
- data/lib/cmdx/immutator.rb +121 -2
- data/lib/cmdx/lazy_struct.rb +261 -18
- data/lib/cmdx/log_formatters/json.rb +46 -0
- data/lib/cmdx/log_formatters/key_value.rb +46 -0
- data/lib/cmdx/log_formatters/line.rb +54 -0
- data/lib/cmdx/log_formatters/logstash.rb +64 -0
- data/lib/cmdx/log_formatters/pretty_json.rb +57 -0
- data/lib/cmdx/log_formatters/pretty_key_value.rb +51 -0
- data/lib/cmdx/log_formatters/pretty_line.rb +60 -0
- data/lib/cmdx/log_formatters/raw.rb +54 -0
- data/lib/cmdx/logger.rb +85 -0
- data/lib/cmdx/logger_ansi.rb +93 -7
- data/lib/cmdx/logger_serializer.rb +116 -0
- data/lib/cmdx/middleware.rb +74 -0
- data/lib/cmdx/middleware_registry.rb +106 -0
- data/lib/cmdx/middlewares/correlate.rb +266 -0
- data/lib/cmdx/middlewares/timeout.rb +232 -0
- data/lib/cmdx/parameter.rb +228 -1
- data/lib/cmdx/parameter_inspector.rb +61 -0
- data/lib/cmdx/parameter_registry.rb +125 -0
- data/lib/cmdx/parameter_serializer.rb +83 -0
- data/lib/cmdx/parameter_validator.rb +62 -0
- data/lib/cmdx/parameter_value.rb +109 -1
- data/lib/cmdx/parameters_inspector.rb +59 -0
- data/lib/cmdx/parameters_serializer.rb +102 -0
- data/lib/cmdx/railtie.rb +123 -3
- data/lib/cmdx/result.rb +367 -25
- data/lib/cmdx/result_ansi.rb +105 -9
- data/lib/cmdx/result_inspector.rb +76 -0
- data/lib/cmdx/result_logger.rb +90 -3
- data/lib/cmdx/result_serializer.rb +137 -0
- data/lib/cmdx/rspec/result_matchers.rb +917 -0
- data/lib/cmdx/rspec/task_matchers.rb +570 -0
- data/lib/cmdx/task.rb +405 -37
- data/lib/cmdx/task_serializer.rb +74 -2
- data/lib/cmdx/utils/ansi_color.rb +95 -0
- data/lib/cmdx/utils/log_timestamp.rb +48 -0
- data/lib/cmdx/utils/monotonic_runtime.rb +71 -4
- data/lib/cmdx/utils/name_affix.rb +78 -0
- data/lib/cmdx/validators/custom.rb +82 -0
- data/lib/cmdx/validators/exclusion.rb +94 -0
- data/lib/cmdx/validators/format.rb +102 -8
- data/lib/cmdx/validators/inclusion.rb +104 -0
- data/lib/cmdx/validators/length.rb +128 -0
- data/lib/cmdx/validators/numeric.rb +128 -0
- data/lib/cmdx/validators/presence.rb +93 -7
- data/lib/cmdx/version.rb +7 -1
- data/lib/cmdx/workflow.rb +394 -0
- data/lib/cmdx.rb +25 -64
- data/lib/generators/cmdx/install_generator.rb +37 -1
- data/lib/generators/cmdx/task_generator.rb +69 -1
- data/lib/generators/cmdx/templates/install.rb +8 -12
- data/lib/generators/cmdx/workflow_generator.rb +109 -0
- metadata +54 -15
- data/docs/basics/run.md +0 -34
- data/docs/batch.md +0 -53
- data/docs/example.md +0 -82
- data/docs/hooks.md +0 -62
- data/lib/cmdx/batch.rb +0 -43
- data/lib/cmdx/parameters.rb +0 -35
- data/lib/cmdx/run.rb +0 -39
- data/lib/cmdx/run_inspector.rb +0 -26
- data/lib/cmdx/run_serializer.rb +0 -20
- data/lib/cmdx/task_hook.rb +0 -18
- data/lib/generators/cmdx/batch_generator.rb +0 -30
- /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
|
|