hutch 0.15.0 → 0.16.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +0 -1
- data/CHANGELOG.md +47 -1
- data/Gemfile +2 -0
- data/README.md +25 -0
- data/hutch.gemspec +1 -0
- data/lib/hutch.rb +1 -0
- data/lib/hutch/broker.rb +15 -4
- data/lib/hutch/config.rb +11 -1
- data/lib/hutch/consumer.rb +4 -0
- data/lib/hutch/error_handlers.rb +1 -0
- data/lib/hutch/error_handlers/airbrake.rb +26 -0
- data/lib/hutch/message.rb +2 -1
- data/lib/hutch/tracers.rb +6 -0
- data/lib/hutch/tracers/newrelic.rb +19 -0
- data/lib/hutch/tracers/null_tracer.rb +15 -0
- data/lib/hutch/version.rb +1 -1
- data/lib/hutch/worker.rb +6 -1
- data/spec/hutch/error_handlers/airbrake_spec.rb +34 -0
- data/spec/hutch/message_spec.rb +1 -1
- metadata +23 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0a8fca35975c1fa959a90ec608e978fe3f6c523b
|
4
|
+
data.tar.gz: b8b8df85e625956eb974403d37180dfecfff03b4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f0043f3e29a151a24b38cd18f3f4d8737c37ce77b99001d4fcac6f533904a7eeabdc478bf9b3cd7ac51385ba1da4d97327c71434bbf8ea6fdc026bd4b0431a52
|
7
|
+
data.tar.gz: cde750774fa801338a7e54103566eeaff7cd91c6e930c3251fa4f5521ee3599ac19599ab066ca9581f6ee7919d0e769b70818c6337029644ae97d3f3e0cc3672
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,4 +1,33 @@
|
|
1
|
-
## 0.
|
1
|
+
## 0.16.0 — July 19th, 2015
|
2
|
+
|
3
|
+
### Support amqps URIs
|
4
|
+
|
5
|
+
Hutch now automatically enables TLS and changes default port
|
6
|
+
when URI scheme is `amqps`.
|
7
|
+
|
8
|
+
Contributed by Carl Hörberg.
|
9
|
+
|
10
|
+
### Hash With Indifferent Access
|
11
|
+
|
12
|
+
Hutch now uses `HashWithIndifferentAccess` internally
|
13
|
+
to reduce use of symbols (which are not garbage collected
|
14
|
+
by widely used Ruby versions).
|
15
|
+
|
16
|
+
Contributed by Teodor Pripoae.
|
17
|
+
|
18
|
+
|
19
|
+
## 0.15.0 — May 5th, 2015
|
20
|
+
|
21
|
+
### Airbrake Error Handler
|
22
|
+
|
23
|
+
Contributed by Nate Salisbury.
|
24
|
+
|
25
|
+
### Ruby 1.9 Support Dropped
|
26
|
+
|
27
|
+
Ruby 1.9 is no longer supported by Hutch (and soon Bunny 2.0).
|
28
|
+
1.9 is also no longer maintained by the Ruby core team.
|
29
|
+
|
30
|
+
### Custom Arguments per Consumers
|
2
31
|
|
3
32
|
Allow to set custom arguments per consumers by using the `arguments` setter.
|
4
33
|
Arguments are usually used by rabbitmq plugins or to set queue policies. You can
|
@@ -6,6 +35,23 @@ find a list of supported arguments [here](https://www.rabbitmq.com/extensions.ht
|
|
6
35
|
|
7
36
|
Contributed by Pierre-Louis Gottfrois.
|
8
37
|
|
38
|
+
### Message Processing Tracers
|
39
|
+
|
40
|
+
Allow to track message processing by using the `:tracer` config option,
|
41
|
+
the value should be a class (or fully-qualified string name of a class) that
|
42
|
+
implements the tracing interface.
|
43
|
+
|
44
|
+
A tracer that performs NewRelic instrumentation ships with Hutch
|
45
|
+
and requires New Relic gem to be loaded.
|
46
|
+
|
47
|
+
Contributed by Mirosław Nagaś.
|
48
|
+
|
49
|
+
### Added Logger Method to Consumer Module
|
50
|
+
|
51
|
+
Consumers can now call a logger method to write to Hutch's log.
|
52
|
+
|
53
|
+
Contributed by Matty Courtney
|
54
|
+
|
9
55
|
## 0.14.0 — Feb 23rd, 2015
|
10
56
|
|
11
57
|
### Configurable Socket Timeouts
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -93,6 +93,21 @@ end
|
|
93
93
|
|
94
94
|
Custom queue arguments can be found on [this page](https://www.rabbitmq.com/extensions.html).
|
95
95
|
|
96
|
+
Consumers can write to Hutch's log by calling the logger method. The logger method returns
|
97
|
+
a [Logger object](http://ruby-doc.org/stdlib-2.1.2/libdoc/logger/rdoc/Logger.html).
|
98
|
+
|
99
|
+
```ruby
|
100
|
+
class FailedPaymentConsumer
|
101
|
+
include Hutch::Consumer
|
102
|
+
consume 'gc.ps.payment.failed'
|
103
|
+
|
104
|
+
def process(message)
|
105
|
+
logger.info "Marking payment #{message[:id]} as failed"
|
106
|
+
mark_payment_as_failed(message[:id])
|
107
|
+
end
|
108
|
+
end
|
109
|
+
```
|
110
|
+
|
96
111
|
If you are using Hutch with Rails and want to make Hutch log to the Rails
|
97
112
|
logger rather than `stdout`, add this to `config/initializers/hutch.rb`
|
98
113
|
|
@@ -103,6 +118,15 @@ Hutch::Logging.logger = Rails.logger
|
|
103
118
|
See this [RabbitMQ tutorial on topic exchanges](http://www.rabbitmq.com/tutorials/tutorial-five-ruby.html)
|
104
119
|
to learn more.
|
105
120
|
|
121
|
+
### Message Processing Tracers
|
122
|
+
|
123
|
+
Tracers allow you to track message processing.
|
124
|
+
|
125
|
+
#### NewRelic
|
126
|
+
```ruby
|
127
|
+
Hutch::Config.set(:tracer, Hutch::Tracers::NewRelic)
|
128
|
+
```
|
129
|
+
This will enable NewRelic custom instrumentation. Batteries included! Screenshoots available [here](https://monosnap.com/list/557020a000779174f23467e3).
|
106
130
|
|
107
131
|
## Running Hutch
|
108
132
|
|
@@ -271,6 +295,7 @@ Known configuration parameters are:
|
|
271
295
|
* `connection_timeout`: Bunny's socket open timeout (default: `11`)
|
272
296
|
* `read_timeout`: Bunny's socket read timeout (default: `11`)
|
273
297
|
* `write_timemout`: Bunny's socket write timeout (default: `11`)
|
298
|
+
* `tracer`: tracer to use to track message processing
|
274
299
|
|
275
300
|
|
276
301
|
## Supported RabbitMQ Versions
|
data/hutch.gemspec
CHANGED
@@ -4,6 +4,7 @@ Gem::Specification.new do |gem|
|
|
4
4
|
gem.add_runtime_dependency 'bunny', '>= 1.7.0'
|
5
5
|
gem.add_runtime_dependency 'carrot-top', '~> 0.0.7'
|
6
6
|
gem.add_runtime_dependency 'multi_json', '~> 1.5'
|
7
|
+
gem.add_runtime_dependency 'activesupport', '>= 3.0'
|
7
8
|
gem.add_development_dependency 'rspec', '~> 3.0'
|
8
9
|
gem.add_development_dependency 'simplecov', '~> 0.7.1'
|
9
10
|
|
data/lib/hutch.rb
CHANGED
data/lib/hutch/broker.rb
CHANGED
@@ -24,6 +24,12 @@ module Hutch
|
|
24
24
|
logger.info "HTTP API use is disabled"
|
25
25
|
end
|
26
26
|
|
27
|
+
if tracing_enabled?
|
28
|
+
logger.info "tracing is enabled using #{@config[:tracer]}"
|
29
|
+
else
|
30
|
+
logger.info "tracing is disabled"
|
31
|
+
end
|
32
|
+
|
27
33
|
if block_given?
|
28
34
|
begin
|
29
35
|
yield
|
@@ -63,10 +69,12 @@ module Hutch
|
|
63
69
|
@config[:mq_vhost] = u.path.sub(/^\//, "")
|
64
70
|
@config[:mq_username] = u.user
|
65
71
|
@config[:mq_password] = u.password
|
72
|
+
@config[:mq_tls] = u.scheme == "amqps"
|
66
73
|
end
|
67
74
|
|
75
|
+
tls = @config[:mq_tls]
|
68
76
|
host = @config[:mq_host]
|
69
|
-
port = @config
|
77
|
+
port = @config.fetch(:mq_port, (tls ? 5671 : 5672))
|
70
78
|
vhost = if @config[:mq_vhost] && "" != @config[:mq_vhost]
|
71
79
|
@config[:mq_vhost]
|
72
80
|
else
|
@@ -74,7 +82,6 @@ module Hutch
|
|
74
82
|
end
|
75
83
|
username = @config[:mq_username]
|
76
84
|
password = @config[:mq_password]
|
77
|
-
tls = @config[:mq_tls]
|
78
85
|
tls_key = @config[:mq_tls_key]
|
79
86
|
tls_cert = @config[:mq_tls_cert]
|
80
87
|
heartbeat = @config[:heartbeat]
|
@@ -82,8 +89,8 @@ module Hutch
|
|
82
89
|
read_timeout = @config[:read_timeout]
|
83
90
|
write_timeout = @config[:write_timeout]
|
84
91
|
|
85
|
-
|
86
|
-
sanitized_uri = "#{
|
92
|
+
scheme = tls ? "amqps" : "amqp"
|
93
|
+
sanitized_uri = "#{scheme}://#{username}@#{host}:#{port}/#{vhost.sub(/^\//, '')}"
|
87
94
|
logger.info "connecting to rabbitmq (#{sanitized_uri})"
|
88
95
|
@connection = Bunny.new(host: host, port: port, vhost: vhost,
|
89
96
|
tls: tls, tls_key: tls_key, tls_cert: tls_cert,
|
@@ -140,6 +147,10 @@ module Hutch
|
|
140
147
|
op && cf
|
141
148
|
end
|
142
149
|
|
150
|
+
def tracing_enabled?
|
151
|
+
@config[:tracer] && @config[:tracer] != Hutch::Tracers::NullTracer
|
152
|
+
end
|
153
|
+
|
143
154
|
# Create / get a durable queue and apply namespace if it exists.
|
144
155
|
def queue(name, arguments = {})
|
145
156
|
with_bunny_precondition_handler('queue') do
|
data/lib/hutch/config.rb
CHANGED
@@ -30,6 +30,7 @@ module Hutch
|
|
30
30
|
require_paths: [],
|
31
31
|
autoload_rails: true,
|
32
32
|
error_handlers: [Hutch::ErrorHandlers::Logger.new],
|
33
|
+
tracer: Hutch::Tracers::NullTracer,
|
33
34
|
namespace: nil,
|
34
35
|
daemonise: false,
|
35
36
|
pidfile: nil,
|
@@ -84,7 +85,16 @@ module Hutch
|
|
84
85
|
|
85
86
|
def self.load_from_file(file)
|
86
87
|
YAML.load(ERB.new(File.read(file)).result).each do |attr, value|
|
87
|
-
Hutch::Config.send("#{attr}=", value)
|
88
|
+
Hutch::Config.send("#{attr}=", convert_value(attr, value))
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def self.convert_value(attr, value)
|
93
|
+
case attr
|
94
|
+
when "tracer"
|
95
|
+
Kernel.const_get(value)
|
96
|
+
else
|
97
|
+
value
|
88
98
|
end
|
89
99
|
end
|
90
100
|
|
data/lib/hutch/consumer.rb
CHANGED
data/lib/hutch/error_handlers.rb
CHANGED
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'hutch/logging'
|
2
|
+
require 'airbrake'
|
3
|
+
|
4
|
+
module Hutch
|
5
|
+
module ErrorHandlers
|
6
|
+
class Airbrake
|
7
|
+
include Logging
|
8
|
+
|
9
|
+
def handle(message_id, payload, consumer, ex)
|
10
|
+
prefix = "message(#{message_id || '-'}): "
|
11
|
+
logger.error prefix + "Logging event to Airbrake"
|
12
|
+
logger.error prefix + "#{ex.class} - #{ex.message}"
|
13
|
+
::Airbrake.notify_or_ignore(ex, {
|
14
|
+
:error_class => ex.class.name,
|
15
|
+
:error_message => "#{ ex.class.name }: #{ ex.message }",
|
16
|
+
:backtrace => ex.backtrace,
|
17
|
+
:parameters => {
|
18
|
+
:payload => payload,
|
19
|
+
:consumer => consumer,
|
20
|
+
},
|
21
|
+
:cgi_data => ENV.to_hash,
|
22
|
+
})
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/lib/hutch/message.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'multi_json'
|
2
2
|
require 'forwardable'
|
3
|
+
require 'active_support/core_ext/hash/indifferent_access'
|
3
4
|
|
4
5
|
module Hutch
|
5
6
|
class Message
|
@@ -11,7 +12,7 @@ module Hutch
|
|
11
12
|
@delivery_info = delivery_info
|
12
13
|
@properties = properties
|
13
14
|
@payload = payload
|
14
|
-
@body = MultiJson.load(payload
|
15
|
+
@body = MultiJson.load(payload).with_indifferent_access
|
15
16
|
end
|
16
17
|
|
17
18
|
def_delegator :@body, :[]
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'newrelic_rpm'
|
2
|
+
|
3
|
+
module Hutch
|
4
|
+
module Tracers
|
5
|
+
class NewRelic
|
6
|
+
include ::NewRelic::Agent::Instrumentation::ControllerInstrumentation
|
7
|
+
|
8
|
+
def initialize(klass)
|
9
|
+
@klass = klass
|
10
|
+
end
|
11
|
+
|
12
|
+
def handle(message)
|
13
|
+
@klass.process(message)
|
14
|
+
end
|
15
|
+
|
16
|
+
add_transaction_tracer :handle, :category => 'OtherTransaction/HutchConsumer', :path => '#{@klass.class.name}'
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/lib/hutch/version.rb
CHANGED
data/lib/hutch/worker.rb
CHANGED
@@ -81,7 +81,8 @@ module Hutch
|
|
81
81
|
broker = @broker
|
82
82
|
begin
|
83
83
|
message = Message.new(delivery_info, properties, payload)
|
84
|
-
consumer.new.tap { |c| c.broker, c.delivery_info = @broker, delivery_info }
|
84
|
+
consumer_instance = consumer.new.tap { |c| c.broker, c.delivery_info = @broker, delivery_info }
|
85
|
+
with_tracing(consumer_instance).handle(message)
|
85
86
|
broker.ack(delivery_info.delivery_tag)
|
86
87
|
rescue StandardError => ex
|
87
88
|
broker.nack(delivery_info.delivery_tag)
|
@@ -89,6 +90,10 @@ module Hutch
|
|
89
90
|
end
|
90
91
|
end
|
91
92
|
|
93
|
+
def with_tracing(klass)
|
94
|
+
Hutch::Config[:tracer].new(klass)
|
95
|
+
end
|
96
|
+
|
92
97
|
def handle_error(message_id, payload, consumer, ex)
|
93
98
|
Hutch::Config[:error_handlers].each do |backend|
|
94
99
|
backend.handle(message_id, payload, consumer, ex)
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Hutch::ErrorHandlers::Airbrake do
|
4
|
+
let(:error_handler) { Hutch::ErrorHandlers::Airbrake.new }
|
5
|
+
|
6
|
+
describe '#handle' do
|
7
|
+
let(:error) do
|
8
|
+
begin
|
9
|
+
raise "Stuff went wrong"
|
10
|
+
rescue RuntimeError => err
|
11
|
+
err
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
it "logs the error to Airbrake" do
|
16
|
+
message_id = "1"
|
17
|
+
payload = "{}"
|
18
|
+
consumer = double
|
19
|
+
ex = error
|
20
|
+
message = {
|
21
|
+
:error_class => ex.class.name,
|
22
|
+
:error_message => "#{ ex.class.name }: #{ ex.message }",
|
23
|
+
:backtrace => ex.backtrace,
|
24
|
+
:parameters => {
|
25
|
+
:payload => payload,
|
26
|
+
:consumer => consumer,
|
27
|
+
},
|
28
|
+
:cgi_data => ENV.to_hash,
|
29
|
+
}
|
30
|
+
expect(::Airbrake).to receive(:notify_or_ignore).with(ex, message)
|
31
|
+
error_handler.handle(message_id, payload, consumer, ex)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
data/spec/hutch/message_spec.rb
CHANGED
@@ -3,7 +3,7 @@ require 'hutch/message'
|
|
3
3
|
describe Hutch::Message do
|
4
4
|
let(:delivery_info) { double('Delivery Info') }
|
5
5
|
let(:props) { double('Properties') }
|
6
|
-
let(:body) {{ foo: 'bar' }}
|
6
|
+
let(:body) {{ foo: 'bar' }.with_indifferent_access}
|
7
7
|
let(:json_body) { MultiJson.dump(body) }
|
8
8
|
subject(:message) { Hutch::Message.new(delivery_info, props, json_body) }
|
9
9
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hutch
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.16.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Harry Marr
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-07-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bunny
|
@@ -52,6 +52,20 @@ dependencies:
|
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '1.5'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: activesupport
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '3.0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '3.0'
|
55
69
|
- !ruby/object:Gem::Dependency
|
56
70
|
name: rspec
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -108,18 +122,23 @@ files:
|
|
108
122
|
- lib/hutch/config.rb
|
109
123
|
- lib/hutch/consumer.rb
|
110
124
|
- lib/hutch/error_handlers.rb
|
125
|
+
- lib/hutch/error_handlers/airbrake.rb
|
111
126
|
- lib/hutch/error_handlers/honeybadger.rb
|
112
127
|
- lib/hutch/error_handlers/logger.rb
|
113
128
|
- lib/hutch/error_handlers/sentry.rb
|
114
129
|
- lib/hutch/exceptions.rb
|
115
130
|
- lib/hutch/logging.rb
|
116
131
|
- lib/hutch/message.rb
|
132
|
+
- lib/hutch/tracers.rb
|
133
|
+
- lib/hutch/tracers/newrelic.rb
|
134
|
+
- lib/hutch/tracers/null_tracer.rb
|
117
135
|
- lib/hutch/version.rb
|
118
136
|
- lib/hutch/worker.rb
|
119
137
|
- spec/hutch/broker_spec.rb
|
120
138
|
- spec/hutch/cli_spec.rb
|
121
139
|
- spec/hutch/config_spec.rb
|
122
140
|
- spec/hutch/consumer_spec.rb
|
141
|
+
- spec/hutch/error_handlers/airbrake_spec.rb
|
123
142
|
- spec/hutch/error_handlers/honeybadger_spec.rb
|
124
143
|
- spec/hutch/error_handlers/logger_spec.rb
|
125
144
|
- spec/hutch/error_handlers/sentry_spec.rb
|
@@ -148,7 +167,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
148
167
|
version: '0'
|
149
168
|
requirements: []
|
150
169
|
rubyforge_project:
|
151
|
-
rubygems_version: 2.4.
|
170
|
+
rubygems_version: 2.4.3
|
152
171
|
signing_key:
|
153
172
|
specification_version: 4
|
154
173
|
summary: Easy inter-service communication using RabbitMQ.
|
@@ -157,6 +176,7 @@ test_files:
|
|
157
176
|
- spec/hutch/cli_spec.rb
|
158
177
|
- spec/hutch/config_spec.rb
|
159
178
|
- spec/hutch/consumer_spec.rb
|
179
|
+
- spec/hutch/error_handlers/airbrake_spec.rb
|
160
180
|
- spec/hutch/error_handlers/honeybadger_spec.rb
|
161
181
|
- spec/hutch/error_handlers/logger_spec.rb
|
162
182
|
- spec/hutch/error_handlers/sentry_spec.rb
|
@@ -165,4 +185,3 @@ test_files:
|
|
165
185
|
- spec/hutch/worker_spec.rb
|
166
186
|
- spec/hutch_spec.rb
|
167
187
|
- spec/spec_helper.rb
|
168
|
-
has_rdoc:
|