riemann-client 0.2.5 → 0.2.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,6 @@
1
+ pkg/
2
+ ._*
3
+ *~
4
+ .DS_Store
5
+ .*.swp
6
+ *.log
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
@@ -48,8 +48,8 @@ faster than TCP, but you will not know if the server is down or encountered an
48
48
  error. You can specify what transport to use by selecting a subclient:
49
49
 
50
50
  ``` ruby
51
- c.udp << { :state "ok" } # => nil
52
- c.tcp << { :state "ok" } # => #<Message ...>
51
+ c.udp << { :state => "ok" } # => nil
52
+ c.tcp << { :state => "ok" } # => #<Message ...>
53
53
  c.tcp["true"] # => [#<Event ... >, ...]
54
54
  c.udp["true"] # => raise Riemann::Client::Unsupported
55
55
  ```
@@ -0,0 +1,46 @@
1
+ $:.unshift(File.join(File.dirname(__FILE__), 'lib'))
2
+
3
+ require 'rubygems'
4
+ require 'rubygems/package_task'
5
+ require 'rdoc/task'
6
+ require 'riemann/version'
7
+ require 'find'
8
+
9
+ # Don't include resource forks in tarballs on Mac OS X.
10
+ ENV['COPY_EXTENDED_ATTRIBUTES_DISABLE'] = 'true'
11
+ ENV['COPYFILE_DISABLE'] = 'true'
12
+
13
+ # Gemspec
14
+ gemspec = Gem::Specification.new do |s|
15
+ s.rubyforge_project = 'riemann-client'
16
+
17
+ s.name = 'riemann-client'
18
+ s.version = Riemann::VERSION
19
+ s.author = 'Kyle Kingsbury'
20
+ s.email = 'aphyr@aphyr.com'
21
+ s.homepage = 'https://github.com/aphyr/riemann-ruby-client'
22
+ s.platform = Gem::Platform::RUBY
23
+ s.summary = 'Client for the distributed event system Riemann.'
24
+
25
+ s.add_dependency 'beefcake', '>= 0.3.5'
26
+ s.add_dependency 'trollop', '>= 1.16.2'
27
+ s.add_dependency 'mtrc', '>= 0.0.4'
28
+
29
+ s.files = FileList['{lib}/**/*', 'LICENSE', 'README.markdown'].to_a
30
+ s.executables = []
31
+ s.require_path = 'lib'
32
+ s.has_rdoc = true
33
+
34
+ s.required_ruby_version = '>= 1.8.7'
35
+ end
36
+
37
+ Gem::PackageTask.new gemspec do |p|
38
+ end
39
+
40
+ RDoc::Task.new do |rd|
41
+ rd.main = 'Riemann'
42
+ rd.title = 'Riemann'
43
+ rd.rdoc_dir = 'doc'
44
+
45
+ rd.rdoc_files.include('lib/**/*.rb')
46
+ end
@@ -28,6 +28,13 @@ class Riemann::Client
28
28
 
29
29
  @udp = UDP.new(@options)
30
30
  @tcp = TCP.new(@options)
31
+ if block_given?
32
+ begin
33
+ yield self
34
+ ensure
35
+ close
36
+ end
37
+ end
31
38
  end
32
39
 
33
40
  def host
@@ -115,8 +115,9 @@ module Riemann
115
115
  sock = ::Socket.new(::Socket::AF_INET, ::Socket::SOCK_STREAM, 0)
116
116
 
117
117
  # close file descriptors if we exec
118
- sock.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)
119
-
118
+ if Fcntl.constants.include?(:F_SETFD) && Fcntl.constants.include?(:FD_CLOEXEC)
119
+ sock.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)
120
+ end
120
121
  # Disable Nagle's algorithm
121
122
  sock.setsockopt(::Socket::IPPROTO_TCP, ::Socket::TCP_NODELAY, 1)
122
123
 
@@ -331,4 +332,4 @@ module Riemann
331
332
  end
332
333
  end
333
334
  end
334
- end
335
+ end
@@ -1,3 +1,3 @@
1
1
  module Riemann
2
- VERSION = '0.2.5'
2
+ VERSION = '0.2.6'
3
3
  end
@@ -0,0 +1,31 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'riemann/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'riemann-client'
8
+ spec.version = Riemann::VERSION
9
+ spec.author = 'Kyle Kingsbury'
10
+ spec.email = 'aphyr@aphyr.com'
11
+ spec.summary = 'Client for the distributed event system Riemann.'
12
+ spec.description = 'Client for the distributed event system Riemann.'
13
+ spec.homepage = 'https://github.com/aphyr/riemann-ruby-client'
14
+ spec.license = 'MIT'
15
+ spec.platform = Gem::Platform::RUBY
16
+
17
+ spec.files = `git ls-files`.split($/)
18
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
19
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
20
+ spec.require_paths = ['lib']
21
+ spec.has_rdoc = true
22
+
23
+ spec.required_ruby_version = '>= 1.8.7'
24
+
25
+ spec.add_development_dependency 'bundler', '>= 1.3'
26
+ spec.add_development_dependency 'bacon'
27
+
28
+ spec.add_dependency 'beefcake', ['>= 0.3.5','<= 1.0.0 ']
29
+ spec.add_dependency 'trollop', '>= 1.16.2'
30
+ spec.add_dependency 'mtrc', '>= 0.0.4'
31
+ end
@@ -0,0 +1,288 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # How to run the bacon tests:
4
+ # 1. Start Riemann on default location 127.0.0.1:5555
5
+ # 2. $ bundle exec bacon spec/client.rb
6
+
7
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib', 'riemann'))
8
+ require 'riemann/client'
9
+ require 'bacon'
10
+ require 'set'
11
+
12
+ Bacon.summary_on_exit
13
+
14
+ include Riemann
15
+
16
+ INACTIVITY_TIME = 5
17
+ RIEMANN_IP = ENV["RIEMANN_IP"] || "127.0.0.1"
18
+ RIEMANN_PORT = ENV["RIEMANN_PORT"] || 5555
19
+
20
+ def roundtrip_metric(m)
21
+ @client_with_transport << {
22
+ :service => 'metric-test',
23
+ :metric => m
24
+ }
25
+ @client["service = \"metric-test\" and metric = #{m}"].
26
+ first.metric.should.equal m
27
+ end
28
+
29
+ def truthy
30
+ lambda { |obj| !(obj.nil? || obj == false) }
31
+ end
32
+
33
+ def falsey
34
+ lambda { |obj| obj.nil? || obj == false }
35
+ end
36
+
37
+ shared "a riemann client" do
38
+
39
+ should 'yield itself to given block' do
40
+ client = nil
41
+ Client.new(:host => RIEMANN_IP, :port => RIEMANN_PORT) do |c|
42
+ client = c
43
+ end
44
+ client.should.be.kind_of?(Client)
45
+ client.should.not.be.connected
46
+ end
47
+
48
+ should 'close sockets if given a block that raises' do
49
+ client = nil
50
+ begin
51
+ Client.new(:host => RIEMANN_IP, :port => RIEMANN_PORT) do |c|
52
+ client = c
53
+ raise "The Boom"
54
+ end
55
+ rescue
56
+ # swallow the exception
57
+ end
58
+ client.should.be.kind_of?(Client)
59
+ client.should.not.be.connected
60
+ end
61
+
62
+ should 'be connected after sending' do
63
+ @client_with_transport.connected?.should.be falsey
64
+ @client.connected?.should.be falsey
65
+ @client_with_transport << {:state => 'ok', :service => 'connected check' }
66
+ @client_with_transport.connected?.should.be truthy
67
+ # NOTE: only single transport connected at this point, @client.connected? is still false until all transports used
68
+ end
69
+
70
+ should 'send longs' do
71
+ roundtrip_metric(0)
72
+ roundtrip_metric(-3)
73
+ roundtrip_metric(5)
74
+ roundtrip_metric(-(2**63))
75
+ roundtrip_metric(2**63 - 1)
76
+ end
77
+
78
+ should 'send doubles' do
79
+ roundtrip_metric 0.0
80
+ roundtrip_metric 12.0
81
+ roundtrip_metric 1.2300000190734863
82
+ end
83
+
84
+ should 'send custom attributes' do
85
+ event = Event.new(
86
+ :service => 'custom',
87
+ :state => 'ok',
88
+ :cats => 'meow',
89
+ :env => 'prod'
90
+ )
91
+ event[:sneak] = 'attack'
92
+ @client_with_transport << event
93
+ event2 = @client['service = "custom"'].first
94
+ event2.service.should.equal 'custom'
95
+ event2.state.should.equal 'ok'
96
+ event2[:cats].should.equal 'meow'
97
+ event2[:env].should.equal 'prod'
98
+ event2[:sneak].should.equal 'attack'
99
+ end
100
+
101
+ should 'send a state with a time' do
102
+ t = Time.now.to_i - 10
103
+ @client_with_transport << {
104
+ :state => 'ok',
105
+ :service => 'test',
106
+ :time => t
107
+ }
108
+ @client.query('service = "test"').events.first.time.should.equal t
109
+ end
110
+
111
+ should 'send a state without time' do
112
+ @client_with_transport << {
113
+ :state => 'ok',
114
+ :service => 'timeless test'
115
+ }
116
+ @client.query('service = "timeless test"').events.first.time.should.equal Time.now.to_i
117
+ end
118
+
119
+ should "query states" do
120
+ @client_with_transport << { :state => 'critical', :service => '1' }
121
+ @client_with_transport << { :state => 'warning', :service => '2' }
122
+ @client_with_transport << { :state => 'critical', :service => '3' }
123
+ @client.query.events.
124
+ map(&:service).to_set.should.superset ['1', '2', '3'].to_set
125
+ @client.query('state = "critical" and (service = "1" or service = "2" or service = "3")').events.
126
+ map(&:service).to_set.should.equal ['1', '3'].to_set
127
+ end
128
+
129
+ it '[]' do
130
+ # @client['state = "critical"'].should == []
131
+ @client_with_transport << {:state => 'critical'}
132
+ @client['state = "critical"'].first.state.should.equal 'critical'
133
+ end
134
+
135
+ should 'query quickly' do
136
+ t1 = Time.now
137
+ total = 1000
138
+ total.times do |i|
139
+ @client.query('state = "critical"')
140
+ end
141
+ t2 = Time.now
142
+
143
+ rate = total / (t2 - t1)
144
+ puts "\n #{"%.2f" % rate} queries/sec (#{"%.2f" % (1000/rate)}ms per query)"
145
+ rate.should > 100
146
+ end
147
+
148
+ should 'be threadsafe' do
149
+ concurrency = 10
150
+ per_thread = 200
151
+ total = concurrency * per_thread
152
+
153
+ t1 = Time.now
154
+ (0...concurrency).map do |i|
155
+ Thread.new do
156
+ per_thread.times do
157
+ @client_with_transport.<<({
158
+ :state => 'ok',
159
+ :service => 'test',
160
+ :description => 'desc',
161
+ :metric_f => 1.0
162
+ })
163
+ end
164
+ end
165
+ end.each do |t|
166
+ t.join
167
+ end
168
+ t2 = Time.now
169
+
170
+ rate = total / (t2 - t1)
171
+ puts "\n #{"%.2f" % rate} inserts/sec (#{"%.2f" % (1000/rate)}ms per insert)"
172
+ rate.should > @expected_rate
173
+ end
174
+
175
+ end
176
+
177
+
178
+ describe "Riemann::Client (TCP transport)" do
179
+ before do
180
+ @client = Client.new(:host => RIEMANN_IP, :port => RIEMANN_PORT)
181
+ @client_with_transport = @client.tcp
182
+ @expected_rate = 100
183
+ end
184
+ behaves_like "a riemann client"
185
+
186
+ should 'send a state' do
187
+ res = @client_with_transport << {
188
+ :state => 'ok',
189
+ :service => 'test',
190
+ :description => 'desc',
191
+ :metric_f => 1.0
192
+ }
193
+
194
+ res.ok.should.be truthy
195
+ @client['service = "test"'].first.state.should.equal 'ok'
196
+ end
197
+
198
+ should 'survive inactivity' do
199
+ @client_with_transport.<<({
200
+ :state => 'warning',
201
+ :service => 'survive TCP inactivity',
202
+ })
203
+ @client['service = "survive TCP inactivity"'].first.state.should.equal 'warning'
204
+
205
+ sleep INACTIVITY_TIME
206
+
207
+ @client_with_transport.<<({
208
+ :state => 'ok',
209
+ :service => 'survive TCP inactivity',
210
+ }).ok.should.be truthy
211
+ @client['service = "survive TCP inactivity"'].first.state.should.equal 'ok'
212
+ end
213
+
214
+ should 'survive local close' do
215
+ @client_with_transport.<<({
216
+ :state => 'warning',
217
+ :service => 'survive TCP local close',
218
+ }).ok.should.be truthy
219
+ @client['service = "survive TCP local close"'].first.state.should.equal 'warning'
220
+
221
+ @client.close
222
+
223
+ @client_with_transport.<<({
224
+ :state => 'ok',
225
+ :service => 'survive TCP local close',
226
+ }).ok.should.be truthy
227
+ @client['service = "survive TCP local close"'].first.state.should.equal 'ok'
228
+ end
229
+ end
230
+
231
+ describe "Riemann::Client (UDP transport)" do
232
+ before do
233
+ @client = Client.new(:host => RIEMANN_IP, :port => RIEMANN_PORT)
234
+ @client_with_transport = @client.udp
235
+ @expected_rate = 1000
236
+ end
237
+ behaves_like "a riemann client"
238
+
239
+ should 'send a state' do
240
+ res = @client_with_transport << {
241
+ :state => 'ok',
242
+ :service => 'test',
243
+ :description => 'desc',
244
+ :metric_f => 1.0
245
+ }
246
+
247
+ res.should.be.nil
248
+ @client['service = "test"'].first.state.should.equal 'ok'
249
+ end
250
+
251
+ should 'survive inactivity' do
252
+ @client_with_transport.<<({
253
+ :state => 'warning',
254
+ :service => 'survive UDP inactivity',
255
+ })
256
+ @client['service = "survive UDP inactivity"'].first.state.should.equal 'warning'
257
+
258
+ sleep INACTIVITY_TIME
259
+
260
+ @client_with_transport.<<({
261
+ :state => 'ok',
262
+ :service => 'survive UDP inactivity',
263
+ })
264
+ @client['service = "survive UDP inactivity"'].first.state.should.equal 'ok'
265
+ end
266
+
267
+ should 'survive local close' do
268
+ @client_with_transport.<<({
269
+ :state => 'warning',
270
+ :service => 'survive UDP local close',
271
+ })
272
+ @client['service = "survive UDP local close"'].first.state.should.equal 'warning'
273
+
274
+ @client.close
275
+
276
+ @client_with_transport.<<({
277
+ :state => 'ok',
278
+ :service => 'survive UDP local close',
279
+ })
280
+ @client['service = "survive UDP local close"'].first.state.should.equal 'ok'
281
+ end
282
+
283
+ should "raise Riemann::Client::Unsupported exception on query" do
284
+ should.raise(Riemann::Client::Unsupported) { @client_with_transport['service = "test"'] }
285
+ should.raise(Riemann::Client::Unsupported) { @client_with_transport.query('service = "test"') }
286
+ end
287
+
288
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: riemann-client
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.5
4
+ version: 0.2.6
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,8 +9,40 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2015-02-05 00:00:00.000000000 Z
12
+ date: 2015-11-18 00:00:00.000000000 Z
13
13
  dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: bundler
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '1.3'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '1.3'
30
+ - !ruby/object:Gem::Dependency
31
+ name: bacon
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
14
46
  - !ruby/object:Gem::Dependency
15
47
  name: beefcake
16
48
  requirement: !ruby/object:Gem::Requirement
@@ -19,6 +51,9 @@ dependencies:
19
51
  - - ! '>='
20
52
  - !ruby/object:Gem::Version
21
53
  version: 0.3.5
54
+ - - <=
55
+ - !ruby/object:Gem::Version
56
+ version: 1.0.0
22
57
  type: :runtime
23
58
  prerelease: false
24
59
  version_requirements: !ruby/object:Gem::Requirement
@@ -27,6 +62,9 @@ dependencies:
27
62
  - - ! '>='
28
63
  - !ruby/object:Gem::Version
29
64
  version: 0.3.5
65
+ - - <=
66
+ - !ruby/object:Gem::Version
67
+ version: 1.0.0
30
68
  - !ruby/object:Gem::Dependency
31
69
  name: trollop
32
70
  requirement: !ruby/object:Gem::Requirement
@@ -59,12 +97,17 @@ dependencies:
59
97
  - - ! '>='
60
98
  - !ruby/object:Gem::Version
61
99
  version: 0.0.4
62
- description:
100
+ description: Client for the distributed event system Riemann.
63
101
  email: aphyr@aphyr.com
64
102
  executables: []
65
103
  extensions: []
66
104
  extra_rdoc_files: []
67
105
  files:
106
+ - .gitignore
107
+ - Gemfile
108
+ - LICENSE
109
+ - README.markdown
110
+ - Rakefile.rb
68
111
  - lib/riemann.rb
69
112
  - lib/riemann/attribute.rb
70
113
  - lib/riemann/auto_state.rb
@@ -78,10 +121,11 @@ files:
78
121
  - lib/riemann/query.rb
79
122
  - lib/riemann/state.rb
80
123
  - lib/riemann/version.rb
81
- - LICENSE
82
- - README.markdown
124
+ - riemann-client.gemspec
125
+ - spec/client.rb
83
126
  homepage: https://github.com/aphyr/riemann-ruby-client
84
- licenses: []
127
+ licenses:
128
+ - MIT
85
129
  post_install_message:
86
130
  rdoc_options: []
87
131
  require_paths:
@@ -99,9 +143,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
99
143
  - !ruby/object:Gem::Version
100
144
  version: '0'
101
145
  requirements: []
102
- rubyforge_project: riemann-client
146
+ rubyforge_project:
103
147
  rubygems_version: 1.8.25
104
148
  signing_key:
105
149
  specification_version: 3
106
150
  summary: Client for the distributed event system Riemann.
107
- test_files: []
151
+ test_files:
152
+ - spec/client.rb