Class: ChefApply::Telemeter

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Includes:
Singleton
Defined in:
lib/chef_apply/telemeter.rb,
lib/chef_apply/telemeter/sender.rb

Overview

This definites the Telemeter interface. Implementation thoughts for when we unstub it:

  • let’s track the call sequence; most of our calls will be nested inside

a main ‘timed_capture’, and it would be good to see ordering within nested calls.

Defined Under Namespace

Classes: Sender

Constant Summary collapse

DEFAULT_INSTALLATION_GUID =
"00000000-0000-0000-0000-000000000000".freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeTelemeter



52
53
54
55
# File 'lib/chef_apply/telemeter.rb', line 52

def initialize
  @events_to_send = []
  @run_timestamp =  Time.now.utc.strftime("%FT%TZ")
end

Instance Attribute Details

#events_to_sendObject (readonly)

Returns the value of attribute events_to_send.



45
46
47
# File 'lib/chef_apply/telemeter.rb', line 45

def events_to_send
  @events_to_send
end

#run_timestampObject (readonly)

Returns the value of attribute run_timestamp.



45
46
47
# File 'lib/chef_apply/telemeter.rb', line 45

def run_timestamp
  @run_timestamp
end

Instance Method Details

#capture(name, data = {}) ⇒ Object



77
78
79
80
81
82
# File 'lib/chef_apply/telemeter.rb', line 77

def capture(name, data = {})
  # Adding it to the head of the list will ensure that the
  # sequence of events is preserved when we send the final payload
  payload = make_event_payload(name, data)
  @events_to_send.unshift payload
end

#commitObject



90
91
92
93
94
95
96
# File 'lib/chef_apply/telemeter.rb', line 90

def commit
  if enabled?
    session = convert_events_to_session
    write_session(session)
  end
  @events_to_send = []
end

#enabled?Boolean



47
48
49
50
# File 'lib/chef_apply/telemeter.rb', line 47

def enabled?
  require "telemetry/decision"
  ChefApply::Config.telemetry.enable && !Telemetry::Decision.env_opt_out?
end

#installation_idObject



110
111
112
113
114
115
116
117
118
# File 'lib/chef_apply/telemeter.rb', line 110

def installation_id
  @installation_id ||=
    begin
      File.read(ChefApply::Config.telemetry_installation_identifier_file).chomp
    rescue
      ChefApply::Log.info "could not read #{ChefApply::Config.telemetry_installation_identifier_file} - using default id"
      DEFAULT_INSTALLATION_GUID
    end
end

#last_eventObject



125
126
127
# File 'lib/chef_apply/telemeter.rb', line 125

def last_event
  @events_to_send.last
end

#make_event_payload(name, data) ⇒ Object



98
99
100
101
102
103
104
105
106
107
108
# File 'lib/chef_apply/telemeter.rb', line 98

def make_event_payload(name, data)
  {
    event: name,
    properties: {
      installation_id: installation_id,
      run_timestamp: run_timestamp,
      host_platform: host_platform,
      event_data: data,
    },
  }
end

#pending_event_countObject

For testing.



121
122
123
# File 'lib/chef_apply/telemeter.rb', line 121

def pending_event_count
  @events_to_send.length
end

#timed_action_capture(action, &block) ⇒ Object



57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/chef_apply/telemeter.rb', line 57

def timed_action_capture(action, &block)
  # Note: we do not directly capture hostname for privacy concerns, but
  # using a sha1 digest will allow us to anonymously see
  # unique hosts to derive number of hosts affected by a command
  target = action.target_host
  target_data = { platform: {}, hostname_sha1: nil, transport_type: nil }
  if target
    target_data[:platform][:name] = target.base_os # :windows, :linux, eventually :macos
    target_data[:platform][:version] = target.version
    target_data[:platform][:architecture] = target.architecture
    target_data[:hostname_sha1] = Digest::SHA1.hexdigest(target.hostname.downcase)
    target_data[:transport_type] = target.transport_type
  end
  timed_capture(:action, { action: action.name, target: target_data }, &block)
end

#timed_capture(name, data = {}) ⇒ Object



84
85
86
87
88
# File 'lib/chef_apply/telemeter.rb', line 84

def timed_capture(name, data = {})
  time = Benchmark.measure { yield }
  data[:duration] = time.real
  capture(name, data)
end

#timed_run_capture(arguments, &block) ⇒ Object



73
74
75
# File 'lib/chef_apply/telemeter.rb', line 73

def timed_run_capture(arguments, &block)
  timed_capture(:run, arguments: arguments, &block)
end