ffwd-google-cloud 0.4.2 → 0.4.3
Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2460bbc3a9e1c03e415c76926df07e8fb7f1f03a
|
4
|
+
data.tar.gz: 4c8c48826dde0239a18b0f50aa15342420a4d5da
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f209e4155c96938adc579c63eb0fd8ccdf05b9f10eab55139f4c541dfd47db23bdf7a5d8f5a8795a863932b1b2cd63c1911f747dc3b611e0415813dc0f7995d3
|
7
|
+
data.tar.gz: 899ee149a5e79621a90ca817b9d79446784f21f7c38bfcd197f2e25817ca05ce5e1f8097566d3fcdb05ea1d158de6e8c577057e2044116add5f4011a42b71754
|
@@ -36,9 +36,10 @@ module FFWD::Plugin::GoogleCloud
|
|
36
36
|
@project = c[:project]
|
37
37
|
@client_id = c[:client_id]
|
38
38
|
@scope = c[:scope]
|
39
|
+
@debug = c[:debug]
|
39
40
|
|
40
|
-
@
|
41
|
-
@
|
41
|
+
@api_pipeline = nil
|
42
|
+
@metadata_pipeline = nil
|
42
43
|
@token = nil
|
43
44
|
@expires_at = nil
|
44
45
|
# list of blocks waiting for a token.
|
@@ -71,7 +72,7 @@ module FFWD::Plugin::GoogleCloud
|
|
71
72
|
|
72
73
|
log.debug "Requesting token"
|
73
74
|
|
74
|
-
http = @
|
75
|
+
http = @metadata_pipeline.get(
|
75
76
|
:path => @acquire,
|
76
77
|
:query => {:client_id => @client_id, :scope => @scope})
|
77
78
|
|
@@ -100,7 +101,7 @@ module FFWD::Plugin::GoogleCloud
|
|
100
101
|
end
|
101
102
|
|
102
103
|
def active?
|
103
|
-
not @
|
104
|
+
not @api_pipeline.nil? and not @metadata_pipeline.nil?
|
104
105
|
end
|
105
106
|
|
106
107
|
def verify_descriptors(metrics, &block)
|
@@ -122,17 +123,21 @@ module FFWD::Plugin::GoogleCloud
|
|
122
123
|
missing.each do |m|
|
123
124
|
name = m[:metric]
|
124
125
|
|
125
|
-
|
126
|
-
:name => m[:metric], :description =>
|
126
|
+
descriptor = {
|
127
|
+
:name => m[:metric], :description => "",
|
128
|
+
:labels => Utils.extract_labels(m[:labels]),
|
127
129
|
:typeDescriptor => {:metricType => "gauge", :valueType => "double"}
|
128
130
|
}
|
129
131
|
|
132
|
+
descriptor = JSON.dump(descriptor)
|
133
|
+
|
130
134
|
log.info "Creating descriptor for: #{name}"
|
131
135
|
|
132
136
|
all << with_token{|token|
|
133
137
|
head = Hash[HEADER_BASE]
|
134
138
|
head['Authorization'] = "Bearer #{token}"
|
135
|
-
p = new_proxy(
|
139
|
+
p = new_proxy(api_request.post(
|
140
|
+
:path => @md_api, :head => head, :body => descriptor))
|
136
141
|
|
137
142
|
p.callback do
|
138
143
|
log.info "Created (caching): #{name}"
|
@@ -140,7 +145,7 @@ module FFWD::Plugin::GoogleCloud
|
|
140
145
|
end
|
141
146
|
|
142
147
|
p.errback do |error|
|
143
|
-
log.error "Failed to create descriptor (#{error}): #{
|
148
|
+
log.error "Failed to create descriptor (#{error}): #{descriptor}"
|
144
149
|
end
|
145
150
|
|
146
151
|
p
|
@@ -159,57 +164,51 @@ module FFWD::Plugin::GoogleCloud
|
|
159
164
|
SingleProxy.new all
|
160
165
|
end
|
161
166
|
|
167
|
+
def metadata_request
|
168
|
+
if @debug
|
169
|
+
return DebugRequest.new(@metadata_url, :response => {
|
170
|
+
:accessToken => "FAKE", :expiresAt => (Time.now.to_i + 3600)})
|
171
|
+
end
|
172
|
+
|
173
|
+
EM::HttpRequest.new(@metadata_url)
|
174
|
+
end
|
175
|
+
|
162
176
|
# avoid pipelining requests by creating a new handle for each
|
163
|
-
def
|
177
|
+
def api_request
|
178
|
+
if @debug
|
179
|
+
return DebugRequest.new(@api_url, :responses => {
|
180
|
+
[:get, @md_api] => {"metrics" => []},
|
181
|
+
[:post, @write_api] => {}
|
182
|
+
})
|
183
|
+
end
|
184
|
+
|
164
185
|
EM::HttpRequest.new(@api_url)
|
165
186
|
end
|
166
187
|
|
167
188
|
def connect
|
168
|
-
@
|
169
|
-
@
|
170
|
-
|
171
|
-
with_token do |token|
|
172
|
-
log.info "Downloading metric descriptors"
|
173
|
-
|
174
|
-
head = Hash[HEADER_BASE]
|
175
|
-
head['Authorization'] = "Bearer #{token}"
|
176
|
-
req = @api_c.get(:path => @md_api, :head => head)
|
177
|
-
p = new_proxy(req)
|
178
|
-
|
179
|
-
p.callback do
|
180
|
-
res = JSON.load(req.response)
|
181
|
-
|
182
|
-
log.info "Downloaded #{res["metrics"].length} descriptor(s)"
|
183
|
-
|
184
|
-
res["metrics"].each do |d|
|
185
|
-
@md_cache[d["name"]] = true
|
186
|
-
end
|
187
|
-
end
|
188
|
-
|
189
|
-
p.errback do |error|
|
190
|
-
log.error "Failed to download metric descriptors: #{error}"
|
191
|
-
end
|
192
|
-
|
193
|
-
p
|
194
|
-
end
|
189
|
+
@metadata_pipeline = metadata_request
|
190
|
+
@api_pipeline = api_request
|
191
|
+
populate_metadata_cache
|
195
192
|
end
|
196
193
|
|
197
194
|
def close
|
198
|
-
@
|
199
|
-
@
|
195
|
+
@metadata_pipeline.close if @metadata_pipeline
|
196
|
+
@api_pipeline.close if @api_pipeline
|
200
197
|
|
201
|
-
@
|
202
|
-
@
|
198
|
+
@metadata_pipeline = nil
|
199
|
+
@api_pipeline = nil
|
203
200
|
end
|
204
201
|
|
205
202
|
def send metrics
|
206
203
|
dropped, timeseries = Utils.make_timeseries(metrics)
|
207
204
|
|
205
|
+
common_labels = Utils.make_common_labels(metrics)
|
206
|
+
|
208
207
|
if dropped > 0
|
209
208
|
log.warning "Dropped #{dropped} points (duplicate entries)"
|
210
209
|
end
|
211
210
|
|
212
|
-
request = {:timeseries => timeseries}
|
211
|
+
request = {:commonLabels => common_labels, :timeseries => timeseries}
|
213
212
|
metrics = JSON.dump(request)
|
214
213
|
|
215
214
|
verify_descriptors(request) do
|
@@ -221,7 +220,8 @@ module FFWD::Plugin::GoogleCloud
|
|
221
220
|
log.debug "Sending: #{metrics}"
|
222
221
|
end
|
223
222
|
|
224
|
-
new_proxy
|
223
|
+
new_proxy api_request.post(
|
224
|
+
:path => @write_api, :head => head, :body => metrics)
|
225
225
|
end
|
226
226
|
end
|
227
227
|
end
|
@@ -252,6 +252,35 @@ module FFWD::Plugin::GoogleCloud
|
|
252
252
|
def reporter_meta
|
253
253
|
{:component => :google_cloud}
|
254
254
|
end
|
255
|
+
|
256
|
+
private
|
257
|
+
|
258
|
+
def populate_metadata_cache
|
259
|
+
with_token do |token|
|
260
|
+
log.info "Downloading metric descriptors"
|
261
|
+
|
262
|
+
head = Hash[HEADER_BASE]
|
263
|
+
head['Authorization'] = "Bearer #{token}"
|
264
|
+
req = @api_pipeline.get(:path => @md_api, :head => head)
|
265
|
+
p = new_proxy(req)
|
266
|
+
|
267
|
+
p.callback do
|
268
|
+
res = JSON.load(req.response)
|
269
|
+
|
270
|
+
log.info "Downloaded #{res["metrics"].length} descriptor(s)"
|
271
|
+
|
272
|
+
res["metrics"].each do |d|
|
273
|
+
@md_cache[d["name"]] = true
|
274
|
+
end
|
275
|
+
end
|
276
|
+
|
277
|
+
p.errback do |error|
|
278
|
+
log.error "Failed to download metric descriptors: #{error}"
|
279
|
+
end
|
280
|
+
|
281
|
+
p
|
282
|
+
end
|
283
|
+
end
|
255
284
|
end
|
256
285
|
|
257
286
|
class SingleProxy
|
@@ -299,18 +328,30 @@ module FFWD::Plugin::GoogleCloud
|
|
299
328
|
def initialize
|
300
329
|
@callbacks = []
|
301
330
|
@errbacks = []
|
331
|
+
@called = false
|
302
332
|
end
|
303
333
|
|
304
334
|
def callback &block
|
335
|
+
if @called
|
336
|
+
block.call if @called == :call
|
337
|
+
return
|
338
|
+
end
|
339
|
+
|
305
340
|
@callbacks << block
|
306
341
|
end
|
307
342
|
|
308
343
|
def errback &block
|
344
|
+
if @called
|
345
|
+
block.call if @called == :err
|
346
|
+
return
|
347
|
+
end
|
348
|
+
|
309
349
|
@errbacks << block
|
310
350
|
end
|
311
351
|
|
312
352
|
def call
|
313
353
|
@callbacks.each(&:call).clear
|
354
|
+
@called = :call
|
314
355
|
end
|
315
356
|
|
316
357
|
def err error
|
@@ -321,6 +362,8 @@ module FFWD::Plugin::GoogleCloud
|
|
321
362
|
@errbacks.each do |cb|
|
322
363
|
cb.call error
|
323
364
|
end.clear
|
365
|
+
|
366
|
+
@called = :err
|
324
367
|
end
|
325
368
|
|
326
369
|
def into other
|
@@ -328,4 +371,61 @@ module FFWD::Plugin::GoogleCloud
|
|
328
371
|
callback { other.call }
|
329
372
|
end
|
330
373
|
end
|
374
|
+
|
375
|
+
class DebugRequest
|
376
|
+
include FFWD::Logging
|
377
|
+
|
378
|
+
class Callback
|
379
|
+
class ResponseHeader
|
380
|
+
attr_reader :status
|
381
|
+
|
382
|
+
def initialize status
|
383
|
+
@status = status
|
384
|
+
end
|
385
|
+
end
|
386
|
+
|
387
|
+
attr_reader :response
|
388
|
+
|
389
|
+
def initialize response
|
390
|
+
@response = response
|
391
|
+
end
|
392
|
+
|
393
|
+
def callback &block
|
394
|
+
block.call
|
395
|
+
end
|
396
|
+
|
397
|
+
def response_header
|
398
|
+
ResponseHeader.new 200
|
399
|
+
end
|
400
|
+
|
401
|
+
def errback █ end
|
402
|
+
end
|
403
|
+
|
404
|
+
def initialize url, params={}
|
405
|
+
@url = url
|
406
|
+
@response = JSON.dump(params[:response] || {})
|
407
|
+
@responses = Hash[(params[:responses] || {}).map{|k, v| [k, JSON.dump(v)]}]
|
408
|
+
end
|
409
|
+
|
410
|
+
def post params={}
|
411
|
+
log_request :post, params
|
412
|
+
end
|
413
|
+
|
414
|
+
def get params={}
|
415
|
+
log_request :get, params
|
416
|
+
end
|
417
|
+
|
418
|
+
# do nothing
|
419
|
+
def close; end
|
420
|
+
|
421
|
+
private
|
422
|
+
|
423
|
+
def log_request method, params
|
424
|
+
path = params.delete(:path) || ""
|
425
|
+
body = params.delete(:body)
|
426
|
+
log.debug "#{method} #{@url}#{path}: #{params}"
|
427
|
+
puts JSON.pretty_generate(JSON.load(body || "{}")) if body
|
428
|
+
Callback.new(@responses[[method, path]] || @response)
|
429
|
+
end
|
430
|
+
end
|
331
431
|
end
|
@@ -18,6 +18,11 @@ module FFWD::Plugin::GoogleCloud
|
|
18
18
|
CUSTOM_PREFIX = "custom.cloudmonitoring.googleapis.com"
|
19
19
|
|
20
20
|
module Utils
|
21
|
+
def self.make_common_labels buffer
|
22
|
+
return nil if buffer.empty?
|
23
|
+
make_labels buffer.first.fixed_attr
|
24
|
+
end
|
25
|
+
|
21
26
|
def self.make_timeseries buffer
|
22
27
|
# we are not allowed to send duplicate data.
|
23
28
|
seen = Set.new
|
@@ -46,11 +51,11 @@ module FFWD::Plugin::GoogleCloud
|
|
46
51
|
end
|
47
52
|
|
48
53
|
def self.make_desc m
|
49
|
-
{:metric => make_key(m), :labels => make_labels(m)}
|
54
|
+
{:metric => make_key(m), :labels => make_labels(m.external_attr)}
|
50
55
|
end
|
51
56
|
|
52
57
|
def self.make_key m
|
53
|
-
attributes = Hash[m.
|
58
|
+
attributes = Hash[m.external_attr]
|
54
59
|
|
55
60
|
entries = []
|
56
61
|
|
@@ -68,17 +73,14 @@ module FFWD::Plugin::GoogleCloud
|
|
68
73
|
end
|
69
74
|
end
|
70
75
|
|
71
|
-
def self.make_labels
|
72
|
-
|
76
|
+
def self.make_labels attr
|
77
|
+
Hash[attr.select{|k, v| k.to_s != "what"}.map{|k, v|
|
73
78
|
["#{CUSTOM_PREFIX}/#{k}", v]
|
74
79
|
}]
|
75
|
-
|
76
|
-
#labels["#{CUSTOM_PREFIX}/host"] = m.host
|
77
|
-
labels
|
78
80
|
end
|
79
81
|
|
80
82
|
def self.extract_labels source
|
81
|
-
source.map{|k, v| {:key => k, :description =>
|
83
|
+
source.map{|k, v| {:key => k, :description => ""}}
|
82
84
|
end
|
83
85
|
end
|
84
86
|
end
|
@@ -34,6 +34,7 @@ module FFWD::Plugin::GoogleCloud
|
|
34
34
|
DEFAULT_SCOPE = "https://www.googleapis.com/auth/monitoring"
|
35
35
|
DEFAULT_FLUSH_INTERVAL = 10
|
36
36
|
DEFAULT_BUFFER_LIMIT = 100
|
37
|
+
DEFAULT_DEBUG = false
|
37
38
|
|
38
39
|
def self.setup_output config
|
39
40
|
if not config[:project_id]
|
@@ -53,6 +54,8 @@ module FFWD::Plugin::GoogleCloud
|
|
53
54
|
config[:api_url] ||= DEFAULT_API_URL
|
54
55
|
config[:flush_interval] ||= DEFAULT_FLUSH_INTERVAL
|
55
56
|
config[:buffer_limit] ||= DEFAULT_BUFFER_LIMIT
|
57
|
+
# Fake all API interaction (output with log.debug)
|
58
|
+
config[:debug] ||= DEFAULT_DEBUG
|
56
59
|
|
57
60
|
hook = Hook.new(config)
|
58
61
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ffwd-google-cloud
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- John-John Tedro
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-03-
|
11
|
+
date: 2015-03-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: em-http-request
|
@@ -30,14 +30,14 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - '='
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 0.4.
|
33
|
+
version: 0.4.3
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - '='
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: 0.4.
|
40
|
+
version: 0.4.3
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: rspec
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|