Skip to content

Commit

Permalink
feat: add telemetry
Browse files Browse the repository at this point in the history
  • Loading branch information
Inksprout authored Feb 21, 2022
1 parent 5fa1e77 commit db5dfa5
Show file tree
Hide file tree
Showing 5 changed files with 148 additions and 0 deletions.
3 changes: 3 additions & 0 deletions lib/pact/mock_service/app_manager.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
require 'pact/consumer/server'
require 'singleton'
require 'pact/mock_service/app'
require 'pact/support/metrics'

module Pact
module MockService
Expand All @@ -29,6 +30,8 @@ def register_mock_service_for(name, url, options = {})
pact_dir: pact_dir,
pact_specification_version: options.fetch(:pact_specification_version)
)

Pact::Support::Metrics.report_metric("Pact mock server started", "ConsumerTest", "MockServerStarted")
register(app, uri.host, uri.port)
end

Expand Down
2 changes: 2 additions & 0 deletions lib/pact/mock_service/run.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
require 'pact/mock_service/run'
require 'pact/mock_service/server/webrick_request_monkeypatch'
require 'pact/specification_version'
require 'pact/support/metrics'

module Pact
module MockService
Expand Down Expand Up @@ -35,6 +36,7 @@ def call
def mock_service
@mock_service ||= begin
mock_service = Pact::MockService.new(service_options)
Pact::Support::Metrics.report_metric("Pact mock server started", "ConsumerTest", "MockServerStarted")
Pact::Consumer::SetLocation.new(mock_service, base_url)
end
end
Expand Down
85 changes: 85 additions & 0 deletions lib/pact/support/metrics.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
require 'securerandom'
require 'digest'
require 'socket'
require 'pact/support/metrics'
require 'pact/mock_service/version'
require 'net/http'

module Pact
module Support
class Metrics

def self.report_metric(event, category, action, value = 1)
in_thread do
begin
if track_events?
Pact.configuration.output_stream.puts "WARN: Please note: we are tracking events anonymously to gather important usage statistics like Pact-Ruby version and operating system. To disable tracking, set the 'PACT_DO_NOT_TRACK' environment variable to 'true'."

uri = URI('https://www.google-analytics.com/collect')
req = Net::HTTP::Post.new(uri)
req.set_form_data(create_tracking_event(event, category, action, value))

Net::HTTP.start(uri.hostname, uri.port, read_timeout:2, open_timeout:2, :use_ssl => true ) do |http|
http.request(req)
end
end
rescue StandardError => e
handle_error(e)
end
end
end

private

def self.handle_error e
if ENV['PACT_METRICS_DEBUG'] == 'true'
Pact.configuration.output_stream.puts("DEBUG: #{e.inspect}\n" + e.backtrace.join("\n"))
end
end

def self.in_thread
Thread.new do
yield
end
end

def self.create_tracking_event(event, category, action, value)
{
"v" => 1,
"t" => "event",
"tid" => "UA-117778936-1",
"cid" => calculate_cid,
"an" => "Pact Mock Service",
"av" => Pact::MockService::VERSION,
"aid" => "pact-mock_service",
"aip" => 1,
"ds" => ENV['PACT_EXECUTING_LANGUAGE'] ? "client" : "cli",
"cd2" => ENV['CI'] == "true" ? "CI" : "unknown",
"cd3" => RUBY_PLATFORM,
"cd6" => ENV['PACT_EXECUTING_LANGUAGE'] || "unknown",
"cd7" => ENV['PACT_EXECUTING_LANGUAGE_VERSION'],
"el" => event,
"ec" => category,
"ea" => action,
"ev" => value
}
end

def self.track_events?
ENV['PACT_DO_NOT_TRACK'] != 'true'
end

def self.calculate_cid
if RUBY_PLATFORM.include? "windows"
hostname = ENV['COMPUTERNAME']
else
hostname = ENV['HOSTNAME']
end
if !hostname
hostname = Socket.gethostname
end
Digest::MD5.hexdigest hostname || SecureRandom.urlsafe_base64(5)
end
end
end
end
7 changes: 7 additions & 0 deletions spec/lib/pact/mock_service/app_manager_spec.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
require 'pact/mock_service/app_manager'
require 'pact/support/metrics'

module Pact::MockService
describe AppManager do
Expand All @@ -9,6 +10,7 @@ module Pact::MockService
describe "register_mock_service_for" do
before do
allow_any_instance_of(AppRegistration).to receive(:spawn) # Don't want process actually spawning during the tests
allow(Pact::Support::Metrics).to receive(:report_metric)
end

let(:name) { 'some_service'}
Expand All @@ -28,6 +30,11 @@ module Pact::MockService
expect(AppManager.instance.app_registered_on?(1234)).to eq true
end

it "reports the metric for pact mock service started" do
expect(Pact::Support::Metrics).to receive(:report_metric).with("Pact mock server started", "ConsumerTest", "MockServerStarted")
AppManager.instance.register_mock_service_for name, url, options
end

it "creates a mock service with the configured pact_dir" do
allow(Pact.configuration).to receive(:pact_dir).and_return('pact_dir')
expect(Pact::MockService).to receive(:new) do | options |
Expand Down
51 changes: 51 additions & 0 deletions spec/pact/support/metrics_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
require 'rspec'
require 'pact/support/metrics'

describe Pact::Support::Metrics do

before do
stub_request(:post, "https://www.google-analytics.com/collect").to_return(status: 200, body: "", headers: {})
ENV['COMPUTERNAME'] = 'test'
ENV['HOSTNAME'] = 'test'
allow(Pact::Support::Metrics).to receive(:in_thread) { |&block| block.call }
end

describe ".report_metric" do
subject { Pact::Support::Metrics.report_metric("Event", "Category", "Action", "Value") }
context 'when do not track is not set' do
let(:expected_event) { {
"v" => 1,
"t" => "event",
"tid" => "UA-117778936-1",
"cid" => "098f6bcd4621d373cade4e832627b4f6",
"an" => "Pact Mock Service",
"av" => Pact::MockService::VERSION,
"aid" => "pact-mock_service",
"aip" => 1,
"ds" => ENV['PACT_EXECUTING_LANGUAGE'] ? "client" : "cli",
"cd2" => ENV['CI'] == "true" ? "CI" : "unknown",
"cd3" => RUBY_PLATFORM,
"cd6" => ENV['PACT_EXECUTING_LANGUAGE'] || "unknown",
"cd7" => ENV['PACT_EXECUTING_LANGUAGE_VERSION'],
"el" => "Event",
"ec" => "Category",
"ea" => "Action",
"ev" => "Value"
} }
it 'sends metrics' do
expect_any_instance_of(Net::HTTP::Post).to receive(:set_form_data).with(expected_event)
expect(Net::HTTP).to receive(:start)
subject
end
end
context 'when do not track is set to true' do
before do
ENV['PACT_DO_NOT_TRACK'] = "true"
end
it 'does not send metrics' do
expect(Net::HTTP).to_not receive(:start)
subject
end
end
end
end

0 comments on commit db5dfa5

Please sign in to comment.