protobuffy 3.1.0 → 3.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGES.md +6 -0
- data/lib/protobuf/rpc/middleware/statsd.rb +55 -0
- data/lib/protobuf/rpc/middleware.rb +3 -0
- data/lib/protobuf/rpc/stat.rb +3 -14
- data/lib/protobuf/statsd.rb +10 -0
- data/lib/protobuf/version.rb +1 -1
- data/spec/lib/protobuf/rpc/middleware/statsd_spec.rb +102 -0
- data/spec/lib/protobuf/rpc/stat_spec.rb +4 -4
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cc8e8aa7b3ed82b4a15558414ef537ada9e5f84a
|
4
|
+
data.tar.gz: d13a9ec3b735bea4184385b36ff0b7e53f9b8f6d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 63d3029e746e4b9cf5c294f8eb172519170266b0a2c161fc24a92d1fd76e47fcd668f5040b70e24cba5e7abd99848a2c04b334afb19fc5bfa72f2c3ac4653cb2
|
7
|
+
data.tar.gz: e94dcd1103b54ad56b5a56d1272f3a408e3c305f0083387a98018ce9858efd5b380df6b59acfda296f535a6ac48d847a721da5ffb0540beb085e16387501762f
|
data/CHANGES.md
CHANGED
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'protobuf/statsd'
|
2
|
+
|
3
|
+
module Protobuf
|
4
|
+
module Rpc
|
5
|
+
module Middleware
|
6
|
+
class Statsd
|
7
|
+
def initialize(app)
|
8
|
+
@app = app
|
9
|
+
end
|
10
|
+
|
11
|
+
def call(env)
|
12
|
+
start_time = Time.now.utc
|
13
|
+
begin
|
14
|
+
env = @app.call(env)
|
15
|
+
ensure
|
16
|
+
record_stats(env, start_time)
|
17
|
+
end
|
18
|
+
|
19
|
+
env
|
20
|
+
end
|
21
|
+
|
22
|
+
# Return base path for StatsD metrics
|
23
|
+
def statsd_base_path(env)
|
24
|
+
if env.service_name && env.method_name
|
25
|
+
"rpc-server.#{env.service_name}.#{env.method_name}".gsub('::', '.').downcase
|
26
|
+
else
|
27
|
+
nil
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
# Send success/failure and timing information to Statsd, if
|
32
|
+
# one was configured in Protobuf::Statsd.
|
33
|
+
def record_stats(env, start_time)
|
34
|
+
statsd_client = Protobuf::Statsd.client
|
35
|
+
path = statsd_base_path(env)
|
36
|
+
return unless statsd_client && path && env.response
|
37
|
+
end_time = Time.now.utc
|
38
|
+
|
39
|
+
if env.response.is_a?(Protobuf::Rpc::PbError)
|
40
|
+
statsd_client.increment("#{path}.failure.total")
|
41
|
+
statsd_client.increment("#{path}.failure.#{env.response.error_type}")
|
42
|
+
else
|
43
|
+
statsd_client.increment("#{path}.success")
|
44
|
+
end
|
45
|
+
|
46
|
+
statsd_client.timing("#{path}.time", end_time - start_time)
|
47
|
+
rescue => e
|
48
|
+
# We insert ourself after Exception handler, so no exceptions allowed!
|
49
|
+
Protobuf::Logger.warn { "Error with Statsd middleware: #{e.message}" }
|
50
|
+
end
|
51
|
+
private :record_stats
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -4,6 +4,7 @@ require 'protobuf/rpc/middleware/exception_handler'
|
|
4
4
|
require 'protobuf/rpc/middleware/logger'
|
5
5
|
require 'protobuf/rpc/middleware/request_decoder'
|
6
6
|
require 'protobuf/rpc/middleware/response_encoder'
|
7
|
+
require 'protobuf/rpc/middleware/statsd'
|
7
8
|
require 'protobuf/rpc/middleware/runner'
|
8
9
|
|
9
10
|
module Protobuf
|
@@ -16,6 +17,8 @@ module Protobuf
|
|
16
17
|
middleware
|
17
18
|
end
|
18
19
|
|
20
|
+
# Statsd comes first so it gets full timing and access to exceptions
|
21
|
+
Rpc.middleware.use(Rpc::Middleware::Statsd)
|
19
22
|
Rpc.middleware.use(Rpc::Middleware::ExceptionHandler)
|
20
23
|
Rpc.middleware.use(Rpc::Middleware::RequestDecoder)
|
21
24
|
Rpc.middleware.use(Rpc::Middleware::Logger)
|
data/lib/protobuf/rpc/stat.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'date'
|
2
2
|
require 'time'
|
3
3
|
require 'protobuf/logger'
|
4
|
+
require 'protobuf/statsd'
|
4
5
|
|
5
6
|
module Protobuf
|
6
7
|
module Rpc
|
@@ -10,18 +11,6 @@ module Protobuf
|
|
10
11
|
|
11
12
|
MODES = [:SERVER, :CLIENT].freeze
|
12
13
|
|
13
|
-
# Set the StatsD Client to send stats to. The client must match
|
14
|
-
# the interface provided by lookout-statsd
|
15
|
-
# (https://github.com/lookout/statsd).
|
16
|
-
def self.statsd_client=(statsd_client)
|
17
|
-
@statsd_client = statsd_client
|
18
|
-
end
|
19
|
-
|
20
|
-
# The StatsD Client configured, if any.
|
21
|
-
def self.statsd_client
|
22
|
-
@statsd_client
|
23
|
-
end
|
24
|
-
|
25
14
|
def initialize(mode = :SERVER)
|
26
15
|
@mode = mode
|
27
16
|
@request_size = 0
|
@@ -119,14 +108,14 @@ module Protobuf
|
|
119
108
|
|
120
109
|
# Return base path for StatsD metrics
|
121
110
|
def statsd_base_path
|
122
|
-
"rpc.#{service}.#{method_name}".gsub('::', '.').downcase
|
111
|
+
"rpc-client.#{service}.#{method_name}".gsub('::', '.').downcase
|
123
112
|
end
|
124
113
|
|
125
114
|
# If a StatsD Client has been configured, send stats to it upon
|
126
115
|
# completion.
|
127
116
|
def call_statsd_client
|
128
117
|
path = statsd_base_path
|
129
|
-
statsd_client =
|
118
|
+
statsd_client = Protobuf::Statsd.client
|
130
119
|
return unless statsd_client
|
131
120
|
|
132
121
|
if @success
|
data/lib/protobuf/version.rb
CHANGED
@@ -0,0 +1,102 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'timecop'
|
3
|
+
|
4
|
+
describe Protobuf::Rpc::Middleware::Statsd do
|
5
|
+
let(:app) { Proc.new { |inner_env| Timecop.freeze(Time.now + call_time); inner_env } }
|
6
|
+
let(:env) {
|
7
|
+
Protobuf::Rpc::Env.new(
|
8
|
+
'client_host' => 'client_host.test.co',
|
9
|
+
'encoded_request' => request_wrapper.encode,
|
10
|
+
'encoded_response' => response_wrapper.encode,
|
11
|
+
'method_name' => method_name,
|
12
|
+
'request' => request,
|
13
|
+
'request_type' => rpc_method.request_type,
|
14
|
+
'response' => response,
|
15
|
+
'response_type' => rpc_method.response_type,
|
16
|
+
'rpc_method' => rpc_method,
|
17
|
+
'rpc_service' => service_class,
|
18
|
+
'service_name' => service_name,
|
19
|
+
)
|
20
|
+
}
|
21
|
+
let(:method_name) { :find }
|
22
|
+
let(:request) { request_type.new(:name => 'required') }
|
23
|
+
let(:request_type) { rpc_method.request_type }
|
24
|
+
let(:request_wrapper) {
|
25
|
+
Protobuf::Socketrpc::Request.new(
|
26
|
+
:service_name => service_name,
|
27
|
+
:method_name => method_name.to_s,
|
28
|
+
:request_proto => request
|
29
|
+
)
|
30
|
+
}
|
31
|
+
let(:response) { rpc_method.response_type.new(:name => 'required') }
|
32
|
+
let(:response_wrapper) { Protobuf::Socketrpc::Response.new(:response_proto => response) }
|
33
|
+
let(:rpc_method) { service_class.rpcs[method_name] }
|
34
|
+
let(:rpc_service) { service_class.new(env) }
|
35
|
+
let(:service_class) { Test::ResourceService }
|
36
|
+
let(:service_name) { service_class.to_s }
|
37
|
+
let(:stats_path) { 'rpc-server.test.resourceservice.find' }
|
38
|
+
let(:call_time) { 100 }
|
39
|
+
|
40
|
+
subject { described_class.new(app) }
|
41
|
+
|
42
|
+
describe "#call" do
|
43
|
+
context "without Protobuf::Statsd.client set" do
|
44
|
+
before :each do
|
45
|
+
Protobuf::Statsd.client = nil
|
46
|
+
end
|
47
|
+
|
48
|
+
it "calls the stack" do
|
49
|
+
app.should_receive(:call).with(env)
|
50
|
+
subject.call(env)
|
51
|
+
end
|
52
|
+
|
53
|
+
it "returns the env" do
|
54
|
+
subject.call(env).should eq env
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
context "with Protobuf::Statsd.client set" do
|
59
|
+
let(:statsd_client) { double("Statsd::Client") }
|
60
|
+
|
61
|
+
before :each do
|
62
|
+
Protobuf::Statsd.client = statsd_client
|
63
|
+
Protobuf::Rpc::Middleware::Statsd.any_instance.stub(:statsd_base_path).and_return(stats_path)
|
64
|
+
Timecop.freeze(Time.now)
|
65
|
+
end
|
66
|
+
|
67
|
+
after :each do
|
68
|
+
Protobuf::Statsd.client = nil
|
69
|
+
Timecop.return
|
70
|
+
end
|
71
|
+
|
72
|
+
context "with success response" do
|
73
|
+
it "should increment the proper stats" do
|
74
|
+
expect(statsd_client).to receive(:increment).with("#{stats_path}.success")
|
75
|
+
expect(statsd_client).to receive(:timing).with("#{stats_path}.time", call_time)
|
76
|
+
|
77
|
+
subject.call(env)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
context "with failure response" do
|
82
|
+
let(:type) { Protobuf::Socketrpc::ErrorReason::BAD_REQUEST_DATA }
|
83
|
+
let(:response) { Protobuf::Rpc::PbError.new('ooops', type) }
|
84
|
+
let(:response_wrapper) { response.to_response }
|
85
|
+
|
86
|
+
it "should increment the proper stats" do
|
87
|
+
expect(statsd_client).to receive(:increment).with("#{stats_path}.failure.total")
|
88
|
+
expect(statsd_client).to receive(:increment).with("#{stats_path}.failure.#{type}")
|
89
|
+
expect(statsd_client).to receive(:timing).with("#{stats_path}.time", call_time)
|
90
|
+
|
91
|
+
subject.call(env)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
describe "#statsd_base_path" do
|
98
|
+
it "should return a good path" do
|
99
|
+
expect(subject.statsd_base_path(env)).to eql "rpc-server.test.resourceservice.find"
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
@@ -77,7 +77,7 @@ describe ::Protobuf::Rpc::Stat do
|
|
77
77
|
end
|
78
78
|
|
79
79
|
it "should use correct base path" do
|
80
|
-
expect(statsd_base_path).to eq "rpc.foo.barservice.find_bars"
|
80
|
+
expect(statsd_base_path).to eq "rpc-client.foo.barservice.find_bars"
|
81
81
|
end
|
82
82
|
end
|
83
83
|
|
@@ -87,7 +87,7 @@ describe ::Protobuf::Rpc::Stat do
|
|
87
87
|
let(:end_time) { Time.now }
|
88
88
|
let(:service) { 'Foo::BarService' }
|
89
89
|
let(:method_name) { 'find_bars' }
|
90
|
-
let(:stats_path) { 'rpc.foo.barservice.find_bars' }
|
90
|
+
let(:stats_path) { 'rpc-client.foo.barservice.find_bars' }
|
91
91
|
|
92
92
|
before :each do
|
93
93
|
stats.service = service
|
@@ -109,11 +109,11 @@ describe ::Protobuf::Rpc::Stat do
|
|
109
109
|
let(:statsd_client) { double("Statsd::Client") }
|
110
110
|
|
111
111
|
before :each do
|
112
|
-
Protobuf::
|
112
|
+
Protobuf::Statsd.client = statsd_client
|
113
113
|
end
|
114
114
|
|
115
115
|
after :each do
|
116
|
-
Protobuf::
|
116
|
+
Protobuf::Statsd.client = nil
|
117
117
|
end
|
118
118
|
|
119
119
|
context "on success" do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: protobuffy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.
|
4
|
+
version: 3.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- BJ Neilsen
|
@@ -13,7 +13,7 @@ autorequire:
|
|
13
13
|
bindir: bin
|
14
14
|
cert_chain: []
|
15
15
|
|
16
|
-
date: 2014-10-
|
16
|
+
date: 2014-10-16 00:00:00 Z
|
17
17
|
dependencies:
|
18
18
|
- !ruby/object:Gem::Dependency
|
19
19
|
name: activesupport
|
@@ -237,6 +237,7 @@ files:
|
|
237
237
|
- lib/protobuf/rpc/middleware/request_decoder.rb
|
238
238
|
- lib/protobuf/rpc/middleware/response_encoder.rb
|
239
239
|
- lib/protobuf/rpc/middleware/runner.rb
|
240
|
+
- lib/protobuf/rpc/middleware/statsd.rb
|
240
241
|
- lib/protobuf/rpc/rpc.pb.rb
|
241
242
|
- lib/protobuf/rpc/server.rb
|
242
243
|
- lib/protobuf/rpc/servers/http/server.rb
|
@@ -255,6 +256,7 @@ files:
|
|
255
256
|
- lib/protobuf/rpc/service_filters.rb
|
256
257
|
- lib/protobuf/rpc/stat.rb
|
257
258
|
- lib/protobuf/socket.rb
|
259
|
+
- lib/protobuf/statsd.rb
|
258
260
|
- lib/protobuf/tasks.rb
|
259
261
|
- lib/protobuf/tasks/compile.rake
|
260
262
|
- lib/protobuf/version.rb
|
@@ -302,6 +304,7 @@ files:
|
|
302
304
|
- spec/lib/protobuf/rpc/middleware/logger_spec.rb
|
303
305
|
- spec/lib/protobuf/rpc/middleware/request_decoder_spec.rb
|
304
306
|
- spec/lib/protobuf/rpc/middleware/response_encoder_spec.rb
|
307
|
+
- spec/lib/protobuf/rpc/middleware/statsd_spec.rb
|
305
308
|
- spec/lib/protobuf/rpc/servers/http/server_spec.rb
|
306
309
|
- spec/lib/protobuf/rpc/servers/socket_server_spec.rb
|
307
310
|
- spec/lib/protobuf/rpc/servers/zmq/server_spec.rb
|