brigade-monitor 0.0.6 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/brigade-monitor +16 -74
- data/lib/brigade/monitor.rb +1 -0
- data/lib/brigade/monitor/api.rb +4 -3
- data/lib/brigade/monitor/monitor.rb +136 -0
- data/lib/brigade/monitor/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0f4f620255dcb2564130a447d620fa4a87ed24db
|
4
|
+
data.tar.gz: 77758c22724815b610be70234fcff7e471bdce34
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b276d063318d5b298d90d395d478ce3de9f4996f68f09a0af893ff01bc7d415f4eef6fbf37a03c7bddb0517db3069b43e6335f29001d0a7302b85f9d2cbf4a05
|
7
|
+
data.tar.gz: f9cdaabf396ad617885e1c6593492cb69d2d94fca49ff6acc71fd0e598d2a846e9cc042e0a91acad36672e7f87217351b8af6531833f178dc7e21a3ea44c3a3b
|
data/bin/brigade-monitor
CHANGED
@@ -3,11 +3,15 @@
|
|
3
3
|
require 'awesome_print'
|
4
4
|
require 'brigade/monitor'
|
5
5
|
require 'cgminer/api'
|
6
|
+
require 'logger'
|
6
7
|
require 'optparse'
|
7
8
|
require 'yaml'
|
8
9
|
|
9
10
|
me = File.basename(__FILE__)
|
10
11
|
|
12
|
+
log = Logger.new(STDOUT)
|
13
|
+
log.level = Logger::WARN
|
14
|
+
|
11
15
|
options = {}
|
12
16
|
optparse = OptionParser.new do |opts|
|
13
17
|
opts.banner = "Usage: #{me} [options]"
|
@@ -17,6 +21,14 @@ optparse = OptionParser.new do |opts|
|
|
17
21
|
opts.on('-k', '--key API-KEY', String, 'Brigade API key') do |key|
|
18
22
|
options[:key] = key
|
19
23
|
end
|
24
|
+
opts.on('-d', '--debug LEVEL', [:debug, :info], 'Debug level (DEBUG, INFO)') do |dbg|
|
25
|
+
case dbg
|
26
|
+
when :debug
|
27
|
+
log.level = Logger::DEBUG
|
28
|
+
when :info
|
29
|
+
log.level = Logger::INFO
|
30
|
+
end
|
31
|
+
end
|
20
32
|
opts.on('-v', '--version', 'Print application version') do
|
21
33
|
puts "#{me} v#{Brigade::Monitor::VERSION}"
|
22
34
|
exit
|
@@ -34,81 +46,11 @@ end
|
|
34
46
|
key = options.fetch(:key, config['api-key'])
|
35
47
|
fail 'Brigade API key is required' if key.nil?
|
36
48
|
|
37
|
-
# XXX connect once, check API key validity
|
38
|
-
|
39
49
|
# build a hash-o-miner clients
|
40
50
|
miners = config['miners'].map do |miner|
|
41
|
-
|
42
|
-
|
43
|
-
client: CGMiner::API::Client.new(miner[1]['host'], miner[1]['port'])
|
44
|
-
}
|
51
|
+
client = CGMiner::API::Client.new(miner[1]['host'], miner[1]['port'])
|
52
|
+
{ name: miner[0], client: client }
|
45
53
|
end
|
46
54
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
updates = []
|
51
|
-
|
52
|
-
miners.each do |miner|
|
53
|
-
begin
|
54
|
-
summary = miner[:client].summary
|
55
|
-
devs = miner[:client].devs
|
56
|
-
pools = miner[:client].pools
|
57
|
-
|
58
|
-
# XXX check status replies on each command?
|
59
|
-
|
60
|
-
update = {
|
61
|
-
host: miner[:name],
|
62
|
-
uptime: summary.body[0]['Elapsed'],
|
63
|
-
mhash: summary.body[0]['MHS 5s'],
|
64
|
-
rejectpct: summary.body[0]['Pool Rejected%'],
|
65
|
-
asics: [],
|
66
|
-
fpgas: [],
|
67
|
-
gpus: [],
|
68
|
-
pools: []
|
69
|
-
}
|
70
|
-
|
71
|
-
devs.body.each do |dev|
|
72
|
-
if dev.has_key? 'GPU'
|
73
|
-
update[:gpus] << {
|
74
|
-
index: dev['GPU'],
|
75
|
-
temperature: dev['Temperature'],
|
76
|
-
enabled: dev['Enabled'] == 'Y',
|
77
|
-
status: :ok, # XXX enumerate statuses
|
78
|
-
uptime: dev['Device Elapsed'],
|
79
|
-
mhash: dev['MHS 5s'],
|
80
|
-
rejectpct: dev['Device Rejected%']
|
81
|
-
}
|
82
|
-
else
|
83
|
-
puts "Skipped device: #{dev}"
|
84
|
-
end
|
85
|
-
end
|
86
|
-
|
87
|
-
pools.body.each do |pool|
|
88
|
-
update[:pools] << {
|
89
|
-
index: pool['POOL'],
|
90
|
-
url: pool['URL'],
|
91
|
-
status: :ok, # XXX enumerate statuses
|
92
|
-
active: pool['Stratum Active'],
|
93
|
-
rejectpct: pool['Pool Rejected%']
|
94
|
-
}
|
95
|
-
end
|
96
|
-
|
97
|
-
updates << update
|
98
|
-
rescue Net::OpenTimeout
|
99
|
-
puts "Timed out: #{miner}"
|
100
|
-
# XXX put something in the update to indicate it barfed
|
101
|
-
rescue Exception => e
|
102
|
-
puts "Some other error: #{miner} (#{e.class})"
|
103
|
-
# XXX put something in the update to indicate it barfed
|
104
|
-
end
|
105
|
-
end
|
106
|
-
|
107
|
-
response = api.hosts(updates)
|
108
|
-
unless 200 == response.code
|
109
|
-
puts "XXX: response: #{response.code}"
|
110
|
-
end
|
111
|
-
|
112
|
-
sleep 60
|
113
|
-
|
114
|
-
end
|
55
|
+
mon = Brigade::Monitor::Monitor.new(key, miners, log)
|
56
|
+
mon.run
|
data/lib/brigade/monitor.rb
CHANGED
data/lib/brigade/monitor/api.rb
CHANGED
@@ -8,8 +8,9 @@ module Brigade
|
|
8
8
|
include HTTParty
|
9
9
|
base_uri 'https://app.brigade.io/api/v1'
|
10
10
|
|
11
|
-
def initialize(key)
|
11
|
+
def initialize(key, logger)
|
12
12
|
@key = key
|
13
|
+
@log = logger
|
13
14
|
end
|
14
15
|
|
15
16
|
def hosts(data)
|
@@ -19,8 +20,8 @@ module Brigade
|
|
19
20
|
private
|
20
21
|
|
21
22
|
def command(command, params)
|
22
|
-
|
23
|
-
self.class.post(command, query: params, verify: false)
|
23
|
+
@log.debug("Posting command: #{command}, params: #{params}")
|
24
|
+
self.class.post(command, query: params.merge({ token: @key }), verify: false)
|
24
25
|
end
|
25
26
|
|
26
27
|
end
|
@@ -0,0 +1,136 @@
|
|
1
|
+
module Brigade
|
2
|
+
module Monitor
|
3
|
+
|
4
|
+
class Monitor
|
5
|
+
|
6
|
+
def initialize(key, miners, logger)
|
7
|
+
@key = key
|
8
|
+
@miners = miners
|
9
|
+
@log = logger
|
10
|
+
end
|
11
|
+
|
12
|
+
def run
|
13
|
+
api = Brigade::Monitor::API.new(@key, @log)
|
14
|
+
|
15
|
+
@log.info("Monitoring #{@miners.length} miners")
|
16
|
+
loop do
|
17
|
+
updates = []
|
18
|
+
|
19
|
+
@miners.each do |miner|
|
20
|
+
@log.debug("Beginning miner: #{miner}")
|
21
|
+
|
22
|
+
begin
|
23
|
+
updates << get_update(miner)
|
24
|
+
rescue Net::OpenTimeout => e
|
25
|
+
@log.warn("Net::OpenTimeout building update for #{miner[:name]} (#{e})")
|
26
|
+
# XXX put something in the update to indicate it barfed
|
27
|
+
rescue Exception => e
|
28
|
+
@log.error("Exception building update for #{miner[:name]} (#{e})")
|
29
|
+
# XXX put something in the update to indicate it barfed
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
if updates.empty?
|
34
|
+
@log.info("Updates empty, not submitting")
|
35
|
+
else
|
36
|
+
@log.info("Updates available (#{updates.length}), submitting")
|
37
|
+
begin
|
38
|
+
tries ||= 3
|
39
|
+
response = api.hosts(updates)
|
40
|
+
rescue Exception => e
|
41
|
+
@log.error("Exception submitting updates (#{e})")
|
42
|
+
unless (tries -= 1).zero?
|
43
|
+
@log.error('Retrying...')
|
44
|
+
retry
|
45
|
+
else
|
46
|
+
@log.error('Giving up for this update...')
|
47
|
+
end
|
48
|
+
else
|
49
|
+
if 401 == response.code
|
50
|
+
@log.error('Unauthorized response submitting updates, check API key!')
|
51
|
+
return
|
52
|
+
end
|
53
|
+
@log.info("Submitted updates (status: #{response.code})")
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
sleep 60
|
58
|
+
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def get_update(miner)
|
63
|
+
summary = miner[:client].summary
|
64
|
+
devs = miner[:client].devs
|
65
|
+
pools = miner[:client].pools
|
66
|
+
|
67
|
+
# XXX check status replies on each command?
|
68
|
+
|
69
|
+
update = {
|
70
|
+
host: miner[:name],
|
71
|
+
uptime: summary.body[0]['Elapsed'],
|
72
|
+
mhash: summary.body[0]['MHS av'],
|
73
|
+
rejectpct: summary.body[0]['Pool Rejected%'],
|
74
|
+
asics: [],
|
75
|
+
fpgas: [],
|
76
|
+
gpus: [],
|
77
|
+
pools: []
|
78
|
+
}
|
79
|
+
|
80
|
+
devs.body.each do |dev|
|
81
|
+
if dev.has_key? 'GPU'
|
82
|
+
update[:gpus] << {
|
83
|
+
index: dev['GPU'],
|
84
|
+
temperature: dev['Temperature'],
|
85
|
+
enabled: dev['Enabled'] == 'Y',
|
86
|
+
status: :ok, # XXX enumerate statuses
|
87
|
+
uptime: dev['Device Elapsed'],
|
88
|
+
mhash: dev['MHS av'],
|
89
|
+
hwerrors: dev['Hardware Errors'],
|
90
|
+
rejectpct: dev['Device Rejected%']
|
91
|
+
}
|
92
|
+
elsif dev.has_key? 'ASC'
|
93
|
+
update[:asics] << {
|
94
|
+
index: dev['ASC'],
|
95
|
+
temperature: dev['Temperature'],
|
96
|
+
enabled: dev['Enabled'] == 'Y',
|
97
|
+
status: :ok, # XXX enumerate statuses
|
98
|
+
uptime: dev['Device Elapsed'],
|
99
|
+
mhash: dev['MHS av'],
|
100
|
+
hwerrors: dev['Hardware Errors'],
|
101
|
+
rejectpct: dev['Device Rejected%']
|
102
|
+
}
|
103
|
+
elsif dev.has_key? 'PGA'
|
104
|
+
update[:fpgas] << {
|
105
|
+
index: dev['PGA'],
|
106
|
+
temperature: dev['Temperature'],
|
107
|
+
enabled: dev['Enabled'] == 'Y',
|
108
|
+
status: :ok, # XXX enumerate statuses
|
109
|
+
uptime: dev['Device Elapsed'],
|
110
|
+
mhash: dev['MHS av'],
|
111
|
+
hwerrors: dev['Hardware Errors'],
|
112
|
+
rejectpct: dev['Device Rejected%']
|
113
|
+
}
|
114
|
+
else
|
115
|
+
@log.warn("Skipped unknown device: #{dev}")
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
pools.body.each do |pool|
|
120
|
+
update[:pools] << {
|
121
|
+
index: pool['POOL'],
|
122
|
+
url: pool['URL'],
|
123
|
+
status: :ok, # XXX enumerate statuses
|
124
|
+
active: pool['Stratum Active'],
|
125
|
+
rejectpct: pool['Pool Rejected%']
|
126
|
+
}
|
127
|
+
end
|
128
|
+
|
129
|
+
@log.debug("Built update: #{update}")
|
130
|
+
update
|
131
|
+
end
|
132
|
+
|
133
|
+
end
|
134
|
+
|
135
|
+
end
|
136
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: brigade-monitor
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nick Veys
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-01-
|
11
|
+
date: 2014-01-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -168,6 +168,7 @@ files:
|
|
168
168
|
- brigade-monitor.gemspec
|
169
169
|
- lib/brigade/monitor.rb
|
170
170
|
- lib/brigade/monitor/api.rb
|
171
|
+
- lib/brigade/monitor/monitor.rb
|
171
172
|
- lib/brigade/monitor/version.rb
|
172
173
|
- sample-config.yaml
|
173
174
|
- spec/spec_helper.rb
|