Module: GDK::Telemetry

Defined in:
lib/gdk/telemetry.rb

Constant Summary collapse

ANALYTICS_APP_ID =
'e2e967c0-785f-40ae-9b45-5a05f729a27f'
ANALYTICS_BASE_URL =
'https://collector.prod-1.gl-product-analytics.com'
SENTRY_DSN =
'https://glet_d59ce9a0092b7f3e0dcecc954e4d1666@observe.gitlab.com:443/errortracking/api/v1/projects/74823'
PROMPT_TEXT =
<<-TEXT
  To improve GDK, GitLab would like to collect basic error and usage data. Please choose one of the following options:

  - To send data to GitLab, enter your GitLab username.
  - To send data to GitLab anonymously, leave blank.
  - To avoid sending data to GitLab, enter a period ('.').
TEXT

Class Method Summary collapse

Class Method Details

.capture_exception(message) ⇒ Object



81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/gdk/telemetry.rb', line 81

def self.capture_exception(message)
  return unless telemetry_enabled?

  if message.is_a?(Exception)
    exception = message.dup
  else
    exception = StandardError.new(message)
    exception.set_backtrace(caller)
  end

  # Drop the caller GDK::Telemetry.capture_exception to make errors distinct.
  exception.set_backtrace(exception.backtrace.drop(1)) if exception.backtrace

  init_sentry
  Sentry.capture_exception(exception)
end

.clientObject



50
51
52
53
54
55
56
57
58
# File 'lib/gdk/telemetry.rb', line 50

def self.client
  return @client if @client

  app_id = ENV.fetch('GITLAB_SDK_APP_ID', ANALYTICS_APP_ID)
  host = ENV.fetch('GITLAB_SDK_HOST', ANALYTICS_BASE_URL)

  SnowplowTracker::LOGGER.level = Logger::WARN
  @client = GitlabSDK::Client.new(app_id: app_id, host: host)
end

.flush_events(async: false) ⇒ Object



42
43
44
# File 'lib/gdk/telemetry.rb', line 42

def self.flush_events(async: false)
  client.flush_events(async: async)
end

.init_sentryObject



60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/gdk/telemetry.rb', line 60

def self.init_sentry
  Sentry.init do |config|
    config.dsn = SENTRY_DSN
    config.breadcrumbs_logger = [:sentry_logger]
    config.traces_sample_rate = 1.0
    config.logger.level = Logger::WARN

    config.before_send = lambda do |event, hint|
      exception = hint[:exception]

      # Workaround for using fingerprint to make certain errors distinct.
      # See https://gitlab.com/gitlab-org/opstrace/opstrace/-/issues/2842#note_1927103517
      event.transaction = exception.message if exception.is_a?(Shellout::ShelloutBaseError)

      event
    end
  end

  Sentry.set_user(username: GDK.config.telemetry.username)
end

.platformObject



46
47
48
# File 'lib/gdk/telemetry.rb', line 46

def self.platform
  GDK.config.telemetry.platform
end

.send_telemetry(success, command, payload = {}) ⇒ Object



34
35
36
37
38
39
40
# File 'lib/gdk/telemetry.rb', line 34

def self.send_telemetry(success, command, payload = {})
  # This is tightly coupled to GDK commands and returns false when the system call exits with a non-zero status.
  status = success ? 'Finish' : 'Failed'

  client.identify(GDK.config.telemetry.username)
  client.track("#{status} #{command} #{ARGV}", payload)
end

.telemetry_enabled?Boolean

Returns:

  • (Boolean)


98
99
100
# File 'lib/gdk/telemetry.rb', line 98

def self.telemetry_enabled?
  GDK.config.telemetry.enabled
end

.update_settings(username) ⇒ Object



102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/gdk/telemetry.rb', line 102

def self.update_settings(username)
  enabled = true
  username = username.to_s

  if username.empty?
    username = SecureRandom.hex
  elsif username == '.'
    username = ''
    enabled = false
  end

  GDK.config.bury!('telemetry.enabled', enabled)
  GDK.config.bury!('telemetry.username', username)
  GDK.config.save_yaml!
end

.with_telemetry(command) ⇒ Object



20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/gdk/telemetry.rb', line 20

def self.with_telemetry(command)
  return yield unless telemetry_enabled?

  start = Process.clock_gettime(Process::CLOCK_MONOTONIC)

  result = yield

  duration = Process.clock_gettime(Process::CLOCK_MONOTONIC) - start

  send_telemetry(result, command, { duration: duration, platform: platform })

  result
end