coverband-service-client 0.0.9 → 0.0.12.rc.2

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
  SHA256:
3
- metadata.gz: 613941985d4fb60122f3e35a84c5139a7aa1395008a443b3a3478eef59df2b30
4
- data.tar.gz: 03eabff6d96401aede1ed1263fdc26a400e93fc4e26ad164977e6b77a4b9a4a7
3
+ metadata.gz: ecee5d46bea965ae3675532f956d99ad2617f1892dcf59cd302f080faf03acc1
4
+ data.tar.gz: 9bde9ec5901ed84880692ded71d617d94e887cfb818e86bb4c3f7607f4f64f9e
5
5
  SHA512:
6
- metadata.gz: 2d800e7c8abc0056866a6f9f96b1c89b9c1fc2ebcd7f5bdc17477199445f5740cc968d795cca1ad9a2ca9951480f32b8960f8e4729e975c2f19eea69aa57c8e7
7
- data.tar.gz: 32d5360aa6a50d722d53481f22736e8c47c05844b9372fdd3d1e993ea2209fbdd3043e66dd2c016aad04df7195cffeb124d9fa8ca4bd66ce361f75462a368ffa
6
+ metadata.gz: 77e703011dcb88cdcb8e7fb107aca73c13419b4e1ed9bf72a47d67c7cb6847e80c2b477d7866ce030264578ee426e889b7789b46d5bc7b8e42b841b68ada7787
7
+ data.tar.gz: a7277f954c3b6c1b418ab2230a41652e71788ddc68a6c8183325931f023b8b9bc52fcb56be51e4a1eb31a67ae3bc23509a197dfafa41a5b02f2e32b58f59a376
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- coverband-service-client (0.0.9)
4
+ coverband-service-client (0.0.12.rc.2)
5
5
  coverband (~> 4.2.4)
6
6
 
7
7
  GEM
@@ -1,5 +1,8 @@
1
1
  # frozen_string_literal: true
2
+ require 'socket'
2
3
 
4
+ COVERBAND_ORIGINAL_START = ENV['COVERBAND_DISABLE_AUTO_START']
5
+ ENV['COVERBAND_DISABLE_AUTO_START'] = 'true'
3
6
  require 'coverband'
4
7
  require 'coverband/service/client/version'
5
8
  require 'securerandom'
@@ -7,7 +10,7 @@ require 'securerandom'
7
10
  module Coverband
8
11
  COVERBAND_ENV = ENV['RACK_ENV'] || ENV['RAILS_ENV'] || (defined?(Rails) ? Rails.env : 'unknown')
9
12
  COVERBAND_SERVICE_URL = ENV['COVERBAND_URL'] || 'https://coverband.io'
10
- COVERBAND_TIMEOUT = (COVERBAND_ENV == 'development') ? 5 : 1
13
+ COVERBAND_TIMEOUT = (COVERBAND_ENV == 'development') ? 5 : 2
11
14
  COVERBAND_ENABLE_DEV_MODE = ENV['COVERBAND_ENABLE_DEV_MODE'] || false
12
15
  COVERBAND_ENABLE_TEST_MODE = ENV['COVERBAND_ENABLE_TEST_MODE'] || false
13
16
  COVERBAND_PROCESS_TYPE = ENV['PROCESS_TYPE'] || 'unknown'
@@ -22,7 +25,7 @@ module Coverband
22
25
  def self.report_coverage
23
26
  # for now disable coverband reporting in test & dev env by default
24
27
  if Coverband.configuration.verbose
25
- puts "Coverband: disabled for #{COVERBAND_ENV}, set COVERBAND_ENABLE_DEV_MODE or COVERBAND_ENABLE_TEST_MODE to enable"
28
+ puts "Coverband: disabled for #{COVERBAND_ENV}, set COVERBAND_ENABLE_DEV_MODE or COVERBAND_ENABLE_TEST_MODE to enable" if Coverband.configuration.verbose || COVERBAND_ENABLE_DEV_MODE
26
29
  end
27
30
  end
28
31
  end
@@ -33,16 +36,37 @@ module Coverband
33
36
  #
34
37
  # NOTES:
35
38
  # * uses net/http to avoid any dependencies
36
- # * currently JSON, but likely better to move to something simpler / faster
39
+ # * currently JSON, but likely better to move to something faster
37
40
  ###
38
41
  class Service < Base
39
- attr_reader :coverband_url, :process_type, :runtime_env
42
+ attr_reader :coverband_url, :process_type, :runtime_env, :hostname, :pid, :stats
40
43
 
41
44
  def initialize(coverband_url, opts = {})
42
45
  super()
43
46
  @coverband_url = coverband_url
44
- @process_type = opts.fetch(:process_type) { COVERBAND_PROCESS_TYPE }
47
+ @process_type = opts.fetch(:process_type) { $PROGRAM_NAME&.split('/')&.last || COVERBAND_PROCESS_TYPE }
48
+ @hostname = opts.fetch(:hostname) { ENV["DYNO"] || Socket.gethostname.force_encoding('utf-8').encode }
49
+ @hostname = @hostname.gsub("'",'').gsub("’",'')
45
50
  @runtime_env = opts.fetch(:runtime_env) { COVERBAND_ENV }
51
+ initialize_stats
52
+ end
53
+
54
+ def initialize_stats
55
+ return unless ENV['COVERBAND_STATS_KEY']
56
+ return unless defined?(Dogapi::Client)
57
+
58
+ @stats = Dogapi::Client.new(ENV['COVERBAND_STATS_KEY'])
59
+ end
60
+
61
+ def report_timing(timing)
62
+ return unless @stats
63
+
64
+ @stats.emit_point(
65
+ 'coverband.save.time',
66
+ timing,
67
+ host: hostname,
68
+ device: "coverband_#{self.class.name.split("::").last}",
69
+ options: {tags: [runtime_env]})
46
70
  end
47
71
 
48
72
  def logger
@@ -66,27 +90,31 @@ module Coverband
66
90
  ENV['COVERBAND_API_KEY'] || Coverband.configuration.api_key
67
91
  end
68
92
 
69
- # TODO: no longer get by type just get both reports in a single request
93
+ ###
94
+ # Fetch coverband coverage via the API
95
+ ###
70
96
  def coverage(local_type = nil, opts = {})
71
97
  local_type ||= opts.key?(:override_type) ? opts[:override_type] : type
72
- uri = URI("#{coverband_url}/api/coverage/#{ENV['COVERBAND_ID']}?type=#{local_type}")
98
+ env_filter = opts.key?(:env_filter) ? opts[:env_filter] : 'production'
99
+ uri = URI("#{coverband_url}/api/coverage?type=#{local_type}&env_filter=#{env_filter}",)
73
100
  req = Net::HTTP::Get.new(uri, 'Content-Type' => 'application/json', 'Coverband-Token' => api_key)
74
101
  res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https') do |http|
75
102
  http.request(req)
76
103
  end
77
104
  coverage_data = JSON.parse(res.body)
78
- # puts "coverage data: "
79
- # puts coverage_data
80
105
  coverage_data
81
106
  rescue StandardError => e
82
- puts "Coverband: Error while retrieving coverage #{e}"
107
+ logger&.error "Coverband: Error while retrieving coverage #{e}" if Coverband.configuration.verbose || COVERBAND_ENABLE_DEV_MODE
83
108
  end
84
109
 
85
110
  def save_report(report)
86
111
  return if report.empty?
87
112
 
113
+ # We set here vs initialize to avoid setting on the primary process vs child processes
114
+ @pid ||= ::Process.pid
115
+
88
116
  # TODO: do we need dup
89
- # TODO: remove timestamps, server will track first_seen
117
+ # TODO: remove upstream timestamps, server will track first_seen
90
118
  Thread.new do
91
119
  data = expand_report(report.dup)
92
120
  full_package = {
@@ -95,12 +123,18 @@ module Coverband
95
123
  tags: {
96
124
  process_type: process_type,
97
125
  app_loading: type == Coverband::EAGER_TYPE,
98
- runtime_env: runtime_env
126
+ runtime_env: runtime_env,
127
+ pid: pid,
128
+ hostname: hostname,
99
129
  },
100
130
  file_coverage: data
101
131
  }
102
132
  }
133
+
134
+ starting = Process.clock_gettime(Process::CLOCK_MONOTONIC)
103
135
  save_coverage(full_package)
136
+ ending = Process.clock_gettime(Process::CLOCK_MONOTONIC)
137
+ report_timing((ending - starting))
104
138
  end&.join
105
139
  end
106
140
 
@@ -113,16 +147,16 @@ module Coverband
113
147
  def save_coverage(data)
114
148
  if api_key.nil?
115
149
  puts "Coverband: Error: no Coverband API key was found!"
150
+ return
116
151
  end
117
152
 
118
153
  uri = URI("#{coverband_url}/api/collector")
119
- logger&.info "Coverband: saving #{uri}" if Coverband.configuration.verbose
120
154
  req = Net::HTTP::Post.new(uri,
121
155
  'Content-Type' => 'application/json',
122
156
  'Coverband-Token' => api_key)
123
157
  req.body = { remote_uuid: SecureRandom.uuid, data: data }.to_json
124
158
 
125
- logger&.info "Coverband: saving #{req.body}" if Coverband.configuration.verbose
159
+ logger&.info "Coverband: saving (#{uri}) #{req.body}" if Coverband.configuration.verbose
126
160
  res = Net::HTTP.start(
127
161
  uri.hostname,
128
162
  uri.port,
@@ -134,7 +168,51 @@ module Coverband
134
168
  http.request(req)
135
169
  end
136
170
  rescue StandardError => e
137
- puts "Coverband: Error while saving coverage #{e}"
171
+ logger&.info "Coverband: Error while saving coverage #{e}" if Coverband.configuration.verbose || COVERBAND_ENABLE_DEV_MODE
172
+ end
173
+ end
174
+
175
+ class PersistentService < Service
176
+ attr_reader :http, :stats
177
+
178
+ def initialize(coverband_url, opts = {})
179
+ super
180
+ initiate_http
181
+ end
182
+
183
+ private
184
+
185
+ def initiate_http
186
+ @http = Net::HTTP::Persistent.new name: 'coverband_persistent'
187
+ @http.headers['Content-Type'] = 'application/json'
188
+ @http.headers['Coverband-Token'] = api_key
189
+ @http.open_timeout = COVERBAND_TIMEOUT
190
+ @http.read_timeout = COVERBAND_TIMEOUT
191
+ @http.ssl_timeout = COVERBAND_TIMEOUT
192
+ end
193
+
194
+ def save_coverage(data)
195
+ persistent_attempts = 0
196
+ begin
197
+ if api_key.nil?
198
+ puts "Coverband: Error: no Coverband API key was found!"
199
+ return
200
+ end
201
+
202
+ post_uri = URI("#{coverband_url}/api/collector")
203
+ post = Net::HTTP::Post.new post_uri.path
204
+ body = { remote_uuid: SecureRandom.uuid, data: data }.to_json
205
+ post.body = body
206
+ logger&.info "Coverband: saving (#{post_uri}) #{body}" if Coverband.configuration.verbose
207
+ res = http.request post_uri, post
208
+ rescue Net::HTTP::Persistent::Error => e
209
+ persistent_attempts += 1
210
+ http.shutdown
211
+ initiate_http
212
+ retry if persistent_attempts < 2
213
+ end
214
+ rescue StandardError => e
215
+ logger&.info "Coverband: Error while saving coverage #{e}" if Coverband.configuration.verbose || COVERBAND_ENABLE_DEV_MODE
138
216
  end
139
217
  end
140
218
  end
@@ -168,18 +246,22 @@ module Coverband
168
246
  rescue StandardError => e
169
247
  # we don't want to raise errors if Coverband can't reach redis.
170
248
  # This is a nice to have not a bring the system down
171
- logger&.error "Coverband: view_tracker failed to store, error #{e.class.name}"
249
+ logger&.error "Coverband: view_tracker failed to store, error #{e.class.name}" if Coverband.configuration.verbose || COVERBAND_ENABLE_DEV_MODE
172
250
  end
173
251
 
174
252
  private
175
253
 
254
+ def api_key
255
+ ENV['COVERBAND_API_KEY'] || Coverband.configuration.api_key
256
+ end
257
+
176
258
  def logger
177
259
  Coverband.configuration.logger
178
260
  end
179
261
 
180
262
  def save_tracked_views(views:, reported_time:)
181
263
  uri = URI("#{COVERBAND_SERVICE_URL}/api/collector")
182
- req = Net::HTTP::Post.new(uri, 'Content-Type' => 'application/json', 'Coverband-Token' => ENV['COVERBAND_API_KEY'])
264
+ req = Net::HTTP::Post.new(uri, 'Content-Type' => 'application/json', 'Coverband-Token' => api_key)
183
265
  data = {
184
266
  collection_type: 'view_tracker_delta',
185
267
  collection_data: {
@@ -196,7 +278,7 @@ module Coverband
196
278
  http.request(req)
197
279
  end
198
280
  rescue StandardError => e
199
- puts "Coverband: Error while saving coverage #{e}"
281
+ logger&.error "Coverband: Error while saving coverage #{e}" if Coverband.configuration.verbose || COVERBAND_ENABLE_DEV_MODE
200
282
  end
201
283
  end
202
284
  end
@@ -208,9 +290,14 @@ module Coverband
208
290
  end
209
291
  end
210
292
 
293
+ ENV['COVERBAND_DISABLE_AUTO_START'] = COVERBAND_ORIGINAL_START
211
294
  Coverband.configure do |config|
212
- # Use The Test Service Adapter
213
- config.store = Coverband::Adapters::Service.new(Coverband::COVERBAND_SERVICE_URL)
295
+ # Use the Service Adapter
296
+ if defined?(Net::HTTP::Persistent)
297
+ config.store = Coverband::Adapters::PersistentService.new(Coverband::COVERBAND_SERVICE_URL)
298
+ else
299
+ config.store = Coverband::Adapters::Service.new(Coverband::COVERBAND_SERVICE_URL)
300
+ end
214
301
 
215
302
  # default to tracking views true
216
303
  config.track_views = if ENV['COVERBAND_DISABLE_VIEW_TRACKER']
@@ -234,7 +321,10 @@ end
234
321
  # NOTE: it is really hard to bypass / overload our config we should fix this in Coverband
235
322
  # this hopefully detects anyone that has both gems and was trying to configure Coverband themselves.
236
323
  if File.exist?('./config/coverband.rb')
237
- puts "Warning: config/coverband.rb found, this overrides coverband service allowing one to setup open source Coverband"
324
+ puts "Warning: config/coverband.rb found, this overrides coverband service allowing one to setup open source Coverband" if Coverband.configuration.verbose || COVERBAND_ENABLE_DEV_MODE
238
325
  end
239
326
 
240
327
  Coverband.configure('./config/coverband_service.rb') if File.exist?('./config/coverband_service.rb')
328
+ Coverband.start
329
+ require "coverband/utils/railtie" if defined? ::Rails::Railtie
330
+ require "coverband/integrations/resque" if defined? ::Resque
@@ -1,7 +1,7 @@
1
1
  module Coverband
2
2
  module Service
3
3
  module Client
4
- VERSION = '0.0.9'
4
+ VERSION = '0.0.12.rc.2'
5
5
  end
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: coverband-service-client
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.9
4
+ version: 0.0.12.rc.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dan Mayer
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2020-05-17 00:00:00.000000000 Z
12
+ date: 2020-06-20 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
@@ -106,9 +106,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
106
106
  version: '0'
107
107
  required_rubygems_version: !ruby/object:Gem::Requirement
108
108
  requirements:
109
- - - ">="
109
+ - - ">"
110
110
  - !ruby/object:Gem::Version
111
- version: '0'
111
+ version: 1.3.1
112
112
  requirements: []
113
113
  rubygems_version: 3.0.3
114
114
  signing_key: