smart_message 0.0.7 → 0.0.9
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/.gitignore +1 -0
- data/.irbrc +24 -0
- data/CHANGELOG.md +143 -0
- data/Gemfile.lock +6 -1
- data/README.md +289 -15
- data/docs/README.md +3 -1
- data/docs/addressing.md +119 -13
- data/docs/architecture.md +68 -0
- data/docs/dead_letter_queue.md +673 -0
- data/docs/dispatcher.md +87 -0
- data/docs/examples.md +59 -1
- data/docs/getting-started.md +8 -1
- data/docs/logging.md +382 -326
- data/docs/message_filtering.md +451 -0
- data/examples/01_point_to_point_orders.rb +54 -53
- data/examples/02_publish_subscribe_events.rb +14 -10
- data/examples/03_many_to_many_chat.rb +16 -8
- data/examples/04_redis_smart_home_iot.rb +20 -10
- data/examples/05_proc_handlers.rb +12 -11
- data/examples/06_custom_logger_example.rb +95 -100
- data/examples/07_error_handling_scenarios.rb +4 -2
- data/examples/08_entity_addressing_basic.rb +18 -6
- data/examples/08_entity_addressing_with_filtering.rb +27 -9
- data/examples/09_dead_letter_queue_demo.rb +559 -0
- data/examples/09_regex_filtering_microservices.rb +407 -0
- data/examples/10_header_block_configuration.rb +263 -0
- data/examples/11_global_configuration_example.rb +219 -0
- data/examples/README.md +102 -0
- data/examples/dead_letters.jsonl +12 -0
- data/examples/performance_metrics/benchmark_results_ractor_20250818_205603.json +135 -0
- data/examples/performance_metrics/benchmark_results_ractor_20250818_205831.json +135 -0
- data/examples/performance_metrics/benchmark_results_test_20250818_204942.json +130 -0
- data/examples/performance_metrics/benchmark_results_threadpool_20250818_204942.json +130 -0
- data/examples/performance_metrics/benchmark_results_threadpool_20250818_204959.json +130 -0
- data/examples/performance_metrics/benchmark_results_threadpool_20250818_205044.json +130 -0
- data/examples/performance_metrics/benchmark_results_threadpool_20250818_205109.json +130 -0
- data/examples/performance_metrics/benchmark_results_threadpool_20250818_205252.json +130 -0
- data/examples/performance_metrics/benchmark_results_unknown_20250819_172852.json +130 -0
- data/examples/performance_metrics/compare_benchmarks.rb +519 -0
- data/examples/performance_metrics/dead_letters.jsonl +3100 -0
- data/examples/performance_metrics/performance_benchmark.rb +344 -0
- data/examples/show_logger.rb +367 -0
- data/examples/show_me.rb +145 -0
- data/examples/temp.txt +94 -0
- data/examples/tmux_chat/bot_agent.rb +4 -2
- data/examples/tmux_chat/human_agent.rb +4 -2
- data/examples/tmux_chat/room_monitor.rb +4 -2
- data/examples/tmux_chat/shared_chat_system.rb +6 -3
- data/lib/smart_message/addressing.rb +259 -0
- data/lib/smart_message/base.rb +121 -599
- data/lib/smart_message/circuit_breaker.rb +23 -6
- data/lib/smart_message/configuration.rb +199 -0
- data/lib/smart_message/dead_letter_queue.rb +361 -0
- data/lib/smart_message/dispatcher.rb +90 -49
- data/lib/smart_message/header.rb +5 -0
- data/lib/smart_message/logger/base.rb +21 -1
- data/lib/smart_message/logger/default.rb +88 -138
- data/lib/smart_message/logger/lumberjack.rb +324 -0
- data/lib/smart_message/logger/null.rb +81 -0
- data/lib/smart_message/logger.rb +17 -9
- data/lib/smart_message/messaging.rb +100 -0
- data/lib/smart_message/plugins.rb +132 -0
- data/lib/smart_message/serializer/base.rb +25 -8
- data/lib/smart_message/serializer/json.rb +5 -4
- data/lib/smart_message/subscription.rb +193 -0
- data/lib/smart_message/transport/base.rb +84 -53
- data/lib/smart_message/transport/memory_transport.rb +7 -5
- data/lib/smart_message/transport/redis_transport.rb +15 -45
- data/lib/smart_message/transport/stdout_transport.rb +18 -8
- data/lib/smart_message/transport.rb +1 -34
- data/lib/smart_message/utilities.rb +142 -0
- data/lib/smart_message/version.rb +1 -1
- data/lib/smart_message/versioning.rb +85 -0
- data/lib/smart_message/wrapper.rb.bak +132 -0
- data/lib/smart_message.rb +74 -27
- data/smart_message.gemspec +3 -0
- metadata +77 -3
- data/lib/smart_message/serializer.rb +0 -10
- data/lib/smart_message/wrapper.rb +0 -43
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5f02a7e60919734663addbef7ae2b5582bc142993654ef33fe17c90e1a70d138
|
4
|
+
data.tar.gz: 50e7250d3e217faba23eb2a1d995b6edff0d9e0d7935bf2ea31602aff483a092
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7c157a60a127d4bd7a86742ccee8dff5385f11110d1449bc859742c497cc79d9a0e528dd39645d66a8e2b413602c31c4c79f73c9c560b5aacb37acc9610d3183
|
7
|
+
data.tar.gz: 31fc0e365c549326e9a9314f435d50715c4c980e7380311e19a7428638198d2ce499f8acd104381a631b2a40cd66d2deb8bb7fa3e16c59a61a443cc980698b56
|
data/.gitignore
CHANGED
data/.irbrc
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# smart_message/.irbrc
|
2
|
+
|
3
|
+
require_relative './lib/smart_message'
|
4
|
+
|
5
|
+
SmartMessage.configure do |config|
|
6
|
+
config.logger = STDOUT
|
7
|
+
config.log_level = :info
|
8
|
+
config.log_format = :text
|
9
|
+
config.log_colorize = true
|
10
|
+
end
|
11
|
+
|
12
|
+
LOG = SmartMessage.configuration.default_logger
|
13
|
+
|
14
|
+
class TheMessage < SmartMessage::Base
|
15
|
+
version 3
|
16
|
+
description "my simple message"
|
17
|
+
|
18
|
+
header do
|
19
|
+
from 'dewayne'
|
20
|
+
to 'madbomber'
|
21
|
+
end
|
22
|
+
|
23
|
+
property :data, required: true
|
24
|
+
end
|
data/CHANGELOG.md
CHANGED
@@ -6,6 +6,149 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
7
7
|
|
8
8
|
## [Unreleased]
|
9
|
+
|
10
|
+
## [0.0.9] 2025-08-20
|
11
|
+
### Added
|
12
|
+
- **Advanced Logging Configuration System**: Comprehensive logger configuration with multiple output formats and options
|
13
|
+
- New SmartMessage configuration options: `log_level`, `log_format`, `log_colorize`, `log_include_source`, `log_structured_data`, `log_options`
|
14
|
+
- Support for symbol-based log levels: `:info`, `:debug`, `:warn`, `:error`, `:fatal`
|
15
|
+
- Colorized console output with customizable color schemes using ANSI terminal colors
|
16
|
+
- File-based logging without colorization for clean log files
|
17
|
+
- JSON structured logging support with metadata inclusion
|
18
|
+
- Log rolling capabilities: size-based and date-based rolling with configurable retention
|
19
|
+
- Source location tracking for debugging (file, line number, method)
|
20
|
+
- Complete Lumberjack logger integration with SmartMessage configuration system
|
21
|
+
- New comprehensive logger demonstration: `examples/show_logger.rb`
|
22
|
+
- Application-level logger access through `SmartMessage.configuration.default_logger`
|
23
|
+
- **Transport Layer Abstraction**: Complete refactoring from legacy Broker to modern Transport architecture
|
24
|
+
- New `SmartMessage::Transport` module providing pluggable message delivery backends
|
25
|
+
- Transport registry system for dynamic plugin discovery and registration
|
26
|
+
- Base transport class with standardized interface for all implementations
|
27
|
+
- Memory, STDOUT, and Redis transport implementations with production-ready features
|
28
|
+
- File-based transport support for inter-process communication
|
29
|
+
- **Message Wrapper Architecture**: Unified message envelope system for cleaner dataflow
|
30
|
+
- New `SmartMessage::Wrapper::Base` class consolidating header and payload
|
31
|
+
- Simplified method signatures throughout message processing pipeline
|
32
|
+
- `_sm_` prefixed properties to avoid collision with user message definitions
|
33
|
+
- Support for different initialization patterns and automatic header generation
|
34
|
+
- **HeaderDSL for Configuration**: Simplified message class setup with declarative syntax
|
35
|
+
- New `SmartMessage::Addressing::HeaderDSL` providing cleaner class-level configuration
|
36
|
+
- Declarative `from`, `to`, `reply_to` methods for entity addressing
|
37
|
+
- Automatic header field configuration without boilerplate code
|
38
|
+
- **Advanced Message Filtering**: Regular expression support for flexible subscription patterns
|
39
|
+
- Regex pattern matching for `from:` and `to:` filters (e.g., `from: /^payment-.*/`)
|
40
|
+
- Array filters combining exact strings and patterns: `from: ['admin', /^system-.*/]`
|
41
|
+
- Environment-based routing patterns for dev/staging/production separation
|
42
|
+
- Service pattern routing for microservices architecture
|
43
|
+
- New example demonstrating regex filtering in microservices (`09_regex_filtering_microservices.rb`)
|
44
|
+
- **Performance Benchmarking Tools**: Comprehensive performance measurement infrastructure
|
45
|
+
- New benchmark suite comparing thread pool and Ractor implementations
|
46
|
+
- JSON-based benchmark result storage with detailed metrics
|
47
|
+
- Benchmark comparison tool for analyzing performance across runs
|
48
|
+
- Ractor-based message processing implementation for parallel execution
|
49
|
+
- **Improved Documentation Structure**: Complete documentation overhaul
|
50
|
+
- New modular documentation in `docs/` directory covering all major features
|
51
|
+
- Dedicated guides for transports, serializers, dispatcher, and filtering
|
52
|
+
- Architecture overview with component relationships
|
53
|
+
- Troubleshooting guide for common issues
|
54
|
+
- Example README with comprehensive usage patterns
|
55
|
+
|
56
|
+
### Changed
|
57
|
+
- **BREAKING: Transport API Migration**: Complete replacement of Broker with Transport
|
58
|
+
- All `broker` references must be updated to `transport`
|
59
|
+
- `SmartMessage::Broker` removed in favor of `SmartMessage::Transport`
|
60
|
+
- Transport implementations now in `lib/smart_message/transport/` directory
|
61
|
+
- Updated all examples and tests to use new transport terminology
|
62
|
+
- **Simplified Module Structure**: Cleaner separation of concerns
|
63
|
+
- Extracted addressing logic into `SmartMessage::Addressing` module
|
64
|
+
- Separated messaging functionality into `SmartMessage::Messaging` module
|
65
|
+
- Created dedicated `SmartMessage::Plugins` module for plugin management
|
66
|
+
- Moved versioning logic to `SmartMessage::Versioning` module
|
67
|
+
- Utilities consolidated in `SmartMessage::Utilities` module
|
68
|
+
- **Enhanced Error Messages**: More descriptive error handling throughout
|
69
|
+
- Improved header validation error messages with context
|
70
|
+
- Better transport registration error reporting
|
71
|
+
- Clearer serialization failure messages
|
72
|
+
|
73
|
+
### Fixed
|
74
|
+
- **Message Processing Simplification**: Removed unnecessary complexity in message wrapper
|
75
|
+
- Eliminated redundant processing steps in wrapper initialization
|
76
|
+
- Streamlined header and payload handling
|
77
|
+
- Fixed potential race conditions in concurrent message processing
|
78
|
+
- **Header Method Handling**: Improved reliability of header field access
|
79
|
+
- Fixed edge cases in header method delegation
|
80
|
+
- Ensured consistent behavior across all header field operations
|
81
|
+
- Better error messages for invalid header operations
|
82
|
+
|
83
|
+
### Enhanced
|
84
|
+
- **Developer Experience**: Significant improvements to API usability
|
85
|
+
- More intuitive transport registration and discovery
|
86
|
+
- Cleaner message class definition with HeaderDSL
|
87
|
+
- Simplified subscription syntax with powerful filtering
|
88
|
+
- Better separation between framework internals and user code
|
89
|
+
- **Testing Infrastructure**: Expanded test coverage
|
90
|
+
- New tests for transport layer abstraction
|
91
|
+
- Comprehensive filtering tests including regex patterns
|
92
|
+
- Performance benchmark test suite
|
93
|
+
- Proc handler integration tests
|
94
|
+
- **Example Programs**: Enhanced educational value
|
95
|
+
- Added performance benchmarking examples
|
96
|
+
- New regex filtering demonstration for microservices
|
97
|
+
- Dead letter queue demonstration with retry scenarios
|
98
|
+
- Updated all examples to use modern transport architecture
|
99
|
+
|
100
|
+
### Deprecated
|
101
|
+
- **Broker System**: Legacy broker implementation marked for removal
|
102
|
+
- `SmartMessage::Broker` and all subclasses deprecated
|
103
|
+
- Migration path provided through transport layer
|
104
|
+
- Broker terminology replaced with transport throughout codebase
|
105
|
+
|
106
|
+
## [0.0.8] 2025-08-19
|
107
|
+
|
108
|
+
### Added
|
109
|
+
- **File-Based Dead Letter Queue System**: Production-ready DLQ implementation with comprehensive replay capabilities
|
110
|
+
- JSON Lines (.jsonl) format for efficient message storage and retrieval
|
111
|
+
- FIFO queue operations: `enqueue`, `dequeue`, `peek`, `size`, `clear`
|
112
|
+
- Configurable file paths with automatic directory creation
|
113
|
+
- Global default instance and custom instance support for different use cases
|
114
|
+
- Comprehensive replay functionality with transport override capabilities
|
115
|
+
- Administrative tools: `statistics`, `filter_by_class`, `filter_by_error_pattern`, `export_range`
|
116
|
+
- Thread-safe operations with Mutex protection for concurrent access
|
117
|
+
- Integration with circuit breaker fallbacks for automatic failed message capture
|
118
|
+
|
119
|
+
### Fixed
|
120
|
+
- **Code Quality: Dead Letter Queue Refactoring**: Eliminated multiple code smells for improved maintainability
|
121
|
+
- **Hardcoded Serialization Assumption**: Added `payload_format` tracking with flexible deserialization supporting multiple formats
|
122
|
+
- **Incomplete Header Restoration**: Complete header field restoration including `message_class`, `published_at`, `publisher_pid`, and `version`
|
123
|
+
- **Transport Override Not Applied**: Fixed replay logic to properly apply transport overrides before message publishing
|
124
|
+
- **Repeated File Reading Patterns**: Extracted common file iteration logic into reusable `read_entries_with_filter` method
|
125
|
+
- **Test Suite: Logger State Pollution**: Fixed cross-test contamination in logger tests
|
126
|
+
- **Root Cause**: Class-level logger state persisting between tests due to shared `@@logger` variable
|
127
|
+
- **Solution**: Added explicit logger reset in "handle nil logger gracefully" test to ensure clean state
|
128
|
+
- **Result**: Full test suite now passes with 0 failures, 0 errors (151 runs, 561 assertions)
|
129
|
+
|
130
|
+
### Enhanced
|
131
|
+
- **Dead Letter Queue Reliability**: Robust error handling and graceful degradation
|
132
|
+
- Automatic fallback to JSON deserialization for unknown payload formats with warning logs
|
133
|
+
- Graceful handling of corrupted DLQ entries without breaking queue operations
|
134
|
+
- Enhanced error context capture including stack traces and retry counts
|
135
|
+
- Backward compatibility maintained for existing DLQ files and message formats
|
136
|
+
- **Circuit Breaker Integration**: Enhanced fallback mechanism with DLQ integration
|
137
|
+
- Circuit breaker fallbacks now include proper circuit name identification for debugging
|
138
|
+
- Automatic serializer format detection and storage for accurate message replay
|
139
|
+
- Seamless integration between transport circuit breakers and dead letter queue storage
|
140
|
+
- **Code Maintainability**: Eliminated code duplication and improved design patterns
|
141
|
+
- DRY principle applied to file reading operations with reusable filter methods
|
142
|
+
- Consistent error handling patterns across all DLQ operations
|
143
|
+
- Clear separation of concerns between queue operations, replay logic, and administrative functions
|
144
|
+
|
145
|
+
### Documentation
|
146
|
+
- **Dead Letter Queue Configuration**: Multiple configuration options for different deployment scenarios
|
147
|
+
- Global default configuration: `SmartMessage::DeadLetterQueue.configure_default(path)`
|
148
|
+
- Instance-level configuration with custom paths for different message types
|
149
|
+
- Environment-based configuration using ENV variables for deployment flexibility
|
150
|
+
- Per-environment path configuration for development, staging, and production
|
151
|
+
|
9
152
|
## [0.0.7] 2025-08-19
|
10
153
|
### Added
|
11
154
|
- **Production-Grade Circuit Breaker Integration**: Comprehensive reliability patterns using BreakerMachines gem
|
data/Gemfile.lock
CHANGED
@@ -1,12 +1,15 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
smart_message (0.0.
|
4
|
+
smart_message (0.0.9)
|
5
5
|
activesupport
|
6
6
|
breaker_machines
|
7
|
+
colorize
|
7
8
|
concurrent-ruby
|
8
9
|
hashie
|
10
|
+
lumberjack
|
9
11
|
redis
|
12
|
+
zeitwerk
|
10
13
|
|
11
14
|
GEM
|
12
15
|
remote: https://rubygems.org/
|
@@ -33,6 +36,7 @@ GEM
|
|
33
36
|
concurrent-ruby (~> 1.3)
|
34
37
|
state_machines (>= 0.50.0)
|
35
38
|
zeitwerk (~> 2.7)
|
39
|
+
colorize (1.1.0)
|
36
40
|
concurrent-ruby (1.3.5)
|
37
41
|
connection_pool (2.5.3)
|
38
42
|
debug_me (1.1.1)
|
@@ -41,6 +45,7 @@ GEM
|
|
41
45
|
i18n (1.14.7)
|
42
46
|
concurrent-ruby (~> 1.0)
|
43
47
|
logger (1.7.0)
|
48
|
+
lumberjack (1.4.0)
|
44
49
|
minitest (5.25.5)
|
45
50
|
minitest-power_assert (0.3.1)
|
46
51
|
minitest
|
data/README.md
CHANGED
@@ -10,15 +10,19 @@ SmartMessage is a message abstraction framework that decouples business logic fr
|
|
10
10
|
- **Transport Abstraction**: Plugin architecture supporting multiple message transports (Redis, RabbitMQ, Kafka, etc.)
|
11
11
|
- **Serialization Flexibility**: Pluggable serialization formats (JSON, MessagePack, etc.)
|
12
12
|
- **Entity-to-Entity Addressing**: Built-in FROM/TO/REPLY_TO addressing for point-to-point and broadcast messaging patterns
|
13
|
+
- **Advanced Message Filtering**: Filter subscriptions using exact strings, regular expressions, or mixed arrays for precise message routing
|
13
14
|
- **Schema Versioning**: Built-in version management with automatic compatibility validation
|
14
15
|
- **Comprehensive Validation**: Property validation with custom error messages and automatic validation before publishing
|
15
16
|
- **Message Documentation**: Built-in documentation support for message classes and properties with automatic defaults
|
16
17
|
- **Flexible Message Handlers**: Multiple subscription patterns - default methods, custom methods, blocks, procs, and lambdas
|
17
18
|
- **Dual-Level Configuration**: Class and instance-level plugin overrides for gateway patterns
|
18
19
|
- **Concurrent Processing**: Thread-safe message routing using `Concurrent::CachedThreadPool`
|
20
|
+
- **Advanced Logging System**: Comprehensive logging with colorized console output, JSON structured logging, and file rolling
|
19
21
|
- **Built-in Statistics**: Message processing metrics and monitoring
|
20
22
|
- **Development Tools**: STDOUT and in-memory transports for testing
|
21
23
|
- **Production Ready**: Redis transport with automatic reconnection and error handling
|
24
|
+
- **Dead Letter Queue**: File-based DLQ with JSON Lines format for failed message capture and replay
|
25
|
+
- **Circuit Breaker Integration**: Production-grade reliability with BreakerMachines for automatic fallback and recovery
|
22
26
|
|
23
27
|
## Installation
|
24
28
|
|
@@ -48,11 +52,18 @@ class OrderMessage < SmartMessage::Base
|
|
48
52
|
# Add a description for the message class
|
49
53
|
description "Represents customer order data for processing and fulfillment"
|
50
54
|
|
51
|
-
# Configure entity addressing
|
55
|
+
# Configure entity addressing (Method 1: Direct methods)
|
52
56
|
from 'order-service'
|
53
57
|
to 'fulfillment-service' # Point-to-point message
|
54
58
|
reply_to 'order-service' # Responses come back here
|
55
59
|
|
60
|
+
# Alternative Method 2: Using header block
|
61
|
+
# header do
|
62
|
+
# from 'order-service'
|
63
|
+
# to 'fulfillment-service'
|
64
|
+
# reply_to 'order-service'
|
65
|
+
# end
|
66
|
+
|
56
67
|
# Required properties with validation
|
57
68
|
property :order_id,
|
58
69
|
required: true,
|
@@ -159,12 +170,43 @@ end
|
|
159
170
|
OrderMessage.subscribe(audit_handler)
|
160
171
|
```
|
161
172
|
|
162
|
-
### 4.
|
173
|
+
### 4. Message Filtering (NEW!)
|
163
174
|
|
164
|
-
SmartMessage supports
|
175
|
+
SmartMessage supports powerful message filtering using exact strings, regular expressions, or arrays:
|
165
176
|
|
166
177
|
```ruby
|
167
|
-
#
|
178
|
+
# Filter by exact sender
|
179
|
+
OrderMessage.subscribe(from: 'payment-service')
|
180
|
+
|
181
|
+
# Filter by sender pattern (all payment services)
|
182
|
+
OrderMessage.subscribe(from: /^payment-.*/)
|
183
|
+
|
184
|
+
# Filter by multiple senders
|
185
|
+
OrderMessage.subscribe(from: ['admin', 'system', 'monitoring'])
|
186
|
+
|
187
|
+
# Mixed exact and pattern matching
|
188
|
+
OrderMessage.subscribe(from: ['admin', /^system-.*/, 'legacy-service'])
|
189
|
+
|
190
|
+
# Filter by recipient patterns
|
191
|
+
OrderMessage.subscribe(to: /^(dev|staging)-.*/)
|
192
|
+
|
193
|
+
# Combined filtering
|
194
|
+
OrderMessage.subscribe(
|
195
|
+
from: /^admin-.*/,
|
196
|
+
to: ['order-service', /^fulfillment-.*/]
|
197
|
+
)
|
198
|
+
|
199
|
+
# Environment-based routing
|
200
|
+
DevService.subscribe(to: /^(dev|staging)-.*/)
|
201
|
+
ProdService.subscribe(to: /^prod-.*/)
|
202
|
+
```
|
203
|
+
|
204
|
+
### 5. Entity Addressing
|
205
|
+
|
206
|
+
SmartMessage supports entity-to-entity addressing with FROM/TO/REPLY_TO fields for advanced message routing. You can configure addressing using three different approaches:
|
207
|
+
|
208
|
+
#### Method 1: Direct Class Methods
|
209
|
+
```ruby
|
168
210
|
class PaymentMessage < SmartMessage::Base
|
169
211
|
version 1
|
170
212
|
from 'payment-service' # Required: sender identity
|
@@ -174,26 +216,67 @@ class PaymentMessage < SmartMessage::Base
|
|
174
216
|
property :amount, required: true
|
175
217
|
property :account_id, required: true
|
176
218
|
end
|
219
|
+
```
|
177
220
|
|
178
|
-
|
179
|
-
|
221
|
+
#### Method 2: Header Block DSL
|
222
|
+
```ruby
|
223
|
+
class PaymentMessage < SmartMessage::Base
|
180
224
|
version 1
|
181
|
-
from 'admin-service' # Required: sender identity
|
182
|
-
# No 'to' field = broadcast to all subscribers
|
183
225
|
|
184
|
-
|
185
|
-
|
226
|
+
# Configure all addressing in a single block
|
227
|
+
header do
|
228
|
+
from 'payment-service'
|
229
|
+
to 'bank-gateway'
|
230
|
+
reply_to 'payment-service'
|
231
|
+
end
|
232
|
+
|
233
|
+
property :amount, required: true
|
234
|
+
property :account_id, required: true
|
186
235
|
end
|
236
|
+
```
|
237
|
+
|
238
|
+
#### Method 3: Instance-Level Configuration
|
239
|
+
```ruby
|
187
240
|
|
188
|
-
#
|
241
|
+
# Create payment instance
|
189
242
|
payment = PaymentMessage.new(amount: 100.00, account_id: "ACCT-123")
|
190
|
-
payment.to('backup-gateway') # Override destination for this instance
|
191
|
-
payment.publish
|
192
243
|
|
193
|
-
#
|
194
|
-
|
244
|
+
# Override addressing at instance level
|
245
|
+
payment.to('backup-gateway') # Method chaining supported
|
246
|
+
payment.from('urgent-processor')
|
247
|
+
|
248
|
+
# Alternative setter syntax
|
249
|
+
payment.from = 'urgent-processor'
|
250
|
+
payment.to = 'backup-gateway'
|
251
|
+
|
252
|
+
# Access addressing (shortcut methods)
|
253
|
+
puts payment.from # => 'urgent-processor'
|
254
|
+
puts payment.to # => 'backup-gateway'
|
255
|
+
puts payment.reply_to # => 'payment-service'
|
256
|
+
|
257
|
+
# Access via header (full path)
|
258
|
+
puts payment._sm_header.from # => 'urgent-processor'
|
195
259
|
puts payment._sm_header.to # => 'backup-gateway'
|
196
260
|
puts payment._sm_header.reply_to # => 'payment-service'
|
261
|
+
|
262
|
+
# Publish with updated addressing
|
263
|
+
payment.publish
|
264
|
+
```
|
265
|
+
|
266
|
+
#### Broadcast Messaging Example
|
267
|
+
```ruby
|
268
|
+
class SystemAnnouncementMessage < SmartMessage::Base
|
269
|
+
version 1
|
270
|
+
|
271
|
+
# Using header block for broadcast configuration
|
272
|
+
header do
|
273
|
+
from 'admin-service' # Required: sender identity
|
274
|
+
# No 'to' field = broadcast to all subscribers
|
275
|
+
end
|
276
|
+
|
277
|
+
property :message, required: true
|
278
|
+
property :priority, default: 'normal'
|
279
|
+
end
|
197
280
|
```
|
198
281
|
|
199
282
|
#### Messaging Patterns Supported
|
@@ -203,6 +286,104 @@ puts payment._sm_header.reply_to # => 'payment-service'
|
|
203
286
|
- **Request-Reply**: Use `reply_to` field to specify response routing
|
204
287
|
- **Gateway Patterns**: Override addressing at instance level for message forwarding
|
205
288
|
|
289
|
+
## Logging Configuration
|
290
|
+
|
291
|
+
SmartMessage includes a comprehensive logging system with support for multiple output formats, colorization, and file rolling capabilities.
|
292
|
+
|
293
|
+
### Basic Logging Configuration
|
294
|
+
|
295
|
+
```ruby
|
296
|
+
# Configure SmartMessage logging
|
297
|
+
SmartMessage.configure do |config|
|
298
|
+
config.logger = STDOUT # Output destination (file path, STDOUT, STDERR)
|
299
|
+
config.log_level = :info # Log level (:debug, :info, :warn, :error, :fatal)
|
300
|
+
config.log_format = :text # Output format (:text, :json)
|
301
|
+
config.log_colorize = true # Enable colorized console output
|
302
|
+
config.log_include_source = false # Include source file/line information
|
303
|
+
config.log_structured_data = false # Enable structured data logging
|
304
|
+
end
|
305
|
+
|
306
|
+
# Access the configured logger in your application
|
307
|
+
logger = SmartMessage.configuration.default_logger
|
308
|
+
logger.info("Application started", component: "main", pid: Process.pid)
|
309
|
+
```
|
310
|
+
|
311
|
+
### Advanced Logging Features
|
312
|
+
|
313
|
+
#### Colorized Console Output
|
314
|
+
```ruby
|
315
|
+
SmartMessage.configure do |config|
|
316
|
+
config.logger = STDOUT
|
317
|
+
config.log_colorize = true
|
318
|
+
config.log_format = :text
|
319
|
+
end
|
320
|
+
|
321
|
+
logger = SmartMessage.configuration.default_logger
|
322
|
+
logger.debug("Debug message") # Green background, white text
|
323
|
+
logger.info("Info message") # White text
|
324
|
+
logger.warn("Warning message") # Yellow background, white bold text
|
325
|
+
logger.error("Error message") # Light red background, white bold text
|
326
|
+
logger.fatal("Fatal message") # Light red background, yellow bold text
|
327
|
+
```
|
328
|
+
|
329
|
+
#### JSON Structured Logging
|
330
|
+
```ruby
|
331
|
+
SmartMessage.configure do |config|
|
332
|
+
config.logger = "log/application.log"
|
333
|
+
config.log_format = :json
|
334
|
+
config.log_structured_data = true
|
335
|
+
config.log_include_source = true
|
336
|
+
end
|
337
|
+
|
338
|
+
logger = SmartMessage.configuration.default_logger
|
339
|
+
logger.info("User action",
|
340
|
+
user_id: 12345,
|
341
|
+
action: "login",
|
342
|
+
ip_address: "192.168.1.1")
|
343
|
+
# Output: {"timestamp":"2025-01-15T10:30:45.123Z","level":"INFO","message":"User action","user_id":12345,"action":"login","ip_address":"192.168.1.1","source":"app.rb:42:in `authenticate`"}
|
344
|
+
```
|
345
|
+
|
346
|
+
#### File Rolling Configuration
|
347
|
+
```ruby
|
348
|
+
SmartMessage.configure do |config|
|
349
|
+
config.logger = "log/application.log"
|
350
|
+
config.log_options = {
|
351
|
+
# Size-based rolling
|
352
|
+
roll_by_size: true,
|
353
|
+
max_file_size: 10 * 1024 * 1024, # 10 MB
|
354
|
+
keep_files: 5, # Keep 5 old files
|
355
|
+
|
356
|
+
# Date-based rolling (alternative to size-based)
|
357
|
+
roll_by_date: false, # Set to true for date-based
|
358
|
+
date_pattern: '%Y-%m-%d' # Daily rolling pattern
|
359
|
+
}
|
360
|
+
end
|
361
|
+
```
|
362
|
+
|
363
|
+
### SmartMessage Integration
|
364
|
+
|
365
|
+
SmartMessage classes automatically use the configured logger:
|
366
|
+
|
367
|
+
```ruby
|
368
|
+
class OrderMessage < SmartMessage::Base
|
369
|
+
property :order_id, required: true
|
370
|
+
property :amount, required: true
|
371
|
+
|
372
|
+
def process
|
373
|
+
# Logger is automatically available
|
374
|
+
logger.info("Processing order",
|
375
|
+
order_id: order_id,
|
376
|
+
amount: amount,
|
377
|
+
header: _sm_header.to_h,
|
378
|
+
payload: _sm_payload)
|
379
|
+
end
|
380
|
+
end
|
381
|
+
|
382
|
+
# Messages inherit the global logger configuration
|
383
|
+
message = OrderMessage.new(order_id: "123", amount: 99.99)
|
384
|
+
message.publish # Uses configured logger for any internal logging
|
385
|
+
```
|
386
|
+
|
206
387
|
## Architecture
|
207
388
|
|
208
389
|
### Core Components
|
@@ -644,6 +825,99 @@ puts message._sm_header.to
|
|
644
825
|
puts message._sm_header.reply_to
|
645
826
|
```
|
646
827
|
|
828
|
+
### Dead Letter Queue
|
829
|
+
|
830
|
+
SmartMessage includes a comprehensive file-based Dead Letter Queue system for handling failed messages:
|
831
|
+
|
832
|
+
```ruby
|
833
|
+
# Configure global DLQ (optional - defaults to 'dead_letters.jsonl')
|
834
|
+
SmartMessage::DeadLetterQueue.configure_default('/var/log/app/dlq.jsonl')
|
835
|
+
|
836
|
+
# Or use environment-based configuration
|
837
|
+
SmartMessage::DeadLetterQueue.configure_default(
|
838
|
+
ENV.fetch('SMART_MESSAGE_DLQ_PATH', 'dead_letters.jsonl')
|
839
|
+
)
|
840
|
+
|
841
|
+
# Access the default DLQ instance
|
842
|
+
dlq = SmartMessage::DeadLetterQueue.default
|
843
|
+
|
844
|
+
# Create a custom DLQ instance for specific needs
|
845
|
+
custom_dlq = SmartMessage::DeadLetterQueue.new('/tmp/critical_failures.jsonl')
|
846
|
+
```
|
847
|
+
|
848
|
+
#### DLQ Operations
|
849
|
+
|
850
|
+
```ruby
|
851
|
+
# Messages are automatically captured when circuit breakers trip
|
852
|
+
# But you can also manually enqueue failed messages:
|
853
|
+
dlq.enqueue(
|
854
|
+
message._sm_header,
|
855
|
+
message_payload,
|
856
|
+
error: "Connection timeout",
|
857
|
+
transport: "Redis",
|
858
|
+
retry_count: 3
|
859
|
+
)
|
860
|
+
|
861
|
+
# Inspect queue status
|
862
|
+
puts "Queue size: #{dlq.size}"
|
863
|
+
puts "Next message: #{dlq.peek}" # Look without removing
|
864
|
+
|
865
|
+
# Get statistics
|
866
|
+
stats = dlq.statistics
|
867
|
+
puts "Total messages: #{stats[:total]}"
|
868
|
+
puts "By error type: #{stats[:by_error]}"
|
869
|
+
puts "By message class: #{stats[:by_class]}"
|
870
|
+
```
|
871
|
+
|
872
|
+
#### Message Replay
|
873
|
+
|
874
|
+
```ruby
|
875
|
+
# Replay messages back through their original transport
|
876
|
+
dlq.replay_one # Replay oldest message
|
877
|
+
dlq.replay_batch(10) # Replay next 10 messages
|
878
|
+
dlq.replay_all # Replay entire queue
|
879
|
+
|
880
|
+
# Replay with a different transport
|
881
|
+
redis_transport = SmartMessage::Transport.create(:redis)
|
882
|
+
dlq.replay_one(redis_transport) # Override original transport
|
883
|
+
```
|
884
|
+
|
885
|
+
#### Administrative Functions
|
886
|
+
|
887
|
+
```ruby
|
888
|
+
# Filter messages for analysis
|
889
|
+
failed_orders = dlq.filter_by_class('OrderMessage')
|
890
|
+
timeout_errors = dlq.filter_by_error_pattern(/timeout/i)
|
891
|
+
|
892
|
+
# Export messages within a time range
|
893
|
+
yesterday = Time.now - 86400
|
894
|
+
today = Time.now
|
895
|
+
recent_failures = dlq.export_range(yesterday, today)
|
896
|
+
|
897
|
+
# Clear the queue when needed
|
898
|
+
dlq.clear # Remove all messages
|
899
|
+
```
|
900
|
+
|
901
|
+
#### Integration with Circuit Breakers
|
902
|
+
|
903
|
+
Dead Letter Queue is automatically integrated with circuit breakers:
|
904
|
+
|
905
|
+
```ruby
|
906
|
+
class PaymentMessage < SmartMessage::Base
|
907
|
+
config do
|
908
|
+
transport SmartMessage::Transport.create(:redis)
|
909
|
+
# Messages automatically go to DLQ when circuit breaker trips
|
910
|
+
end
|
911
|
+
end
|
912
|
+
|
913
|
+
# Monitor circuit breaker status
|
914
|
+
transport = PaymentMessage.transport
|
915
|
+
stats = transport.transport_circuit_stats
|
916
|
+
if stats[:transport_publish][:open]
|
917
|
+
puts "Circuit open - messages going to DLQ"
|
918
|
+
end
|
919
|
+
```
|
920
|
+
|
647
921
|
## Development
|
648
922
|
|
649
923
|
After checking out the repo, run:
|
data/docs/README.md
CHANGED
@@ -17,11 +17,13 @@ Welcome to the comprehensive documentation for SmartMessage, a Ruby gem that abs
|
|
17
17
|
- [SmartMessage::Base](base.md)
|
18
18
|
- [Property System](properties.md)
|
19
19
|
- [Entity Addressing](addressing.md)
|
20
|
+
- [Message Filtering](message_filtering.md)
|
20
21
|
- [Transport Layer](transports.md)
|
21
22
|
- [Serializers](serializers.md)
|
22
23
|
- [Logging System](logging.md)
|
23
24
|
- [Dispatcher & Routing](dispatcher.md)
|
24
25
|
- [Message Headers](headers.md)
|
26
|
+
- [Dead Letter Queue](dead_letter_queue.md)
|
25
27
|
|
26
28
|
### Advanced Topics
|
27
29
|
- [Custom Transports](custom-transports.md)
|
@@ -50,6 +52,6 @@ Welcome to the comprehensive documentation for SmartMessage, a Ruby gem that abs
|
|
50
52
|
|
51
53
|
## Version
|
52
54
|
|
53
|
-
This documentation is for SmartMessage v0.0.
|
55
|
+
This documentation is for SmartMessage v0.0.8.
|
54
56
|
|
55
57
|
For older versions, please check the git tags and corresponding documentation.
|