riemann-ruby-experiments 0.0.3
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/Gemfile +2 -0
- data/README.adoc +81 -0
- data/Rakefile +135 -0
- data/data/riemann.proto +43 -0
- data/lib/riemann-ruby-experiments.rb +21 -0
- data/lib/riemann-ruby-experiments/event.rb +205 -0
- data/lib/riemann-ruby-experiments/main.rb +117 -0
- data/lib/riemann-ruby-experiments/riemann.pb.rb +65 -0
- data/lib/riemann-ruby-experiments/version.rb +6 -0
- data/project.yaml +11 -0
- data/riemann-ruby-experiments.gemspec +31 -0
- metadata +139 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 7493f64bd96d10b57b58cf47a79390866f8dd92b
|
4
|
+
data.tar.gz: bb4ec0ad7c71c8e898546627f9e1dbe56fb68c2b
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 0e2535d6834d35510036cc013b3fe56638d7b84b131463bc03d600b6ecd3f5d04605cc6eb7946c980a58c7a729737cc816e2ffdeaf2dbe126cd77afd7f741b9f
|
7
|
+
data.tar.gz: 83ced84778692d4a9891c2e11ec5db125f3b3e9b7ee9c23eeadcff6d651ffecbb09b80acceb7a462c9fe7954c992e575f10b119d5115a0a1191fc64ee570ae34
|
data/Gemfile
ADDED
data/README.adoc
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
= riemann-ruby-experiments
|
2
|
+
Chris Riddoch <riddochc@gmail.com>
|
3
|
+
:language: ruby
|
4
|
+
:homepage: https://syntacticsugar.org/projects/riemann-ruby-experiments
|
5
|
+
:revnumber: 0.0.3
|
6
|
+
:revdate: 2016-05-29
|
7
|
+
|
8
|
+
== Description
|
9
|
+
|
10
|
+
A Riemann client for ruby
|
11
|
+
|
12
|
+
Just another client, to experiment with.
|
13
|
+
|
14
|
+
== Requirements
|
15
|
+
|
16
|
+
* A riemann server to talk to
|
17
|
+
|
18
|
+
== Installation
|
19
|
+
|
20
|
+
gem install riemann-ruby-experiments
|
21
|
+
|
22
|
+
== Use
|
23
|
+
|
24
|
+
Include the following line in your Gemfile:
|
25
|
+
|
26
|
+
gem 'riemann-ruby-experiments'
|
27
|
+
|
28
|
+
Then, you can use it like this:
|
29
|
+
|
30
|
+
client = Riemann::Experiment::Client.new(server: "localhost:5555", service: "A new riemann logger!")
|
31
|
+
e1 = {time: Time.now.to_i,
|
32
|
+
description: "An event of some sort",
|
33
|
+
metric: 42.15,
|
34
|
+
anotherkey: "anothervalue"}
|
35
|
+
client.add_event(e1)
|
36
|
+
|
37
|
+
e2 = {time: Time.now.to_i, description: "Another event", metric: 73}
|
38
|
+
client.add_event(e2)
|
39
|
+
|
40
|
+
response = client.send_message()
|
41
|
+
|
42
|
+
if response.ok == 'ok'
|
43
|
+
# acknowledged by server...
|
44
|
+
end
|
45
|
+
|
46
|
+
You can also send queries to the Riemann server:
|
47
|
+
|
48
|
+
client = Riemann::Experiment::Client.new()
|
49
|
+
events = client['service = "http/head/mysite"']
|
50
|
+
puts events.first.roundtrip
|
51
|
+
|
52
|
+
New attributes can be assigned to an `Riemann::Experiment::Event` object as though
|
53
|
+
they were defined on the object with simple attr_accessors. To create events
|
54
|
+
yourself, make sure to call `setup()` on them, passing the client, before doing
|
55
|
+
other manipulations (and especially before serializing) in order to make sure
|
56
|
+
that client-wide default values are applied correctly.
|
57
|
+
|
58
|
+
e = Riemann::Experiment::Event.new
|
59
|
+
e.setup(client)
|
60
|
+
e.time = Time.now
|
61
|
+
e.website = "http://example.com/"
|
62
|
+
Base64.strict_encode64(e) # Just for illustration:
|
63
|
+
=> "CKyWs7oFGiMuL3JpZW1hbm4tcnVieS1leHBlcmltZW50cy5yYjsxMDU4NyIFdGh5bWVKHgoHd2Vic2l0ZRITaHR0cDovL2V4YW1wbGUuY29tLw=="
|
64
|
+
|
65
|
+
For most purposes, though, it's easier to just pass a hash of field values to
|
66
|
+
the client's `add_event()` and let it take care of the details.
|
67
|
+
|
68
|
+
== Contributing
|
69
|
+
|
70
|
+
Pull requests welcome.
|
71
|
+
|
72
|
+
== Contributors
|
73
|
+
|
74
|
+
* Chris Riddoch
|
75
|
+
|
76
|
+
== License
|
77
|
+
|
78
|
+
Copyright © 2016 Chris Riddoch
|
79
|
+
|
80
|
+
See LICENSE for license details
|
81
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,135 @@
|
|
1
|
+
# vim: syntax=ruby
|
2
|
+
|
3
|
+
require 'yaml'
|
4
|
+
require 'find'
|
5
|
+
require 'asciidoctor'
|
6
|
+
require 'erb'
|
7
|
+
require 'pry'
|
8
|
+
|
9
|
+
def installed_gem_version(name)
|
10
|
+
IO.popen(["gem", "list", "-l", name], 'r') do |io|
|
11
|
+
# this regex is using lookahead/behind to match things within \( and \), non-greedily.
|
12
|
+
io.readlines.grep(/^#{name}\s/).first[/(?<=\().*?(?=\))/].split(', ').first
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def filtered_project_files()
|
17
|
+
Dir.chdir __dir__ do
|
18
|
+
Find.find(".").reject {|f|
|
19
|
+
!File.file?(f) ||
|
20
|
+
f =~ %r{^\./(.git|tmp)} ||
|
21
|
+
f =~ %r{\.(so|gem)$}
|
22
|
+
}.map {|f| f.sub %r{^\./}, '' }
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
adoc = Asciidoctor.load_file("README.adoc")
|
27
|
+
summary = adoc.sections.find {|s| s.name == "Description" }.blocks[0].content.gsub(/\n/, ' ')
|
28
|
+
description = adoc.sections.find {|s| s.name == "Description" }.blocks[1].content.gsub(/\n/, ' ')
|
29
|
+
config = YAML.load_file(File.join(__dir__, "project.yaml"))
|
30
|
+
project = config.fetch('name', File.split(File.expand_path(__dir__)).last)
|
31
|
+
toplevel_module = config.fetch('toplevel_module') { project.capitalize }
|
32
|
+
version = adoc.attributes['revnumber']
|
33
|
+
dependencies = config.fetch('dependencies', {})
|
34
|
+
if dependencies.nil?
|
35
|
+
dependencies = {}
|
36
|
+
end
|
37
|
+
dev_dependencies = config.fetch('dev-dependencies', {})
|
38
|
+
if dev_dependencies.nil?
|
39
|
+
dev_dependencies = {}
|
40
|
+
end
|
41
|
+
license = config.fetch('license') { "LGPL-3.0" }
|
42
|
+
|
43
|
+
#["rake", "asciidoctor", "yard", "pry", "rspec", "rspec-sequel-formatter", "#{project}-tests"]
|
44
|
+
["rake", "asciidoctor", "yard", "pry"].each do |dep|
|
45
|
+
dev_dependencies[dep] = dev_dependencies.fetch(dep) {|d| "=#{installed_gem_version(d)}" }
|
46
|
+
end
|
47
|
+
|
48
|
+
gemspec_template = <<GEMSPEC
|
49
|
+
Gem::Specification.new do |s|
|
50
|
+
s.name = "<%= project %>"
|
51
|
+
s.version = "<%= version %>"
|
52
|
+
s.licenses = ["<%= license %>"]
|
53
|
+
s.platform = Gem::Platform::RUBY
|
54
|
+
s.summary = "<%= summary %>"
|
55
|
+
s.description = "<%= description %>"
|
56
|
+
s.authors = ["<%= adoc.author %>"]
|
57
|
+
s.email = "<%= adoc.attributes['email'] %>"
|
58
|
+
s.date = "<%= Date.today %>"
|
59
|
+
s.files = [<%= all_files.map{|f| '"' + f + '"' }.join(",\n ") %>]
|
60
|
+
s.homepage = "<%= adoc.attributes['homepage'] %>"
|
61
|
+
|
62
|
+
% dependencies.each_pair do |req, vers|
|
63
|
+
s.add_dependency "<%= req %>", "<%= vers %>"
|
64
|
+
% end
|
65
|
+
|
66
|
+
% dev_dependencies.each_pair do |req, vers|
|
67
|
+
s.add_development_dependency "<%= req %>", "<%= vers %>"
|
68
|
+
% end
|
69
|
+
end
|
70
|
+
GEMSPEC
|
71
|
+
|
72
|
+
task default: ["lib/riemann-ruby-experiments/riemann.pb.rb",
|
73
|
+
:gen_version, :gemspec, :gemfile, :build]
|
74
|
+
|
75
|
+
task "lib/riemann-ruby-experiments/riemann.pb.rb" do
|
76
|
+
sh "ruby-protoc", "data/riemann.proto"
|
77
|
+
mv "data/riemann.pb.rb", "lib/riemann-ruby-experiments/riemann.pb.rb"
|
78
|
+
end
|
79
|
+
|
80
|
+
task :gen_version do
|
81
|
+
File.open(File.join("lib", project, "version.rb"), 'w') {|f|
|
82
|
+
f.puts "module #{toplevel_module}"
|
83
|
+
major, minor, tiny = *version.split(/\./).map {|p| p.to_i }
|
84
|
+
f.puts ' VERSION = "' + version + '"'
|
85
|
+
f.puts " VERSION_MAJOR = #{major}"
|
86
|
+
f.puts " VERSION_MINOR = #{minor}"
|
87
|
+
f.puts " VERSION_TINY = #{tiny}"
|
88
|
+
f.puts "end"
|
89
|
+
}
|
90
|
+
end
|
91
|
+
|
92
|
+
task :gemspec => [:gen_version] do
|
93
|
+
files_in_git = IO.popen(["git", "ls-files"], 'r') { |io| io.readlines.map {|l| l.chomp } }
|
94
|
+
all_files = filtered_project_files()
|
95
|
+
if all_files - files_in_git
|
96
|
+
puts "Looks like there's some files uncommitted."
|
97
|
+
end
|
98
|
+
|
99
|
+
requires = all_files.grep(/\.rb$/).
|
100
|
+
map {|f| File.readlines(f).grep (/^\s*require(?!_relative)\b/) }.
|
101
|
+
flatten.
|
102
|
+
map {|line| line.split(/['"]/).at(1).split('/').at(0) }.
|
103
|
+
uniq
|
104
|
+
|
105
|
+
missing_deps = requires - dependencies.keys
|
106
|
+
if missing_deps.length > 0
|
107
|
+
puts "There may be some dependencies not listed for the gemspec:"
|
108
|
+
puts missing_deps.join(", ")
|
109
|
+
end
|
110
|
+
|
111
|
+
File.open(project + ".gemspec", 'w') do |f|
|
112
|
+
erb = ERB.new(gemspec_template, nil, "%<>")
|
113
|
+
f.write(erb.result(binding))
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
task :gemfile do
|
118
|
+
File.open("Gemfile", 'w') do |f|
|
119
|
+
f.puts "source 'https://rubygems.org"
|
120
|
+
f.puts "gemspec"
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
task :build => [:gemspec] do
|
125
|
+
system "gem build #{project}.gemspec"
|
126
|
+
end
|
127
|
+
|
128
|
+
task :install => [:build] do
|
129
|
+
system "gem install ./#{project}-#{version}.gem"
|
130
|
+
end
|
131
|
+
|
132
|
+
task :clean do
|
133
|
+
rm_f "./#{project}-#{version}.gem"
|
134
|
+
rm_rf "tmp"
|
135
|
+
end
|
data/data/riemann.proto
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
message State {
|
2
|
+
optional int64 time = 1;
|
3
|
+
optional string state = 2;
|
4
|
+
optional string service = 3;
|
5
|
+
optional string host = 4;
|
6
|
+
optional string description = 5;
|
7
|
+
optional bool once = 6;
|
8
|
+
repeated string tags = 7;
|
9
|
+
optional float ttl = 8;
|
10
|
+
optional float metric_f = 15;
|
11
|
+
}
|
12
|
+
|
13
|
+
message Event {
|
14
|
+
optional int64 time = 1;
|
15
|
+
optional string state = 2;
|
16
|
+
optional string service = 3;
|
17
|
+
optional string host = 4;
|
18
|
+
optional string description = 5;
|
19
|
+
repeated string tags = 7;
|
20
|
+
optional float ttl = 8;
|
21
|
+
repeated Attribute attributes = 9;
|
22
|
+
|
23
|
+
optional sint64 metric_sint64 = 13;
|
24
|
+
optional double metric_d = 14;
|
25
|
+
optional float metric_f = 15;
|
26
|
+
}
|
27
|
+
|
28
|
+
message Query {
|
29
|
+
optional string string = 1;
|
30
|
+
}
|
31
|
+
|
32
|
+
message Msg {
|
33
|
+
optional bool ok = 2;
|
34
|
+
optional string error = 3;
|
35
|
+
repeated State states = 4;
|
36
|
+
optional Query query = 5;
|
37
|
+
repeated Event events = 6;
|
38
|
+
}
|
39
|
+
|
40
|
+
message Attribute {
|
41
|
+
required string key = 1;
|
42
|
+
optional string value = 2;
|
43
|
+
}
|
@@ -0,0 +1,21 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
require "protocol_buffers"
|
4
|
+
require "net/tcp_client"
|
5
|
+
require "English"
|
6
|
+
require 'set'
|
7
|
+
require 'date'
|
8
|
+
|
9
|
+
module Riemann
|
10
|
+
end
|
11
|
+
|
12
|
+
require_relative 'riemann-ruby-experiments/riemann.pb'
|
13
|
+
require_relative 'riemann-ruby-experiments/event.rb'
|
14
|
+
require_relative 'riemann-ruby-experiments/main'
|
15
|
+
|
16
|
+
# I do a lot of testing with pry.
|
17
|
+
if $0 == __FILE__
|
18
|
+
require 'pry'
|
19
|
+
c = Riemann::Experiment::Client.new()
|
20
|
+
binding.pry
|
21
|
+
end
|
@@ -0,0 +1,205 @@
|
|
1
|
+
module Riemann::Experiment
|
2
|
+
class Event
|
3
|
+
attr_accessor :attribute_names
|
4
|
+
attr_accessor :protobuf
|
5
|
+
|
6
|
+
# Provide defaults on initialization
|
7
|
+
def initialize()
|
8
|
+
@attrs = []
|
9
|
+
@cached_attrs = {}
|
10
|
+
end
|
11
|
+
|
12
|
+
def setup(client)
|
13
|
+
@service = client&.default_service
|
14
|
+
@host = client&.default_host
|
15
|
+
@tags = client&.default_tags
|
16
|
+
@ttl = client&.default_ttl
|
17
|
+
@protobuf = ::Event.new
|
18
|
+
end
|
19
|
+
|
20
|
+
def build(**fields)
|
21
|
+
fields.each_pair {|k, v|
|
22
|
+
self.send("#{k}=".to_sym, v)
|
23
|
+
}
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.load(pb)
|
27
|
+
e = self.new()
|
28
|
+
if !pb.is_a?(::Event)
|
29
|
+
raise ArgumentError, "Not an Event protocol buffer object"
|
30
|
+
end
|
31
|
+
e.protobuf = pb
|
32
|
+
pb.attributes.each {|a|
|
33
|
+
e.attribute_set(a.key, a.value)
|
34
|
+
}
|
35
|
+
e
|
36
|
+
end
|
37
|
+
|
38
|
+
def attribute_set(name, value)
|
39
|
+
if attribute_get_value(name)
|
40
|
+
a = protobuf.attributes&.detect {|a| a.key == name }
|
41
|
+
a.value = value
|
42
|
+
else
|
43
|
+
a = Attribute.new
|
44
|
+
a.key = name
|
45
|
+
a.value = value
|
46
|
+
protobuf.attributes << a
|
47
|
+
end
|
48
|
+
@cached_attrs[name] = value
|
49
|
+
end
|
50
|
+
|
51
|
+
def attribute_get_value(name)
|
52
|
+
@cached_attrs.fetch(name) {
|
53
|
+
a = protobuf.attributes&.detect {|a| a.key == name }
|
54
|
+
if !a.nil?
|
55
|
+
@cached_attrs[name] = a.value
|
56
|
+
retval = a.value
|
57
|
+
else
|
58
|
+
retval = yield(name) if block_given?
|
59
|
+
end
|
60
|
+
retval
|
61
|
+
}
|
62
|
+
end
|
63
|
+
|
64
|
+
def each_attribute
|
65
|
+
return enum_for(:each_attribute) unless block_given?
|
66
|
+
protobuf.attributes.each {|a|
|
67
|
+
yield(a.key, a.value)
|
68
|
+
}
|
69
|
+
end
|
70
|
+
|
71
|
+
def time=(time)
|
72
|
+
case time
|
73
|
+
when ::Time
|
74
|
+
protobuf.time = time.to_i
|
75
|
+
when ::DateTime
|
76
|
+
protobuf.time = time.to_time.to_i
|
77
|
+
else
|
78
|
+
protobuf.time = time
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def time
|
83
|
+
Time.at(protobuf.time)
|
84
|
+
end
|
85
|
+
|
86
|
+
def service=(service)
|
87
|
+
protobuf.service = service.to_s
|
88
|
+
end
|
89
|
+
|
90
|
+
def service
|
91
|
+
s = protobuf.service
|
92
|
+
(s != "") ? s : nil
|
93
|
+
end
|
94
|
+
|
95
|
+
def state=(s)
|
96
|
+
protobuf.state = s
|
97
|
+
end
|
98
|
+
|
99
|
+
def state
|
100
|
+
s = protobuf.state
|
101
|
+
(s != "") ? s : nil
|
102
|
+
end
|
103
|
+
|
104
|
+
def host=(host)
|
105
|
+
protobuf.host = host.to_s
|
106
|
+
end
|
107
|
+
|
108
|
+
def host
|
109
|
+
h = protobuf.host
|
110
|
+
h != "" ? h : nil
|
111
|
+
end
|
112
|
+
|
113
|
+
def description=(d)
|
114
|
+
protobuf.description = d.to_s
|
115
|
+
end
|
116
|
+
|
117
|
+
def description
|
118
|
+
d = protobuf.description
|
119
|
+
d != "" ? d : nil
|
120
|
+
end
|
121
|
+
|
122
|
+
def ttl=(ttl)
|
123
|
+
protobuf.ttl = ttl.to_f
|
124
|
+
end
|
125
|
+
|
126
|
+
def ttl
|
127
|
+
t = protobuf.ttl
|
128
|
+
t != "" ? t : nil
|
129
|
+
end
|
130
|
+
|
131
|
+
def add_tags(*tags)
|
132
|
+
@tags = [] if @tags.nil?
|
133
|
+
tags.each {|t| @tags.push(t.to_s) }
|
134
|
+
end
|
135
|
+
|
136
|
+
def tags
|
137
|
+
protobuf.tags
|
138
|
+
end
|
139
|
+
|
140
|
+
def metric=(m)
|
141
|
+
case m
|
142
|
+
when Integer
|
143
|
+
protobuf.metric_sint64 = m
|
144
|
+
when Float
|
145
|
+
protobuf.metric_d = m
|
146
|
+
end # BigDecimal? Anything else?
|
147
|
+
end
|
148
|
+
|
149
|
+
def metric
|
150
|
+
protobuf.metric_sint64 || protobuf.metric_d || protobuf.metric_f
|
151
|
+
end
|
152
|
+
|
153
|
+
def maybe_apply_defaults
|
154
|
+
if protobuf.service == ""
|
155
|
+
@service ||= "#{$0};#{$PID}"
|
156
|
+
protobuf.service = @service
|
157
|
+
end
|
158
|
+
if protobuf.host == ""
|
159
|
+
protobuf.host = @host
|
160
|
+
end
|
161
|
+
|
162
|
+
if !@tags.nil?
|
163
|
+
protobuf.tags = @tags
|
164
|
+
end
|
165
|
+
if !@ttl.nil?
|
166
|
+
protobuf.ttl = @ttl
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
def to_s
|
171
|
+
maybe_apply_defaults
|
172
|
+
protobuf.to_s
|
173
|
+
end
|
174
|
+
|
175
|
+
alias_method :to_sym, :to_s
|
176
|
+
alias_method :dump, :to_s
|
177
|
+
|
178
|
+
def respond_to?(m, include_private = false)
|
179
|
+
ms = m.to_s
|
180
|
+
mnoeq = ms[0..-2]
|
181
|
+
if ms.end_with?("=") && ms.length >= 2
|
182
|
+
true
|
183
|
+
elsif attribute_get_value(ms)
|
184
|
+
true
|
185
|
+
else
|
186
|
+
super
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
def method_missing(m, *rest, &blk)
|
191
|
+
ms = m.to_s
|
192
|
+
if ms.end_with?("=") && ms.length >= 2
|
193
|
+
attribute_set(ms[0..-2], rest.first.to_s)
|
194
|
+
else
|
195
|
+
val = attribute_get_value(ms)
|
196
|
+
if val.nil?
|
197
|
+
super
|
198
|
+
else
|
199
|
+
val
|
200
|
+
end
|
201
|
+
end
|
202
|
+
end
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
@@ -0,0 +1,117 @@
|
|
1
|
+
module Riemann::Experiment
|
2
|
+
class Client < Net::TCPClient
|
3
|
+
attr_reader :keepalive_active, :keepalive_idle, :keepalive_interval, :keepalive_count
|
4
|
+
attr_accessor :default_host, :default_service, :default_tags, :default_ttl, :pending_events
|
5
|
+
|
6
|
+
# service and host can be assigned to :default here,
|
7
|
+
# to use a string generated from process info and hostname, respectively.
|
8
|
+
def initialize(options = {})
|
9
|
+
@event_fields = Set.new([:time, :service, :host, :description, :metric, :tags, :ttl])
|
10
|
+
@msg_fields = Set.new([:ok, :error, :states, :query, :events])
|
11
|
+
@generated_service = "#{$0};#{$PID}"
|
12
|
+
|
13
|
+
default_opts = {server: "localhost:5555",
|
14
|
+
connect_timeout: 2,
|
15
|
+
read_timeout: 2,
|
16
|
+
write_timeout: 2 }
|
17
|
+
|
18
|
+
@default_service = options.delete(:service)
|
19
|
+
@default_host = options.delete(:host) || Socket.gethostname
|
20
|
+
@default_tags = options.delete(:tags)
|
21
|
+
@default_ttl = options.delete(:ttl)
|
22
|
+
@pending_events = []
|
23
|
+
|
24
|
+
@keepalive_active = options.delete(:keepalive_active) || true
|
25
|
+
@keepalive_idle = options.delete(:keepalive_idle) || 60
|
26
|
+
@keepalive_interval = options.delete(:keepalive_interval) || 30
|
27
|
+
@keepalive_count = options.delete(:keepalive_count) || 5
|
28
|
+
|
29
|
+
options = default_opts.merge(options)
|
30
|
+
options.delete(:buffered)
|
31
|
+
options[:buffered] = false
|
32
|
+
super(options)
|
33
|
+
setsockopt(::Socket::SOL_SOCKET, ::Socket::SO_KEEPALIVE, @keepalive_active)
|
34
|
+
setsockopt(::Socket::SOL_TCP, ::Socket::TCP_KEEPIDLE , @keepalive_idle)
|
35
|
+
setsockopt(::Socket::SOL_TCP, ::Socket::TCP_KEEPINTVL, @keepalive_interval)
|
36
|
+
setsockopt(::Socket::SOL_TCP, ::Socket::TCP_KEEPCNT , @keepalive_count)
|
37
|
+
end
|
38
|
+
|
39
|
+
def add_event(*rest)
|
40
|
+
e = Riemann::Experiment::Event.new()
|
41
|
+
e.setup(self)
|
42
|
+
e.time = Time.now.to_i
|
43
|
+
e.build(*rest)
|
44
|
+
@pending_events.push(e)
|
45
|
+
end
|
46
|
+
|
47
|
+
def send_message(**p)
|
48
|
+
m = ::Msg.new
|
49
|
+
if p[:ok] == true
|
50
|
+
m.ok = true
|
51
|
+
elsif p[:ok] == false
|
52
|
+
m.ok = false
|
53
|
+
end
|
54
|
+
m.error = p[:error] if p.has_key?(:error)
|
55
|
+
if p.has_key?(:query)
|
56
|
+
q = Query.new
|
57
|
+
q.string = p[:query]
|
58
|
+
m.query = q
|
59
|
+
end
|
60
|
+
@pending_events.each {|e|
|
61
|
+
e.maybe_apply_defaults
|
62
|
+
m.events << e.protobuf
|
63
|
+
}
|
64
|
+
r = exchange(m.to_s)
|
65
|
+
@pending_events = []
|
66
|
+
r
|
67
|
+
end
|
68
|
+
|
69
|
+
# Query the riemann server for events.
|
70
|
+
# Skips the queue of otherwise pending events.
|
71
|
+
def [](querystring)
|
72
|
+
m = Msg.new
|
73
|
+
q = Query.new
|
74
|
+
q.string = querystring
|
75
|
+
m.query = q
|
76
|
+
r = exchange(m.to_s)
|
77
|
+
if !r.nil? && r.ok == true
|
78
|
+
r.events.map {|e| Riemann::Experiment::Event.load(e) }
|
79
|
+
else
|
80
|
+
[]
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
# Writes a riemann message to socket.
|
85
|
+
# You probably want to use exchange, because it receives a
|
86
|
+
# response from
|
87
|
+
# yields to a block if the write times out (and re-raises the WriteTimeout)
|
88
|
+
def put(message)
|
89
|
+
msg = message.to_s
|
90
|
+
out_packet = [msg.length].pack('N') + msg
|
91
|
+
write(out_packet)
|
92
|
+
rescue Net::TCPClient::WriteTimeout => e
|
93
|
+
yield if block_given?
|
94
|
+
raise e
|
95
|
+
end
|
96
|
+
|
97
|
+
# Receives a response from a riemann server.
|
98
|
+
# This method will raise ProtocolBuffers::DecoderError on invalid data.
|
99
|
+
# yields to a block if the read times out (and re-raises the ReadTimeout)
|
100
|
+
def get()
|
101
|
+
in_len = read(4).unpack("N").first
|
102
|
+
in_packet = read(in_len)
|
103
|
+
Msg.parse(in_packet)
|
104
|
+
rescue Net::TCPClient::ReadTimeout => e
|
105
|
+
yield if block_given?
|
106
|
+
raise e
|
107
|
+
end
|
108
|
+
|
109
|
+
def exchange(message)
|
110
|
+
retry_on_connection_failure do
|
111
|
+
put(message)
|
112
|
+
get
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
@@ -0,0 +1,65 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
3
|
+
|
4
|
+
require 'protocol_buffers'
|
5
|
+
|
6
|
+
# forward declarations
|
7
|
+
class State < ::ProtocolBuffers::Message; end
|
8
|
+
class Event < ::ProtocolBuffers::Message; end
|
9
|
+
class Query < ::ProtocolBuffers::Message; end
|
10
|
+
class Msg < ::ProtocolBuffers::Message; end
|
11
|
+
class Attribute < ::ProtocolBuffers::Message; end
|
12
|
+
|
13
|
+
class State < ::ProtocolBuffers::Message
|
14
|
+
set_fully_qualified_name "State"
|
15
|
+
|
16
|
+
optional :int64, :time, 1
|
17
|
+
optional :string, :state, 2
|
18
|
+
optional :string, :service, 3
|
19
|
+
optional :string, :host, 4
|
20
|
+
optional :string, :description, 5
|
21
|
+
optional :bool, :once, 6
|
22
|
+
repeated :string, :tags, 7
|
23
|
+
optional :float, :ttl, 8
|
24
|
+
optional :float, :metric_f, 15
|
25
|
+
end
|
26
|
+
|
27
|
+
class Event < ::ProtocolBuffers::Message
|
28
|
+
set_fully_qualified_name "Event"
|
29
|
+
|
30
|
+
optional :int64, :time, 1
|
31
|
+
optional :string, :state, 2
|
32
|
+
optional :string, :service, 3
|
33
|
+
optional :string, :host, 4
|
34
|
+
optional :string, :description, 5
|
35
|
+
repeated :string, :tags, 7
|
36
|
+
optional :float, :ttl, 8
|
37
|
+
repeated ::Attribute, :attributes, 9
|
38
|
+
optional :sint64, :metric_sint64, 13
|
39
|
+
optional :double, :metric_d, 14
|
40
|
+
optional :float, :metric_f, 15
|
41
|
+
end
|
42
|
+
|
43
|
+
class Query < ::ProtocolBuffers::Message
|
44
|
+
set_fully_qualified_name "Query"
|
45
|
+
|
46
|
+
optional :string, :string, 1
|
47
|
+
end
|
48
|
+
|
49
|
+
class Msg < ::ProtocolBuffers::Message
|
50
|
+
set_fully_qualified_name "Msg"
|
51
|
+
|
52
|
+
optional :bool, :ok, 2
|
53
|
+
optional :string, :error, 3
|
54
|
+
repeated ::State, :states, 4
|
55
|
+
optional ::Query, :query, 5
|
56
|
+
repeated ::Event, :events, 6
|
57
|
+
end
|
58
|
+
|
59
|
+
class Attribute < ::ProtocolBuffers::Message
|
60
|
+
set_fully_qualified_name "Attribute"
|
61
|
+
|
62
|
+
required :string, :key, 1
|
63
|
+
optional :string, :value, 2
|
64
|
+
end
|
65
|
+
|
data/project.yaml
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = "riemann-ruby-experiments"
|
3
|
+
s.version = "0.0.3"
|
4
|
+
s.licenses = ["LGPL-3.0"]
|
5
|
+
s.platform = Gem::Platform::RUBY
|
6
|
+
s.summary = "A Riemann client for ruby"
|
7
|
+
s.description = "Just another client, to experiment with."
|
8
|
+
s.authors = ["Chris Riddoch"]
|
9
|
+
s.email = "riddochc@gmail.com"
|
10
|
+
s.date = "2016-05-30"
|
11
|
+
s.files = ["Gemfile",
|
12
|
+
"README.adoc",
|
13
|
+
"Rakefile",
|
14
|
+
"data/riemann.proto",
|
15
|
+
"lib/riemann-ruby-experiments/event.rb",
|
16
|
+
"lib/riemann-ruby-experiments/main.rb",
|
17
|
+
"lib/riemann-ruby-experiments/riemann.pb.rb",
|
18
|
+
"lib/riemann-ruby-experiments/version.rb",
|
19
|
+
"lib/riemann-ruby-experiments.rb",
|
20
|
+
"project.yaml",
|
21
|
+
"riemann-ruby-experiments.gemspec"]
|
22
|
+
s.homepage = "https://syntacticsugar.org/projects/riemann-ruby-experiments"
|
23
|
+
|
24
|
+
s.add_dependency "ruby-protocol-buffers", ">= 1.6.1"
|
25
|
+
s.add_dependency "net_tcp_client", ">= 2.0.0"
|
26
|
+
|
27
|
+
s.add_development_dependency "rake", "=10.5.0"
|
28
|
+
s.add_development_dependency "asciidoctor", "=1.5.5.dev"
|
29
|
+
s.add_development_dependency "yard", "=0.8.7.6"
|
30
|
+
s.add_development_dependency "pry", "=0.10.3"
|
31
|
+
end
|
metadata
ADDED
@@ -0,0 +1,139 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: riemann-ruby-experiments
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.3
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Chris Riddoch
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-05-30 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: ruby-protocol-buffers
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 1.6.1
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 1.6.1
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: net_tcp_client
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 2.0.0
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 2.0.0
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 10.5.0
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 10.5.0
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: asciidoctor
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - '='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 1.5.5.dev
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - '='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 1.5.5.dev
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: yard
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - '='
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 0.8.7.6
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - '='
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 0.8.7.6
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: pry
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - '='
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: 0.10.3
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - '='
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: 0.10.3
|
97
|
+
description: Just another client, to experiment with.
|
98
|
+
email: riddochc@gmail.com
|
99
|
+
executables: []
|
100
|
+
extensions: []
|
101
|
+
extra_rdoc_files: []
|
102
|
+
files:
|
103
|
+
- Gemfile
|
104
|
+
- README.adoc
|
105
|
+
- Rakefile
|
106
|
+
- data/riemann.proto
|
107
|
+
- lib/riemann-ruby-experiments.rb
|
108
|
+
- lib/riemann-ruby-experiments/event.rb
|
109
|
+
- lib/riemann-ruby-experiments/main.rb
|
110
|
+
- lib/riemann-ruby-experiments/riemann.pb.rb
|
111
|
+
- lib/riemann-ruby-experiments/version.rb
|
112
|
+
- project.yaml
|
113
|
+
- riemann-ruby-experiments.gemspec
|
114
|
+
homepage: https://syntacticsugar.org/projects/riemann-ruby-experiments
|
115
|
+
licenses:
|
116
|
+
- LGPL-3.0
|
117
|
+
metadata: {}
|
118
|
+
post_install_message:
|
119
|
+
rdoc_options: []
|
120
|
+
require_paths:
|
121
|
+
- lib
|
122
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
123
|
+
requirements:
|
124
|
+
- - ">="
|
125
|
+
- !ruby/object:Gem::Version
|
126
|
+
version: '0'
|
127
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
requirements: []
|
133
|
+
rubyforge_project:
|
134
|
+
rubygems_version: 2.5.1
|
135
|
+
signing_key:
|
136
|
+
specification_version: 4
|
137
|
+
summary: A Riemann client for ruby
|
138
|
+
test_files: []
|
139
|
+
has_rdoc:
|