Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat add metrics #256

Merged
merged 12 commits into from
Feb 21, 2022
Merged

Conversation

Inksprout
Copy link
Contributor

The purpose of this PR is to add code that can be used to push metrics from pact-ruby to google analytics.
The PR adds event tracking for when pact verification has completed. The code supports users turning off this tracking by setting the env var PACT_DO_NOT_TRACK to 'true'.

lib/pact/utils/metrics.rb Outdated Show resolved Hide resolved
Inksprout and others added 2 commits January 25, 2022 10:59
Co-authored-by: Matt Fellows <matt.fellows@onegeek.com.au>
@Inksprout Inksprout requested a review from uglyog January 25, 2022 00:18

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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Upper case PACT_DO_NOT_TRACK.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The other implementations have followed the original Pact.js implementation, which uses a lower case environment variable name

Copy link
Member

@mefellows mefellows Jan 27, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, I think you've misread the code. In Pact Node, you can set the pact_do_not_track config item (i.e. npm config set pact_do_not_track true or in package.json).

We still support the env var PACT_DO_NOT_TRACK also, see https://github.com/pact-foundation/pact-js-core/blob/pact-node/standalone/install.ts#L85.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, in that case we need to change the other implementations. Probably best to make it case-insensitive

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, for clarity, Upper case PACT_DO_NOT_TRACK is what we want for consistency (including the warning). We can update rust later.

"av" => Pact::VERSION,
"aid" => "pact-ruby",
"aip" => 1,
"ds" => ENV["CI"] || "unknown",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ENV["CI"] will eq 'true'. You need this to return "ci" if ENV["CI"] == 'true'.

"aid" => "pact-ruby",
"aip" => 1,
"ds" => ENV["CI"] || "unknown",
"cd2" => ENV['PACT_EXECUTING_LANGUAGE'] ? "client" : "unknown",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is cd2? I think this will always be 'client'.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah I think what's happened is I have mixed up the 'ds' field and 'cd2' field.
ds should be one of: client, cli, broker
while cd2 should be "One of: CI, development, unknown"
For cd2 Ron suggested it should be "CI" if the CI env var is set or otherwise "unknown". If that sounds good I'll fix up these 2 fields

"cd2" => ENV['PACT_EXECUTING_LANGUAGE'] ? "client" : "unknown",
"cd3" => RUBY_PLATFORM,
"cd6" => ENV['PACT_EXECUTING_LANGUAGE'] || "unknown",
"cd7" => RUBY_VERSION,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we only want to use the ruby version if the executing language is Ruby.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

when it's not ruby would we just leave this blank?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should get it from the wrapping language implementation

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So perhaps ENV['PACT_EXECUTING_LANGUAGE_VERSION']?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thats seems sensible to me!

@bethesque
Copy link
Member

The next thing we need to do is make this call interrupt the user as little as possible. We want to keep the connection and request timeouts very small.

Some reading:
https://felipeelias.github.io/ruby/2017/08/20/net-http-timeouts.html
https://ruby-doc.org/stdlib-2.2.4/libdoc/net/http/rdoc/Net/HTTP.html (search for timeout in here)

Do you think it's worth using a thread to make sure it's non blocking @uglyog? How have you implemented it in other languages?

@bethesque
Copy link
Member

We also need to make sure any exception that gets thrown does not impact or get shown to the user.

@uglyog
Copy link
Member

uglyog commented Jan 27, 2022

I've implemented it as a background thread in other places

@bethesque
Copy link
Member

Cool. This looks straightforward https://www.rubyguides.com/2015/07/ruby-threads/

@bethesque
Copy link
Member

bethesque commented Feb 1, 2022

Unlike the mock service, this one is reporting at the end of the event, and it's possible that the ruby process will have shut down before the http request is completed. I think we should either call it before the test is run, so it can have lots of time to make the http call, or we need to do a thread.join to ensure it's finished before the tests shut down.

@TimothyJones
Copy link

As mentioned here, I think we should not implement this change.

  1. Tracking the versions of runtime is potentially information an attacker can use
  2. This updates pact to call home rather than just track the downloads
  3. Our tracking is opt-out by default (in pact-js have a friendly message that essentially says "we just tracked you! Let us know if you want us to not do that again")

If we do bring in a change like this, I think it should be opt-in by default - as that's the trend (and in my view best-behaviour) these days anyway. I created pact-foundation/pact-js-core#360 to track this for pact-js.

Critically, I think the GDPR is relevant here, too - as it means that we're gaining access to information that is already stored on the user's machine that could be used in the process of identifying them (and isn't required for the operation of the service, which means the exception doesn't apply). This means it must be opt-in. There's some discussion on stack exchange here (although it's about local storage, the discussion is relevant).

@mefellows
Copy link
Member

@TimothyJones I understand your concern, rather than duplicating responses, I'll refer to https://github.com/pact-foundation/pact-js-core/pull/359#issuecomment-1027529629] which sums up the thinking so future readers will know where to look.

@mefellows
Copy link
Member

Confirming the telemetry docs page is now live and shared with maintainers, who have given it the 👍 .


def self.handle_error e
if ENV['PACT_METRICS_DEBUG'] == 'true'
Pact.configuration.output_stream.puts("DEBUG: #{e.inspect}")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

e.inspect doesn't include the backtrace. Can you make this

Pact.configuration.output_stream.puts("DEBUG: #{e.inspect}\n" + e.backtrace.join("\n"))


private

def self.handle_error e
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indentation is a bit off here.

@bethesque bethesque merged commit 4497ee9 into pact-foundation:master Feb 21, 2022
alex9smith pushed a commit to alphagov/account-api that referenced this pull request Feb 22, 2022
The upgrade to pact 1.62.0 includes pact-foundation/pact-ruby#256
which adds telemetry[[1]] for the package maintainers.

Set the `PACT_DO_NOT_TRACK` environment variable which opts out of
sending this telemetry.

[1]: https://docs.pact.io/telemetry/
kevindew added a commit to alphagov/publishing-api that referenced this pull request Apr 8, 2022
Pact have recently added tracking to their project which will result in
data sent from our build servers to their servers [1].

I'm not sure if we have a collective opinion on whether we're happy with
this or not, so it seems simplest to disable it and save the need for a
divisive decision.

[1]: pact-foundation/pact-ruby#256
kevindew added a commit to alphagov/publishing-api that referenced this pull request Apr 8, 2022
Pact have recently added tracking to their project which will result in
data sent from our build servers to their servers [1].

I'm not sure if we have a collective opinion on whether we're happy with
this or not, so it seems simplest to disable it and save the need for a
divisive decision.

[1]: pact-foundation/pact-ruby#256
kevindew added a commit to alphagov/gds-api-adapters that referenced this pull request Aug 17, 2022
Pact have recently added tracking to their project which will result in
data sent from our build servers to their servers [1].

I'm not sure if we have a collective opinion on whether we're happy with
this or not, so it seems simplest to disable it and save the need for a
divisive decision. It also gets rid of an annoying warning.

[1]: pact-foundation/pact-ruby#256
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants