riemann-client 0.2.5 → 1.0.1
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 +7 -0
- data/.github/workflows/ci.yml +58 -0
- data/.gitignore +10 -0
- data/.rubocop.yml +18 -0
- data/CHANGELOG.md +84 -0
- data/Gemfile +7 -0
- data/README.markdown +21 -12
- data/Rakefile +15 -0
- data/lib/riemann/attribute.rb +2 -0
- data/lib/riemann/auto_state.rb +9 -3
- data/lib/riemann/client/ssl_socket.rb +92 -0
- data/lib/riemann/client/tcp.rb +46 -39
- data/lib/riemann/client/tcp_socket.rb +76 -58
- data/lib/riemann/client/udp.rb +8 -4
- data/lib/riemann/client.rb +84 -78
- data/lib/riemann/event.rb +60 -61
- data/lib/riemann/message.rb +2 -0
- data/lib/riemann/metric_thread.rb +59 -54
- data/lib/riemann/query.rb +4 -2
- data/lib/riemann/state.rb +8 -8
- data/lib/riemann/version.rb +3 -1
- data/lib/riemann.rb +2 -3
- data/riemann-client.gemspec +34 -0
- data/spec/client.rb +384 -0
- data/spec/riemann.config +30 -0
- metadata +84 -38
data/lib/riemann/event.rb
CHANGED
@@ -1,16 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Riemann
|
2
4
|
class Event
|
3
5
|
require 'set'
|
4
6
|
include Beefcake::Message
|
5
7
|
|
6
8
|
optional :time, :int64, 1
|
7
|
-
optional :state, :string,
|
9
|
+
optional :state, :string, 2
|
8
10
|
optional :service, :string, 3
|
9
11
|
optional :host, :string, 4
|
10
12
|
optional :description, :string, 5
|
11
13
|
repeated :tags, :string, 7
|
12
14
|
optional :ttl, :float, 8
|
13
15
|
repeated :attributes, Attribute, 9
|
16
|
+
optional :time_micros, :int64, 10
|
14
17
|
|
15
18
|
optional :metric_sint64, :sint64, 13
|
16
19
|
optional :metric_d, :double, 14
|
@@ -21,12 +24,16 @@ module Riemann
|
|
21
24
|
VIRTUAL_FIELDS = Set.new([:metric])
|
22
25
|
# Fields which are specially encoded in the Event protobuf--that is, they
|
23
26
|
# can't be used as attributes.
|
24
|
-
RESERVED_FIELDS = fields.map do |
|
27
|
+
RESERVED_FIELDS = fields.map do |_i, field|
|
25
28
|
field.name.to_sym
|
26
|
-
end.reduce(VIRTUAL_FIELDS) do |set, field|
|
29
|
+
end.reduce(VIRTUAL_FIELDS) do |set, field| # rubocop:disable Style/MultilineBlockChain
|
27
30
|
set << field
|
28
31
|
end
|
29
32
|
|
33
|
+
def self.now
|
34
|
+
(Time.now.to_f * 1_000_000).to_i
|
35
|
+
end
|
36
|
+
|
30
37
|
# Average a set of states together. Chooses the mean metric, the mode
|
31
38
|
# state, mode service, and the mean time. If init is provided, its values
|
32
39
|
# override (where present) the computed ones.
|
@@ -39,24 +46,23 @@ module Riemann
|
|
39
46
|
end
|
40
47
|
|
41
48
|
# Metric
|
42
|
-
init.metric_f ||= states.inject(0.0)
|
43
|
-
|
44
|
-
|
45
|
-
if init.metric_f.nan?
|
46
|
-
init.metric_f = 0.0
|
47
|
-
end
|
49
|
+
init.metric_f ||= states.inject(0.0) do |a, state|
|
50
|
+
a + (state.metric || 0)
|
51
|
+
end / states.size
|
52
|
+
init.metric_f = 0.0 if init.metric_f.nan?
|
48
53
|
|
49
54
|
# Event
|
50
55
|
init.state ||= mode states.map(&:state)
|
51
56
|
init.service ||= mode states.map(&:service)
|
52
57
|
|
53
58
|
# Time
|
54
|
-
init.
|
55
|
-
times = states.map(&:
|
59
|
+
init.time_micros = begin
|
60
|
+
times = states.map(&:time_micros).compact
|
56
61
|
(times.inject(:+) / times.size).to_i
|
57
|
-
rescue
|
62
|
+
rescue ZeroDivisionError
|
63
|
+
nil
|
58
64
|
end
|
59
|
-
init.
|
65
|
+
init.time_micros ||= now
|
60
66
|
|
61
67
|
init
|
62
68
|
end
|
@@ -73,24 +79,23 @@ module Riemann
|
|
73
79
|
end
|
74
80
|
|
75
81
|
# Metric
|
76
|
-
init.metric_f ||= states.inject(0.0)
|
77
|
-
|
78
|
-
}
|
79
|
-
if init.metric_f.nan?
|
80
|
-
init.metric_f = 0.0
|
82
|
+
init.metric_f ||= states.inject(0.0) do |a, state|
|
83
|
+
a + (state.metric || 0)
|
81
84
|
end
|
85
|
+
init.metric_f = 0.0 if init.metric_f.nan?
|
82
86
|
|
83
87
|
# Event
|
84
88
|
init.state ||= mode states.map(&:state)
|
85
89
|
init.service ||= mode states.map(&:service)
|
86
90
|
|
87
91
|
# Time
|
88
|
-
init.
|
89
|
-
times = states.map(&:
|
92
|
+
init.time_micros = begin
|
93
|
+
times = states.map(&:time_micros).compact
|
90
94
|
(times.inject(:+) / times.size).to_i
|
91
|
-
rescue
|
95
|
+
rescue ZeroDivisionError
|
96
|
+
nil
|
92
97
|
end
|
93
|
-
init.
|
98
|
+
init.time_micros ||= now
|
94
99
|
|
95
100
|
init
|
96
101
|
end
|
@@ -106,12 +111,10 @@ module Riemann
|
|
106
111
|
end
|
107
112
|
|
108
113
|
# Metric
|
109
|
-
init.metric_f ||= states.inject(0.0)
|
110
|
-
|
111
|
-
}
|
112
|
-
if init.metric.nan?
|
113
|
-
init.metric = 0.0
|
114
|
+
init.metric_f ||= states.inject(0.0) do |a, state|
|
115
|
+
a + (state.metric || 0)
|
114
116
|
end
|
117
|
+
init.metric = 0.0 if init.metric.nan?
|
115
118
|
|
116
119
|
# Event
|
117
120
|
init.state ||= states.inject(nil) do |max, state|
|
@@ -119,34 +122,35 @@ module Riemann
|
|
119
122
|
end
|
120
123
|
|
121
124
|
# Time
|
122
|
-
init.
|
123
|
-
times = states.map(&:
|
125
|
+
init.time_micros = begin
|
126
|
+
times = states.map(&:time_micros).compact
|
124
127
|
(times.inject(:+) / times.size).to_i
|
125
|
-
rescue
|
128
|
+
rescue ZeroDivisionError
|
129
|
+
nil
|
126
130
|
end
|
127
|
-
init.
|
131
|
+
init.time_micros ||= now
|
128
132
|
|
129
133
|
init
|
130
134
|
end
|
131
135
|
|
132
136
|
def self.mode(array)
|
133
|
-
array.
|
137
|
+
array.each_with_object(Hash.new(0)) do |e, counts|
|
134
138
|
counts[e] += 1
|
135
|
-
|
136
|
-
|
139
|
+
end.max_by { |_e, count| count }.first # rubocop:disable Style/MultilineBlockChain
|
140
|
+
rescue StandardError
|
141
|
+
nil
|
137
142
|
end
|
138
143
|
|
139
144
|
# Partition a list of states by a field
|
140
145
|
# Returns a hash of field_value => state
|
141
146
|
def self.partition(states, field)
|
142
|
-
states.
|
147
|
+
states.each_with_object({}) do |state, p|
|
143
148
|
k = state.send field
|
144
149
|
if p.include? k
|
145
150
|
p[k] << state
|
146
151
|
else
|
147
152
|
p[k] = [state]
|
148
153
|
end
|
149
|
-
p
|
150
154
|
end
|
151
155
|
end
|
152
156
|
|
@@ -167,26 +171,22 @@ module Riemann
|
|
167
171
|
|
168
172
|
def initialize(hash = nil)
|
169
173
|
if hash
|
170
|
-
|
171
|
-
|
172
|
-
self.metric = hash[:metric]
|
173
|
-
else
|
174
|
-
super hash
|
175
|
-
end
|
174
|
+
super hash
|
175
|
+
self.metric = hash[:metric] if hash[:metric]
|
176
176
|
|
177
177
|
# Add extra attributes to the event as Attribute instances with values
|
178
178
|
# converted to String
|
179
|
-
self.attributes = hash.map do |key,
|
179
|
+
self.attributes = hash.map do |key, _value|
|
180
180
|
unless RESERVED_FIELDS.include? key.to_sym
|
181
|
-
Attribute.new(:
|
182
|
-
:
|
181
|
+
Attribute.new(key: key.to_s,
|
182
|
+
value: (hash[key] || hash[key.to_sym]).to_s)
|
183
183
|
end
|
184
184
|
end.compact
|
185
185
|
else
|
186
186
|
super()
|
187
187
|
end
|
188
188
|
|
189
|
-
@
|
189
|
+
@time_micros ||= self.class.now unless @time
|
190
190
|
end
|
191
191
|
|
192
192
|
def metric
|
@@ -195,36 +195,35 @@ module Riemann
|
|
195
195
|
metric_f
|
196
196
|
end
|
197
197
|
|
198
|
-
def metric=(
|
199
|
-
if Integer
|
198
|
+
def metric=(value)
|
199
|
+
if value.is_a?(Integer) && (-(2**63)...2**63).include?(value)
|
200
200
|
# Long
|
201
|
-
self.metric_sint64 =
|
202
|
-
self.metric_f = m.to_f
|
201
|
+
self.metric_sint64 = value
|
203
202
|
else
|
204
|
-
self.metric_d =
|
205
|
-
self.metric_f = m.to_f
|
203
|
+
self.metric_d = value.to_f
|
206
204
|
end
|
205
|
+
self.metric_f = value.to_f
|
207
206
|
end
|
208
207
|
|
209
208
|
# Look up attributes
|
210
|
-
def [](
|
211
|
-
if RESERVED_FIELDS.include?
|
209
|
+
def [](key)
|
210
|
+
if RESERVED_FIELDS.include? key.to_sym
|
212
211
|
super
|
213
212
|
else
|
214
|
-
|
213
|
+
attributes.find { |a| a.key.to_s == key.to_s }.value
|
215
214
|
end
|
216
215
|
end
|
217
216
|
|
218
217
|
# Set attributes
|
219
|
-
def []=(
|
220
|
-
if RESERVED_FIELDS.include?
|
218
|
+
def []=(key, value)
|
219
|
+
if RESERVED_FIELDS.include? key.to_sym
|
221
220
|
super
|
222
221
|
else
|
223
|
-
|
224
|
-
if
|
225
|
-
|
222
|
+
attr = attributes.find { |a| a.key == key.to_s }
|
223
|
+
if attr
|
224
|
+
attr.value = value.to_s
|
226
225
|
else
|
227
|
-
|
226
|
+
attributes << Attribute.new(key: key.to_s, value: value.to_s)
|
228
227
|
end
|
229
228
|
end
|
230
229
|
end
|
data/lib/riemann/message.rb
CHANGED
@@ -1,68 +1,73 @@
|
|
1
|
-
|
2
|
-
# A metric thread is simple: it wraps some metric object which responds to <<,
|
3
|
-
# and every interval seconds, calls #flush which replaces the object and calls
|
4
|
-
# a user specified function.
|
5
|
-
|
6
|
-
INTERVAL = 10
|
7
|
-
|
8
|
-
attr_accessor :interval
|
9
|
-
attr_accessor :metric
|
1
|
+
# frozen_string_literal: true
|
10
2
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
# loop do
|
17
|
-
# sleep rand
|
18
|
-
# m << rand
|
19
|
-
# end
|
20
|
-
def initialize(klass, *klass_args, &f)
|
21
|
-
@klass = klass
|
22
|
-
@klass_args = klass_args
|
23
|
-
@f = f
|
24
|
-
@interval = INTERVAL
|
3
|
+
module Riemann
|
4
|
+
class MetricThread
|
5
|
+
# A metric thread is simple: it wraps some metric object which responds to <<,
|
6
|
+
# and every interval seconds, calls #flush which replaces the object and calls
|
7
|
+
# a user specified function.
|
25
8
|
|
26
|
-
|
9
|
+
INTERVAL = 10
|
27
10
|
|
28
|
-
|
29
|
-
end
|
11
|
+
attr_accessor :interval, :metric
|
30
12
|
|
31
|
-
|
32
|
-
|
33
|
-
|
13
|
+
# client = Riemann::Client.new
|
14
|
+
# m = MetricThread.new Mtrc::Rate do |rate|
|
15
|
+
# client << rate
|
16
|
+
# end
|
17
|
+
#
|
18
|
+
# loop do
|
19
|
+
# sleep rand
|
20
|
+
# m << rand
|
21
|
+
# end
|
22
|
+
def initialize(klass, *klass_args, &block)
|
23
|
+
@klass = klass
|
24
|
+
@klass_args = klass_args
|
25
|
+
@block = block
|
26
|
+
@interval = INTERVAL
|
34
27
|
|
35
|
-
|
36
|
-
@klass.new *@klass_args
|
37
|
-
end
|
28
|
+
@metric = new_metric
|
38
29
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
30
|
+
start
|
31
|
+
end
|
32
|
+
|
33
|
+
def <<(value)
|
34
|
+
@metric.<<(value)
|
35
|
+
end
|
36
|
+
|
37
|
+
def new_metric
|
38
|
+
@klass.new(*@klass_args)
|
39
|
+
end
|
40
|
+
|
41
|
+
def flush
|
42
|
+
old = @metric
|
43
|
+
@metric = new_metric
|
44
|
+
@block[old]
|
45
|
+
end
|
46
|
+
|
47
|
+
def start
|
48
|
+
raise 'already running' if @runner
|
43
49
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
rescue Exception => e
|
50
|
+
@running = true
|
51
|
+
@runner = Thread.new do
|
52
|
+
while @running
|
53
|
+
sleep @interval
|
54
|
+
begin
|
55
|
+
flush
|
56
|
+
rescue StandardError
|
57
|
+
# ignore
|
58
|
+
end
|
54
59
|
end
|
60
|
+
@runner = nil
|
55
61
|
end
|
56
|
-
@runner = nil
|
57
62
|
end
|
58
|
-
end
|
59
63
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
+
def stop
|
65
|
+
stop!
|
66
|
+
@runner.join
|
67
|
+
end
|
64
68
|
|
65
|
-
|
66
|
-
|
69
|
+
def stop!
|
70
|
+
@running = false
|
71
|
+
end
|
67
72
|
end
|
68
73
|
end
|
data/lib/riemann/query.rb
CHANGED
data/lib/riemann/state.rb
CHANGED
@@ -1,9 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Riemann
|
2
4
|
class State
|
3
5
|
include Beefcake::Message
|
4
|
-
|
5
|
-
optional :time, :int64, 1
|
6
|
-
optional :state, :string,
|
6
|
+
|
7
|
+
optional :time, :int64, 1
|
8
|
+
optional :state, :string, 2
|
7
9
|
optional :service, :string, 3
|
8
10
|
optional :host, :string, 4
|
9
11
|
optional :description, :string, 5
|
@@ -12,8 +14,8 @@ module Riemann
|
|
12
14
|
optional :ttl, :float, 8
|
13
15
|
optional :metric_f, :float, 15
|
14
16
|
|
15
|
-
def initialize
|
16
|
-
super
|
17
|
+
def initialize
|
18
|
+
super
|
17
19
|
|
18
20
|
@time ||= Time.now.to_i
|
19
21
|
end
|
@@ -22,8 +24,6 @@ module Riemann
|
|
22
24
|
@metric || metric_f
|
23
25
|
end
|
24
26
|
|
25
|
-
|
26
|
-
@metric = m
|
27
|
-
end
|
27
|
+
attr_writer :metric
|
28
28
|
end
|
29
29
|
end
|
data/lib/riemann/version.rb
CHANGED
data/lib/riemann.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
|
2
|
-
$LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__))
|
1
|
+
# frozen_string_literal: true
|
3
2
|
|
3
|
+
module Riemann
|
4
4
|
require 'rubygems'
|
5
5
|
require 'beefcake'
|
6
6
|
require 'timeout'
|
@@ -10,5 +10,4 @@ module Riemann
|
|
10
10
|
require 'riemann/event'
|
11
11
|
require 'riemann/query'
|
12
12
|
require 'riemann/message'
|
13
|
-
require 'riemann/client'
|
14
13
|
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'English'
|
4
|
+
|
5
|
+
lib = File.expand_path('lib', __dir__)
|
6
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
7
|
+
require 'riemann/version'
|
8
|
+
|
9
|
+
Gem::Specification.new do |spec|
|
10
|
+
spec.name = 'riemann-client'
|
11
|
+
spec.version = Riemann::VERSION
|
12
|
+
spec.author = 'Kyle Kingsbury'
|
13
|
+
spec.email = 'aphyr@aphyr.com'
|
14
|
+
spec.summary = 'Client for the distributed event system Riemann.'
|
15
|
+
spec.description = 'Client for the distributed event system Riemann.'
|
16
|
+
spec.homepage = 'https://github.com/aphyr/riemann-ruby-client'
|
17
|
+
spec.license = 'MIT'
|
18
|
+
spec.platform = Gem::Platform::RUBY
|
19
|
+
|
20
|
+
spec.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
|
21
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
22
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
23
|
+
spec.require_paths = ['lib']
|
24
|
+
|
25
|
+
spec.required_ruby_version = '>= 2.6.0'
|
26
|
+
|
27
|
+
spec.add_development_dependency 'bacon'
|
28
|
+
spec.add_development_dependency 'bundler', '>= 1.3'
|
29
|
+
spec.add_development_dependency 'rubocop'
|
30
|
+
spec.add_development_dependency 'timecop'
|
31
|
+
|
32
|
+
spec.add_dependency 'beefcake', ['>= 1.0.0 ']
|
33
|
+
spec.add_dependency 'mtrc', '>= 0.0.4'
|
34
|
+
end
|