rmq-healer 0.1.0__tar.gz

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 (37) hide show
  1. rmq_healer-0.1.0/LICENSE +21 -0
  2. rmq_healer-0.1.0/PKG-INFO +283 -0
  3. rmq_healer-0.1.0/README.md +225 -0
  4. rmq_healer-0.1.0/pyproject.toml +71 -0
  5. rmq_healer-0.1.0/rmq_healer/__init__.py +3 -0
  6. rmq_healer-0.1.0/rmq_healer/actions/__init__.py +137 -0
  7. rmq_healer-0.1.0/rmq_healer/actions/base.py +31 -0
  8. rmq_healer-0.1.0/rmq_healer/actions/drop_or_ack_with_audit.py +28 -0
  9. rmq_healer-0.1.0/rmq_healer/actions/log.py +24 -0
  10. rmq_healer-0.1.0/rmq_healer/actions/mutate_json.py +108 -0
  11. rmq_healer-0.1.0/rmq_healer/actions/python_script.py +126 -0
  12. rmq_healer-0.1.0/rmq_healer/actions/quarantine.py +52 -0
  13. rmq_healer-0.1.0/rmq_healer/actions/republish.py +48 -0
  14. rmq_healer-0.1.0/rmq_healer/actions/route_unknown.py +51 -0
  15. rmq_healer-0.1.0/rmq_healer/actions/set_headers.py +27 -0
  16. rmq_healer-0.1.0/rmq_healer/audit.py +97 -0
  17. rmq_healer-0.1.0/rmq_healer/classifier.py +110 -0
  18. rmq_healer-0.1.0/rmq_healer/config.py +210 -0
  19. rmq_healer-0.1.0/rmq_healer/exceptions.py +19 -0
  20. rmq_healer-0.1.0/rmq_healer/main.py +1254 -0
  21. rmq_healer-0.1.0/rmq_healer/message.py +89 -0
  22. rmq_healer-0.1.0/rmq_healer/metrics.py +184 -0
  23. rmq_healer-0.1.0/rmq_healer/pretty.py +280 -0
  24. rmq_healer-0.1.0/rmq_healer/rabbit.py +198 -0
  25. rmq_healer-0.1.0/rmq_healer/templating.py +36 -0
  26. rmq_healer-0.1.0/rmq_healer/workflow.py +60 -0
  27. rmq_healer-0.1.0/rmq_healer/workflow_context.py +46 -0
  28. rmq_healer-0.1.0/rmq_healer.egg-info/PKG-INFO +283 -0
  29. rmq_healer-0.1.0/rmq_healer.egg-info/SOURCES.txt +35 -0
  30. rmq_healer-0.1.0/rmq_healer.egg-info/dependency_links.txt +1 -0
  31. rmq_healer-0.1.0/rmq_healer.egg-info/entry_points.txt +2 -0
  32. rmq_healer-0.1.0/rmq_healer.egg-info/requires.txt +18 -0
  33. rmq_healer-0.1.0/rmq_healer.egg-info/top_level.txt +1 -0
  34. rmq_healer-0.1.0/setup.cfg +4 -0
  35. rmq_healer-0.1.0/tests/test_classifier.py +167 -0
  36. rmq_healer-0.1.0/tests/test_config.py +106 -0
  37. rmq_healer-0.1.0/tests/test_workflow.py +141 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 grimnexo
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,283 @@
1
+ Metadata-Version: 2.4
2
+ Name: rmq-healer
3
+ Version: 0.1.0
4
+ Summary: Abstract, extensible RabbitMQ error-queue remediation tool
5
+ License: MIT License
6
+
7
+ Copyright (c) 2026 grimnexo
8
+
9
+ Permission is hereby granted, free of charge, to any person obtaining a copy
10
+ of this software and associated documentation files (the "Software"), to deal
11
+ in the Software without restriction, including without limitation the rights
12
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13
+ copies of the Software, and to permit persons to whom the Software is
14
+ furnished to do so, subject to the following conditions:
15
+
16
+ The above copyright notice and this permission notice shall be included in all
17
+ copies or substantial portions of the Software.
18
+
19
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25
+ SOFTWARE.
26
+
27
+ Classifier: Development Status :: 4 - Beta
28
+ Classifier: Environment :: Console
29
+ Classifier: Intended Audience :: Developers
30
+ Classifier: Intended Audience :: System Administrators
31
+ Classifier: License :: OSI Approved :: MIT License
32
+ Classifier: Programming Language :: Python :: 3
33
+ Classifier: Programming Language :: Python :: 3.11
34
+ Classifier: Programming Language :: Python :: 3.12
35
+ Classifier: Programming Language :: Python :: 3.13
36
+ Classifier: Topic :: System :: Monitoring
37
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
38
+ Requires-Python: >=3.11
39
+ Description-Content-Type: text/markdown
40
+ License-File: LICENSE
41
+ Requires-Dist: pika>=1.3
42
+ Requires-Dist: pydantic>=2.0
43
+ Requires-Dist: pydantic-settings>=2.0
44
+ Requires-Dist: PyYAML>=6.0
45
+ Requires-Dist: jsonpath-ng>=1.6
46
+ Requires-Dist: Jinja2>=3.1
47
+ Requires-Dist: click>=8.1
48
+ Provides-Extra: dev
49
+ Requires-Dist: pytest>=8.0; extra == "dev"
50
+ Requires-Dist: pytest-cov; extra == "dev"
51
+ Requires-Dist: ruff>=0.4; extra == "dev"
52
+ Requires-Dist: mypy>=1.8; extra == "dev"
53
+ Requires-Dist: types-PyYAML; extra == "dev"
54
+ Requires-Dist: types-pika; extra == "dev"
55
+ Provides-Extra: metrics
56
+ Requires-Dist: prometheus-client>=0.19; extra == "metrics"
57
+ Dynamic: license-file
58
+
59
+ <p align="center">
60
+ <img src="assets/img/rmq-healer-gh-banner.png" alt="RMQ Healer" width="100%"/>
61
+ </p>
62
+
63
+ <p align="center">
64
+ <img src="assets/img/rmq-healer-logo.png" alt="RMQ Healer Logo" width="180"/>
65
+ </p>
66
+
67
+ <p align="center">
68
+ <strong>Abstract, extensible RabbitMQ error-queue remediation.</strong><br/>
69
+ Classify &rarr; remediate &rarr; audit &mdash; fully configurable, no code required for common cases.
70
+ </p>
71
+
72
+ <p align="center">
73
+ <img alt="Python" src="https://img.shields.io/badge/python-3.11%2B-blue?logo=python&logoColor=white"/>
74
+ <img alt="License" src="https://img.shields.io/badge/license-MIT-green"/>
75
+ <img alt="CI" src="https://github.com/grimnexo/RMQ-Healer/actions/workflows/ci.yml/badge.svg"/>
76
+ <img alt="Coverage" src="https://img.shields.io/codecov/c/github/grimnexo/RMQ-Healer?logo=codecov"/>
77
+ <img alt="PyPI" src="https://img.shields.io/pypi/v/rmq-healer?logo=pypi&logoColor=white"/>
78
+ <img alt="Docker" src="https://img.shields.io/docker/pulls/grimnexo/rmq-healer?logo=docker"/>
79
+ <img alt="Code style" src="https://img.shields.io/badge/code%20style-ruff-orange?logo=python"/>
80
+ </p>
81
+
82
+ ---
83
+
84
+ ## What Is It?
85
+
86
+ RMQ Healer watches RabbitMQ error queues and **automatically remediates known failure patterns** without touching your application code. You write YAML rules; the healer classifies every message and runs the matching workflow.
87
+
88
+ ### Core Features
89
+
90
+ | | Feature |
91
+ |---|---|
92
+ | **Zero-loss processing** | Messages are acked *only* after a terminal action succeeds. If anything fails the message stays in the queue — untouched. |
93
+ | **Declarative rules** | YAML rule files with nested boolean logic: `body_contains`, `json_path`, `header_equals`, `property_equals`, and combinators (`all`/`any`/`not`). |
94
+ | **Rich workflow engine** | `log`, `mutate_json`, `set_headers`, `python_script`, `republish`, `quarantine`, `route_unknown`, `drop`. |
95
+ | **Jinja2 templating** | Every action param is a Jinja2 template — reference headers, body fields, script outputs, queue config. |
96
+ | **Python script plugins** | Drop any Python script in; it receives full message context on stdin and returns a JSON decision on stdout. |
97
+ | **Idempotency guard** | Bump-and-quarantine: after N failed runs the message is quarantined automatically. |
98
+ | **Structured audit log** | JSON-lines output — pipe straight to Fluentd, Loki, or CloudWatch. |
99
+ | **Non-destructive peek** | Inspect queue contents without consuming — broker requeues automatically after peek. |
100
+ | **Graceful shutdown** | SIGTERM/SIGINT safe — finishes the current message before stopping. |
101
+ | **Developer GUI** | PyQt6 desktop app for editing configs, viewing chains, peeking live queues, and browsing audit logs. |
102
+ | **Plugin architecture** | Register custom actions via Python `entry_points` or a local `plugins/` directory. |
103
+ | **Prometheus metrics** | Optional `prometheus_client` integration — zero-overhead when not installed. |
104
+ | **Dry-run with diffs** | See exactly what `mutate_json` would change before committing. |
105
+
106
+ ---
107
+
108
+ ## Architecture
109
+
110
+ ```mermaid
111
+ flowchart TD
112
+ EQ[("Error Queue")]
113
+ CL["Classifier\n(first match wins)"]
114
+ WF["WorkflowRunner"]
115
+ AU["AuditLogger\n(JSON-lines)"]
116
+
117
+ EQ -->|basic_get| CL
118
+ CL -->|matched rule| WF
119
+ CL -->|no match| UQ[("Unknown Queue")]
120
+ WF --> A1["log / set_headers\nmutate_json / python_script"]
121
+ A1 --> T{"Terminal\naction"}
122
+ T -->|republish| RQ[("Repaired Queue")]
123
+ T -->|quarantine| Q[("Quarantine Queue")]
124
+ T -->|route_unknown| UQ
125
+ T -->|drop| DONE["Ack + discard"]
126
+ WF --> AU
127
+ CL --> AU
128
+ ```
129
+
130
+ ---
131
+
132
+ ## Quick Start
133
+
134
+ ```bash
135
+ # 1. Install
136
+ pip install -e ".[dev]"
137
+
138
+ # 2. Set broker URL
139
+ export RMQ_URL="amqp://guest:guest@localhost/"
140
+
141
+ # 3. Generate config interactively
142
+ rmq-healer configure --output config/queues.yml
143
+
144
+ # 4. Validate
145
+ rmq-healer validate --config config/queues.yml
146
+
147
+ # 5. Test a rule against a sample message
148
+ rmq-healer test-rule --config config/queues.yml \
149
+ --queue order-service.error --message examples/retry-timeout/sample.json
150
+
151
+ # 6. Dry-run with mutation diffs — nothing acked or published
152
+ rmq-healer dry-run --config config/queues.yml --all --pretty
153
+
154
+ # 7. Live run
155
+ rmq-healer run --config config/queues.yml --all --pretty
156
+
157
+ # 8. Peek without consuming
158
+ rmq-healer peek --config config/queues.yml --queue order-service.error --count 10
159
+
160
+ # 9. Visualise a workflow as a Mermaid diagram
161
+ rmq-healer workflow render --config config/queues.yml --queue order-service.error
162
+
163
+ # 10. Search audit logs
164
+ rmq-healer audit-search --log audit.jsonl --outcome quarantine
165
+ ```
166
+
167
+ ---
168
+
169
+ ## Example Configuration
170
+
171
+ ```yaml
172
+ rabbitmq:
173
+ url: "${RMQ_URL}"
174
+ prefetch: 10
175
+
176
+ idempotency:
177
+ enabled: true
178
+ max_handler_attempts: 3
179
+
180
+ queues:
181
+ - name: order-service.error
182
+ enabled: true
183
+ rules_file: rules/order-errors.yml
184
+ repaired_exchange: order.events
185
+ repaired_routing_key: order.retry
186
+ quarantine_exchange: ops.errors
187
+ quarantine_routing_key: order.quarantine
188
+ ```
189
+
190
+ ```yaml
191
+ # rules/order-errors.yml
192
+ rules:
193
+ - id: transient_timeout
194
+ match:
195
+ any:
196
+ - body_contains: "ETIMEDOUT"
197
+ - json_path: $.error.code
198
+ equals: "TIMEOUT"
199
+ workflow:
200
+ - action: set_headers
201
+ params:
202
+ headers:
203
+ x-rmq-healer-rule: transient_timeout
204
+ - action: republish
205
+ params:
206
+ exchange: "{{ queue.repaired_exchange }}"
207
+ routing_key: "{{ queue.repaired_routing_key }}"
208
+
209
+ - id: missing_customer_id
210
+ match:
211
+ all:
212
+ - json_path: $.customer_id
213
+ equals: null
214
+ workflow:
215
+ - action: python_script
216
+ params:
217
+ script: scripts/lookup_customer.py
218
+ timeout: 30
219
+ output:
220
+ save_as: customer
221
+ - action: mutate_json
222
+ params:
223
+ set:
224
+ "$.customer_id": "{{ customer.id }}"
225
+ - action: republish
226
+ params:
227
+ exchange: "{{ queue.repaired_exchange }}"
228
+ routing_key: "{{ queue.repaired_routing_key }}"
229
+ ```
230
+
231
+ See the `examples/` directory for complete, runnable scenarios.
232
+
233
+ ---
234
+
235
+ ## Documentation
236
+
237
+ | Topic | Guide |
238
+ |---|---|
239
+ | Installation & setup | [docs/installation.md](docs/installation.md) |
240
+ | Configuration reference | [docs/configuration.md](docs/configuration.md) |
241
+ | Writing rules | [docs/rules.md](docs/rules.md) |
242
+ | Python script actions | [docs/python-scripts.md](docs/python-scripts.md) |
243
+ | CLI reference (all commands) | [docs/cli-reference.md](docs/cli-reference.md) |
244
+ | Operations guide | [docs/operations.md](docs/operations.md) |
245
+ | Docker deployment | [docs/docker.md](docs/docker.md) |
246
+ | Developer GUI | [docs/developer-gui.md](docs/developer-gui.md) |
247
+ | Plugin architecture | [docs/plugins.md](docs/plugins.md) |
248
+ | Metrics & observability | [docs/metrics.md](docs/metrics.md) |
249
+ | Contributing & tooling | [docs/contributing.md](docs/contributing.md) |
250
+ | Troubleshooting | [docs/troubleshooting.md](docs/troubleshooting.md) |
251
+
252
+ > **[Browse all docs &rarr;](docs/README.md)**
253
+
254
+ ---
255
+
256
+ ## Developer Environment
257
+
258
+ ```powershell
259
+ # Windows
260
+ .\developer\scripts\setup.ps1 # start RabbitMQ + seed fixtures
261
+ .\developer\scripts\run-test.ps1 # dry-run
262
+ .\developer\scripts\launch-gui.ps1 # open GUI
263
+ .\developer\scripts\teardown.ps1 # stop
264
+ ```
265
+
266
+ ```bash
267
+ # Linux / macOS
268
+ bash developer/scripts/setup.sh
269
+ bash developer/scripts/run-test.sh
270
+ bash developer/scripts/launch-gui.sh
271
+ bash developer/scripts/teardown.sh
272
+
273
+ # Or cross-platform Python
274
+ python developer/scripts/dev_setup.py
275
+ python developer/scripts/run_test.py
276
+ python developer/scripts/launch_gui.py
277
+ ```
278
+
279
+ ---
280
+
281
+ ## License
282
+
283
+ MIT &mdash; see [LICENSE](LICENSE).
@@ -0,0 +1,225 @@
1
+ <p align="center">
2
+ <img src="assets/img/rmq-healer-gh-banner.png" alt="RMQ Healer" width="100%"/>
3
+ </p>
4
+
5
+ <p align="center">
6
+ <img src="assets/img/rmq-healer-logo.png" alt="RMQ Healer Logo" width="180"/>
7
+ </p>
8
+
9
+ <p align="center">
10
+ <strong>Abstract, extensible RabbitMQ error-queue remediation.</strong><br/>
11
+ Classify &rarr; remediate &rarr; audit &mdash; fully configurable, no code required for common cases.
12
+ </p>
13
+
14
+ <p align="center">
15
+ <img alt="Python" src="https://img.shields.io/badge/python-3.11%2B-blue?logo=python&logoColor=white"/>
16
+ <img alt="License" src="https://img.shields.io/badge/license-MIT-green"/>
17
+ <img alt="CI" src="https://github.com/grimnexo/RMQ-Healer/actions/workflows/ci.yml/badge.svg"/>
18
+ <img alt="Coverage" src="https://img.shields.io/codecov/c/github/grimnexo/RMQ-Healer?logo=codecov"/>
19
+ <img alt="PyPI" src="https://img.shields.io/pypi/v/rmq-healer?logo=pypi&logoColor=white"/>
20
+ <img alt="Docker" src="https://img.shields.io/docker/pulls/grimnexo/rmq-healer?logo=docker"/>
21
+ <img alt="Code style" src="https://img.shields.io/badge/code%20style-ruff-orange?logo=python"/>
22
+ </p>
23
+
24
+ ---
25
+
26
+ ## What Is It?
27
+
28
+ RMQ Healer watches RabbitMQ error queues and **automatically remediates known failure patterns** without touching your application code. You write YAML rules; the healer classifies every message and runs the matching workflow.
29
+
30
+ ### Core Features
31
+
32
+ | | Feature |
33
+ |---|---|
34
+ | **Zero-loss processing** | Messages are acked *only* after a terminal action succeeds. If anything fails the message stays in the queue — untouched. |
35
+ | **Declarative rules** | YAML rule files with nested boolean logic: `body_contains`, `json_path`, `header_equals`, `property_equals`, and combinators (`all`/`any`/`not`). |
36
+ | **Rich workflow engine** | `log`, `mutate_json`, `set_headers`, `python_script`, `republish`, `quarantine`, `route_unknown`, `drop`. |
37
+ | **Jinja2 templating** | Every action param is a Jinja2 template — reference headers, body fields, script outputs, queue config. |
38
+ | **Python script plugins** | Drop any Python script in; it receives full message context on stdin and returns a JSON decision on stdout. |
39
+ | **Idempotency guard** | Bump-and-quarantine: after N failed runs the message is quarantined automatically. |
40
+ | **Structured audit log** | JSON-lines output — pipe straight to Fluentd, Loki, or CloudWatch. |
41
+ | **Non-destructive peek** | Inspect queue contents without consuming — broker requeues automatically after peek. |
42
+ | **Graceful shutdown** | SIGTERM/SIGINT safe — finishes the current message before stopping. |
43
+ | **Developer GUI** | PyQt6 desktop app for editing configs, viewing chains, peeking live queues, and browsing audit logs. |
44
+ | **Plugin architecture** | Register custom actions via Python `entry_points` or a local `plugins/` directory. |
45
+ | **Prometheus metrics** | Optional `prometheus_client` integration — zero-overhead when not installed. |
46
+ | **Dry-run with diffs** | See exactly what `mutate_json` would change before committing. |
47
+
48
+ ---
49
+
50
+ ## Architecture
51
+
52
+ ```mermaid
53
+ flowchart TD
54
+ EQ[("Error Queue")]
55
+ CL["Classifier\n(first match wins)"]
56
+ WF["WorkflowRunner"]
57
+ AU["AuditLogger\n(JSON-lines)"]
58
+
59
+ EQ -->|basic_get| CL
60
+ CL -->|matched rule| WF
61
+ CL -->|no match| UQ[("Unknown Queue")]
62
+ WF --> A1["log / set_headers\nmutate_json / python_script"]
63
+ A1 --> T{"Terminal\naction"}
64
+ T -->|republish| RQ[("Repaired Queue")]
65
+ T -->|quarantine| Q[("Quarantine Queue")]
66
+ T -->|route_unknown| UQ
67
+ T -->|drop| DONE["Ack + discard"]
68
+ WF --> AU
69
+ CL --> AU
70
+ ```
71
+
72
+ ---
73
+
74
+ ## Quick Start
75
+
76
+ ```bash
77
+ # 1. Install
78
+ pip install -e ".[dev]"
79
+
80
+ # 2. Set broker URL
81
+ export RMQ_URL="amqp://guest:guest@localhost/"
82
+
83
+ # 3. Generate config interactively
84
+ rmq-healer configure --output config/queues.yml
85
+
86
+ # 4. Validate
87
+ rmq-healer validate --config config/queues.yml
88
+
89
+ # 5. Test a rule against a sample message
90
+ rmq-healer test-rule --config config/queues.yml \
91
+ --queue order-service.error --message examples/retry-timeout/sample.json
92
+
93
+ # 6. Dry-run with mutation diffs — nothing acked or published
94
+ rmq-healer dry-run --config config/queues.yml --all --pretty
95
+
96
+ # 7. Live run
97
+ rmq-healer run --config config/queues.yml --all --pretty
98
+
99
+ # 8. Peek without consuming
100
+ rmq-healer peek --config config/queues.yml --queue order-service.error --count 10
101
+
102
+ # 9. Visualise a workflow as a Mermaid diagram
103
+ rmq-healer workflow render --config config/queues.yml --queue order-service.error
104
+
105
+ # 10. Search audit logs
106
+ rmq-healer audit-search --log audit.jsonl --outcome quarantine
107
+ ```
108
+
109
+ ---
110
+
111
+ ## Example Configuration
112
+
113
+ ```yaml
114
+ rabbitmq:
115
+ url: "${RMQ_URL}"
116
+ prefetch: 10
117
+
118
+ idempotency:
119
+ enabled: true
120
+ max_handler_attempts: 3
121
+
122
+ queues:
123
+ - name: order-service.error
124
+ enabled: true
125
+ rules_file: rules/order-errors.yml
126
+ repaired_exchange: order.events
127
+ repaired_routing_key: order.retry
128
+ quarantine_exchange: ops.errors
129
+ quarantine_routing_key: order.quarantine
130
+ ```
131
+
132
+ ```yaml
133
+ # rules/order-errors.yml
134
+ rules:
135
+ - id: transient_timeout
136
+ match:
137
+ any:
138
+ - body_contains: "ETIMEDOUT"
139
+ - json_path: $.error.code
140
+ equals: "TIMEOUT"
141
+ workflow:
142
+ - action: set_headers
143
+ params:
144
+ headers:
145
+ x-rmq-healer-rule: transient_timeout
146
+ - action: republish
147
+ params:
148
+ exchange: "{{ queue.repaired_exchange }}"
149
+ routing_key: "{{ queue.repaired_routing_key }}"
150
+
151
+ - id: missing_customer_id
152
+ match:
153
+ all:
154
+ - json_path: $.customer_id
155
+ equals: null
156
+ workflow:
157
+ - action: python_script
158
+ params:
159
+ script: scripts/lookup_customer.py
160
+ timeout: 30
161
+ output:
162
+ save_as: customer
163
+ - action: mutate_json
164
+ params:
165
+ set:
166
+ "$.customer_id": "{{ customer.id }}"
167
+ - action: republish
168
+ params:
169
+ exchange: "{{ queue.repaired_exchange }}"
170
+ routing_key: "{{ queue.repaired_routing_key }}"
171
+ ```
172
+
173
+ See the `examples/` directory for complete, runnable scenarios.
174
+
175
+ ---
176
+
177
+ ## Documentation
178
+
179
+ | Topic | Guide |
180
+ |---|---|
181
+ | Installation & setup | [docs/installation.md](docs/installation.md) |
182
+ | Configuration reference | [docs/configuration.md](docs/configuration.md) |
183
+ | Writing rules | [docs/rules.md](docs/rules.md) |
184
+ | Python script actions | [docs/python-scripts.md](docs/python-scripts.md) |
185
+ | CLI reference (all commands) | [docs/cli-reference.md](docs/cli-reference.md) |
186
+ | Operations guide | [docs/operations.md](docs/operations.md) |
187
+ | Docker deployment | [docs/docker.md](docs/docker.md) |
188
+ | Developer GUI | [docs/developer-gui.md](docs/developer-gui.md) |
189
+ | Plugin architecture | [docs/plugins.md](docs/plugins.md) |
190
+ | Metrics & observability | [docs/metrics.md](docs/metrics.md) |
191
+ | Contributing & tooling | [docs/contributing.md](docs/contributing.md) |
192
+ | Troubleshooting | [docs/troubleshooting.md](docs/troubleshooting.md) |
193
+
194
+ > **[Browse all docs &rarr;](docs/README.md)**
195
+
196
+ ---
197
+
198
+ ## Developer Environment
199
+
200
+ ```powershell
201
+ # Windows
202
+ .\developer\scripts\setup.ps1 # start RabbitMQ + seed fixtures
203
+ .\developer\scripts\run-test.ps1 # dry-run
204
+ .\developer\scripts\launch-gui.ps1 # open GUI
205
+ .\developer\scripts\teardown.ps1 # stop
206
+ ```
207
+
208
+ ```bash
209
+ # Linux / macOS
210
+ bash developer/scripts/setup.sh
211
+ bash developer/scripts/run-test.sh
212
+ bash developer/scripts/launch-gui.sh
213
+ bash developer/scripts/teardown.sh
214
+
215
+ # Or cross-platform Python
216
+ python developer/scripts/dev_setup.py
217
+ python developer/scripts/run_test.py
218
+ python developer/scripts/launch_gui.py
219
+ ```
220
+
221
+ ---
222
+
223
+ ## License
224
+
225
+ MIT &mdash; see [LICENSE](LICENSE).
@@ -0,0 +1,71 @@
1
+ [build-system]
2
+ requires = ["setuptools>=68", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "rmq-healer"
7
+ version = "0.1.0"
8
+ description = "Abstract, extensible RabbitMQ error-queue remediation tool"
9
+ readme = "README.md"
10
+ license = { file = "LICENSE" }
11
+ requires-python = ">=3.11"
12
+ classifiers = [
13
+ "Development Status :: 4 - Beta",
14
+ "Environment :: Console",
15
+ "Intended Audience :: Developers",
16
+ "Intended Audience :: System Administrators",
17
+ "License :: OSI Approved :: MIT License",
18
+ "Programming Language :: Python :: 3",
19
+ "Programming Language :: Python :: 3.11",
20
+ "Programming Language :: Python :: 3.12",
21
+ "Programming Language :: Python :: 3.13",
22
+ "Topic :: System :: Monitoring",
23
+ "Topic :: Software Development :: Libraries :: Python Modules",
24
+ ]
25
+ dependencies = [
26
+ "pika>=1.3",
27
+ "pydantic>=2.0",
28
+ "pydantic-settings>=2.0",
29
+ "PyYAML>=6.0",
30
+ "jsonpath-ng>=1.6",
31
+ "Jinja2>=3.1",
32
+ "click>=8.1",
33
+ ]
34
+
35
+ [project.scripts]
36
+ rmq-healer = "rmq_healer.main:main"
37
+
38
+ [project.optional-dependencies]
39
+ dev = [
40
+ "pytest>=8.0",
41
+ "pytest-cov",
42
+ "ruff>=0.4",
43
+ "mypy>=1.8",
44
+ "types-PyYAML",
45
+ "types-pika",
46
+ ]
47
+ metrics = [
48
+ "prometheus-client>=0.19",
49
+ ]
50
+
51
+ [tool.pytest.ini_options]
52
+ testpaths = ["tests"]
53
+ addopts = "-v --cov=rmq_healer --cov-report=term-missing --cov-report=xml"
54
+
55
+ [tool.ruff]
56
+ line-length = 100
57
+ target-version = "py311"
58
+
59
+ [tool.ruff.lint]
60
+ select = ["E", "F", "W", "I", "UP", "B"]
61
+ ignore = ["E501"]
62
+
63
+ [tool.mypy]
64
+ python_version = "3.11"
65
+ warn_return_any = false
66
+ ignore_missing_imports = true
67
+ no_strict_optional = true
68
+
69
+ [tool.setuptools.packages.find]
70
+ where = ["."]
71
+ include = ["rmq_healer*"]
@@ -0,0 +1,3 @@
1
+ """RMQ Healer — abstract, extensible RabbitMQ error-queue remediation tool."""
2
+
3
+ __version__ = "0.1.0"