coverband-service-client 0.0.10 → 0.0.12.rc.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f8d7b393a8c8e038d9ec952cea42d257685e93e68d8e00a1dcd6c5be2c46272c
4
- data.tar.gz: 9aeba81b92f75f43557cbb891b9cee1927e46d03683927d8cfabaad8caf10d46
3
+ metadata.gz: 9fe3bdfd98c39a57b8483038842ddec02d9ba6d64f9aafc9dc47ad5c6d0a07cb
4
+ data.tar.gz: 570f69150be14beb052dc0f218d04782375632ae16a45d8923db8141608c4b21
5
5
  SHA512:
6
- metadata.gz: 466d704e4b97b84c5ae198e997292c3207179cdd185e3087a2067365223cfcb6971b691decb78d7eeb8ed08be88a718c5a448aca5c3abe01c1ff4a76069a9757
7
- data.tar.gz: 0c6b6c7db5364d591c0fbcbcd74e61c04aadebcca9e3ef3dd02b44ae952a6e86e0a800a9110db819bc4cf0d66cd5d43691ad42ad8c157049ba68a1e42ea957f9
6
+ metadata.gz: 73ba2a65ad9c1ed4b0373e22413e26b7d9cf316d4a3885d73aef14e5fed1becdcfffae89df1ef89f71088b0c38c586cd26cd50139eec73410fce68c8859b1696
7
+ data.tar.gz: 9e2293b601ca18ae1db97a0f9d376da80cbfb1b45bc3fdce78106f0c11d8beff2aedff73b6bd77123d92dccfc5ca72d74f2212dc2351b34077180c9c6a87fd1b
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- coverband-service-client (0.0.10)
4
+ coverband-service-client (0.0.12.rc.3)
5
5
  coverband (~> 4.2.4)
6
6
 
7
7
  GEM
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+ require 'socket'
2
3
 
3
4
  COVERBAND_ORIGINAL_START = ENV['COVERBAND_DISABLE_AUTO_START']
4
5
  ENV['COVERBAND_DISABLE_AUTO_START'] = 'true'
@@ -9,7 +10,7 @@ require 'securerandom'
9
10
  module Coverband
10
11
  COVERBAND_ENV = ENV['RACK_ENV'] || ENV['RAILS_ENV'] || (defined?(Rails) ? Rails.env : 'unknown')
11
12
  COVERBAND_SERVICE_URL = ENV['COVERBAND_URL'] || 'https://coverband.io'
12
- COVERBAND_TIMEOUT = (COVERBAND_ENV == 'development') ? 5 : 1
13
+ COVERBAND_TIMEOUT = (COVERBAND_ENV == 'development') ? 5 : 2
13
14
  COVERBAND_ENABLE_DEV_MODE = ENV['COVERBAND_ENABLE_DEV_MODE'] || false
14
15
  COVERBAND_ENABLE_TEST_MODE = ENV['COVERBAND_ENABLE_TEST_MODE'] || false
15
16
  COVERBAND_PROCESS_TYPE = ENV['PROCESS_TYPE'] || 'unknown'
@@ -35,16 +36,38 @@ module Coverband
35
36
  #
36
37
  # NOTES:
37
38
  # * uses net/http to avoid any dependencies
38
- # * currently JSON, but likely better to move to something simpler / faster
39
+ # * currently JSON, but likely better to move to something faster
39
40
  ###
40
41
  class Service < Base
41
- attr_reader :coverband_url, :process_type, :runtime_env
42
+ attr_reader :coverband_url, :process_type, :runtime_env, :hostname, :pid, :stats
42
43
 
43
44
  def initialize(coverband_url, opts = {})
44
45
  super()
45
46
  @coverband_url = coverband_url
46
- @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("’",'')
47
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
+ @app_name = defined?(Rails) ? Rails.application.class.module_parent.to_s : "unknown"
60
+ end
61
+
62
+ def report_timing(timing)
63
+ return unless @stats
64
+
65
+ @stats.emit_point(
66
+ 'coverband.save.time',
67
+ timing,
68
+ host: hostname,
69
+ device: "coverband_#{self.class.name.split("::").last}",
70
+ options: {tags: [runtime_env]})
48
71
  end
49
72
 
50
73
  def logger
@@ -68,27 +91,31 @@ module Coverband
68
91
  ENV['COVERBAND_API_KEY'] || Coverband.configuration.api_key
69
92
  end
70
93
 
71
- # TODO: no longer get by type just get both reports in a single request
94
+ ###
95
+ # Fetch coverband coverage via the API
96
+ ###
72
97
  def coverage(local_type = nil, opts = {})
73
98
  local_type ||= opts.key?(:override_type) ? opts[:override_type] : type
74
- uri = URI("#{coverband_url}/api/coverage/#{ENV['COVERBAND_ID']}?type=#{local_type}")
99
+ env_filter = opts.key?(:env_filter) ? opts[:env_filter] : 'production'
100
+ uri = URI("#{coverband_url}/api/coverage?type=#{local_type}&env_filter=#{env_filter}",)
75
101
  req = Net::HTTP::Get.new(uri, 'Content-Type' => 'application/json', 'Coverband-Token' => api_key)
76
102
  res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https') do |http|
77
103
  http.request(req)
78
104
  end
79
105
  coverage_data = JSON.parse(res.body)
80
- # puts "coverage data: "
81
- # puts coverage_data
82
106
  coverage_data
83
107
  rescue StandardError => e
84
- puts "Coverband: Error while retrieving coverage #{e}"
108
+ logger&.error "Coverband: Error while retrieving coverage #{e}" if Coverband.configuration.verbose || COVERBAND_ENABLE_DEV_MODE
85
109
  end
86
110
 
87
111
  def save_report(report)
88
112
  return if report.empty?
89
113
 
114
+ # We set here vs initialize to avoid setting on the primary process vs child processes
115
+ @pid ||= ::Process.pid
116
+
90
117
  # TODO: do we need dup
91
- # TODO: remove timestamps, server will track first_seen
118
+ # TODO: remove upstream timestamps, server will track first_seen
92
119
  Thread.new do
93
120
  data = expand_report(report.dup)
94
121
  full_package = {
@@ -97,12 +124,18 @@ module Coverband
97
124
  tags: {
98
125
  process_type: process_type,
99
126
  app_loading: type == Coverband::EAGER_TYPE,
100
- runtime_env: runtime_env
127
+ runtime_env: runtime_env,
128
+ pid: pid,
129
+ hostname: hostname,
101
130
  },
102
131
  file_coverage: data
103
132
  }
104
133
  }
134
+
135
+ starting = Process.clock_gettime(Process::CLOCK_MONOTONIC)
105
136
  save_coverage(full_package)
137
+ ending = Process.clock_gettime(Process::CLOCK_MONOTONIC)
138
+ report_timing((ending - starting))
106
139
  end&.join
107
140
  end
108
141
 
@@ -115,6 +148,7 @@ module Coverband
115
148
  def save_coverage(data)
116
149
  if api_key.nil?
117
150
  puts "Coverband: Error: no Coverband API key was found!"
151
+ return
118
152
  end
119
153
 
120
154
  uri = URI("#{coverband_url}/api/collector")
@@ -138,6 +172,50 @@ module Coverband
138
172
  logger&.info "Coverband: Error while saving coverage #{e}" if Coverband.configuration.verbose || COVERBAND_ENABLE_DEV_MODE
139
173
  end
140
174
  end
175
+
176
+ class PersistentService < Service
177
+ attr_reader :http, :stats
178
+
179
+ def initialize(coverband_url, opts = {})
180
+ super
181
+ initiate_http
182
+ end
183
+
184
+ private
185
+
186
+ def initiate_http
187
+ @http = Net::HTTP::Persistent.new name: 'coverband_persistent'
188
+ @http.headers['Content-Type'] = 'application/json'
189
+ @http.headers['Coverband-Token'] = api_key
190
+ @http.open_timeout = COVERBAND_TIMEOUT
191
+ @http.read_timeout = COVERBAND_TIMEOUT
192
+ @http.ssl_timeout = COVERBAND_TIMEOUT
193
+ end
194
+
195
+ def save_coverage(data)
196
+ persistent_attempts = 0
197
+ begin
198
+ if api_key.nil?
199
+ puts "Coverband: Error: no Coverband API key was found!"
200
+ return
201
+ end
202
+
203
+ post_uri = URI("#{coverband_url}/api/collector")
204
+ post = Net::HTTP::Post.new post_uri.path
205
+ body = { remote_uuid: SecureRandom.uuid, data: data }.to_json
206
+ post.body = body
207
+ logger&.info "Coverband: saving (#{post_uri}) #{body}" if Coverband.configuration.verbose
208
+ res = http.request post_uri, post
209
+ rescue Net::HTTP::Persistent::Error => e
210
+ persistent_attempts += 1
211
+ http.shutdown
212
+ initiate_http
213
+ retry if persistent_attempts < 2
214
+ end
215
+ rescue StandardError => e
216
+ logger&.info "Coverband: Error while saving coverage #{e}" if Coverband.configuration.verbose || COVERBAND_ENABLE_DEV_MODE
217
+ end
218
+ end
141
219
  end
142
220
 
143
221
  module Service
@@ -174,13 +252,17 @@ module Coverband
174
252
 
175
253
  private
176
254
 
255
+ def api_key
256
+ ENV['COVERBAND_API_KEY'] || Coverband.configuration.api_key
257
+ end
258
+
177
259
  def logger
178
260
  Coverband.configuration.logger
179
261
  end
180
262
 
181
263
  def save_tracked_views(views:, reported_time:)
182
264
  uri = URI("#{COVERBAND_SERVICE_URL}/api/collector")
183
- req = Net::HTTP::Post.new(uri, 'Content-Type' => 'application/json', 'Coverband-Token' => ENV['COVERBAND_API_KEY'])
265
+ req = Net::HTTP::Post.new(uri, 'Content-Type' => 'application/json', 'Coverband-Token' => api_key)
184
266
  data = {
185
267
  collection_type: 'view_tracker_delta',
186
268
  collection_data: {
@@ -211,8 +293,12 @@ end
211
293
 
212
294
  ENV['COVERBAND_DISABLE_AUTO_START'] = COVERBAND_ORIGINAL_START
213
295
  Coverband.configure do |config|
214
- # Use The Test Service Adapter
215
- config.store = Coverband::Adapters::Service.new(Coverband::COVERBAND_SERVICE_URL)
296
+ # Use the Service Adapter
297
+ if defined?(Net::HTTP::Persistent)
298
+ config.store = Coverband::Adapters::PersistentService.new(Coverband::COVERBAND_SERVICE_URL)
299
+ else
300
+ config.store = Coverband::Adapters::Service.new(Coverband::COVERBAND_SERVICE_URL)
301
+ end
216
302
 
217
303
  # default to tracking views true
218
304
  config.track_views = if ENV['COVERBAND_DISABLE_VIEW_TRACKER']
@@ -1,7 +1,7 @@
1
1
  module Coverband
2
2
  module Service
3
3
  module Client
4
- VERSION = '0.0.10'
4
+ VERSION = '0.0.12.rc.3'
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.10
4
+ version: 0.0.12.rc.3
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-21 00:00:00.000000000 Z
12
+ date: 2020-06-21 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: