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: telemetry for all commands #366

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions lib/aptible/cli/agent.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

require_relative 'helpers/ssh'
require_relative 'helpers/token'
require_relative 'helpers/telemetry'
require_relative 'helpers/operation'
require_relative 'helpers/environment'
require_relative 'helpers/app'
Expand Down
58 changes: 58 additions & 0 deletions lib/aptible/cli/helpers/telemetry.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
require 'httpclient'
require 'securerandom'
require 'uri'

module Aptible
module CLI
module Helpers
module Telemetry
def telemetry(cmd, options = {})
token_hash = decode_token
format = Renderer.format
format = 'text' if format.nil?
sub = token_hash[0]['sub']
parsed_url = URI.parse(sub)
path_components = parsed_url.path.split('/')
user_or_org_id = path_components.last
# https://github.com/aptible/aptible-resource/blob/7c3a79e6eee9c88aa7dbf332e550508f22a5b08d/lib/hyper_resource/modules/http.rb#L21
client = HTTPClient.new.tap do |c|
c.cookie_manager = nil
c.connect_timeout = 30
c.send_timeout = 45
c.keep_alive_timeout = 15
c.ssl_config.set_default_paths
end

value = {
'email' => token_hash[0]['email'],
'format' => format,
'cmd' => cmd,
'options' => options,
'version' => version_string,
# https://stackoverflow.com/a/73973555
'github' => ENV['GITHUB_ACTIONS'],
'gitlab' => ENV['GITLAB_CI'],
'travis' => ENV['TRAVIS'],
'circleci' => ENV['CIRCLECI'],
'ci' => ENV['CI']
}

begin
uri = URI('https://tuna.aptible.com/www/e')
client.get(
uri,
'id' => SecureRandom.uuid,
'user_id' => user_or_org_id,
'type' => 'cli_telemetry',
'url' => sub,
'value' => value
)
rescue
# since this is just for telemetry we don't want to notify
# user of an error
end
end
end
end
end
end
6 changes: 6 additions & 0 deletions lib/aptible/cli/helpers/token.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
require 'aptible/auth'
require 'jwt'

require_relative 'config_path'

Expand Down Expand Up @@ -46,6 +47,11 @@ def current_token_hash
def token_file
File.join(aptible_config_path, 'tokens.json').freeze
end

def decode_token
tok = fetch_token
JWT.decode(tok, nil, false)
end
end
end
end
Expand Down
6 changes: 5 additions & 1 deletion lib/aptible/cli/renderer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,12 @@ module CLI
module Renderer
FORMAT_VAR = 'APTIBLE_OUTPUT_FORMAT'.freeze

def self.format
ENV[FORMAT_VAR]
end

def self.current
case (format = ENV[FORMAT_VAR])
case format
when 'json'
Json.new
when 'text'
Expand Down
11 changes: 11 additions & 0 deletions lib/aptible/cli/subcommands/apps.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,13 @@ def self.included(thor)
include Helpers::App
include Helpers::Environment
include Helpers::Token
include Helpers::Telemetry

desc 'apps', 'List all applications'
option :environment, aliases: '--env'
def apps
telemetry(__method__, options)

Formatter.render(Renderer.current) do |root|
root.grouped_keyed_list(
{ 'environment' => 'handle' },
Expand All @@ -30,6 +33,8 @@ def apps
desc 'apps:create HANDLE', 'Create a new application'
option :environment, aliases: '--env'
define_method 'apps:create' do |handle|
telemetry(__method__, options)

environment = ensure_environment(options)
app = environment.create_app(handle: handle)

Expand All @@ -56,6 +61,8 @@ def apps
option :container_profile, type: :string,
desc: 'Examples: m c r'
define_method 'apps:scale' do |type|
telemetry(__method__, options)

service = ensure_service(options, type)

container_count = options[:container_count]
Expand Down Expand Up @@ -89,6 +96,8 @@ def apps
desc 'apps:deprovision', 'Deprovision an app'
app_options
define_method 'apps:deprovision' do
telemetry(__method__, options)

app = ensure_app(options)
CLI.logger.info "Deprovisioning #{app.handle}..."
op = app.create_operation!(type: 'deprovision')
Expand All @@ -108,6 +117,8 @@ def apps
' drain destinations, you must restart the app.'
option :environment, aliases: '--env'
define_method 'apps:rename' do |old_handle, new_handle|
telemetry(__method__, options)

env = ensure_environment(options)
app = ensure_app(options.merge(app: old_handle))
app.update!(handle: new_handle)
Expand Down
9 changes: 9 additions & 0 deletions lib/aptible/cli/subcommands/backup.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ def self.included(thor)
thor.class_eval do
include Helpers::Token
include Helpers::Database
include Helpers::Telemetry

desc 'backup:restore BACKUP_ID ' \
'[--environment ENVIRONMENT_HANDLE] [--handle HANDLE] ' \
Expand All @@ -24,6 +25,8 @@ def self.included(thor)
desc: 'Examples: m c r'
option :iops, type: :numeric
define_method 'backup:restore' do |backup_id|
telemetry(__method__, options)

backup = Aptible::Api::Backup.find(backup_id, token: fetch_token)
raise Thor::Error, "Backup ##{backup_id} not found" if backup.nil?

Expand Down Expand Up @@ -74,6 +77,8 @@ def self.included(thor)
default: '99y',
desc: 'Limit backups returned (example usage: 1w, 1y, etc.)'
define_method 'backup:list' do |handle|
telemetry(__method__, options)

age = ChronicDuration.parse(options[:max_age])
raise Thor::Error, "Invalid age: #{options[:max_age]}" if age.nil?
min_created_at = Time.now - age
Expand Down Expand Up @@ -101,6 +106,8 @@ def self.included(thor)
desc: 'Limit backups returned '\
'(example usage: 1w, 1y, etc.)'
define_method 'backup:orphaned' do
telemetry(__method__, options)

age = ChronicDuration.parse(options[:max_age])
raise Thor::Error, "Invalid age: #{options[:max_age]}" if age.nil?
min_created_at = Time.now - age
Expand All @@ -126,6 +133,8 @@ def self.included(thor)
desc 'backup:purge BACKUP_ID',
'Permanently delete a backup and any copies of it'
define_method 'backup:purge' do |backup_id|
telemetry(__method__, options)

backup = Aptible::Api::Backup.find(backup_id, token: fetch_token)
raise Thor::Error, "Backup ##{backup_id} not found" if backup.nil?

Expand Down
5 changes: 5 additions & 0 deletions lib/aptible/cli/subcommands/backup_retention_policy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,13 @@ def self.included(thor)
thor.class_eval do
include Helpers::Environment
include Term::ANSIColor
include Helpers::Telemetry

desc 'backup_retention_policy [ENVIRONMENT_HANDLE]',
'Show the current backup retention policy for the environment'
define_method 'backup_retention_policy' do |env|
telemetry(__method__, options)

account = ensure_environment(environment: env)
policy = account.backup_retention_policies.first
unless policy
Expand Down Expand Up @@ -52,6 +55,8 @@ def self.included(thor)
desc: 'Do not prompt for confirmation if the new policy ' \
'retains fewer backups than the current policy'
define_method 'backup_retention_policy:set' do |env|
telemetry(__method__, options)

if options.empty?
raise Thor::Error,
'Please specify at least one attribute to change'
Expand Down
11 changes: 11 additions & 0 deletions lib/aptible/cli/subcommands/config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,13 @@ def self.included(thor)
thor.class_eval do
include Helpers::Operation
include Helpers::App
include Helpers::Telemetry

desc 'config', "Print an app's current configuration"
app_options
def config
telemetry(__method__, options)

app = ensure_app(options)
config = app.current_configuration
env = config ? config.env : {}
Expand All @@ -32,6 +35,8 @@ def config
"Print a specific key within an app's current configuration"
app_options
define_method 'config:get' do |*args|
telemetry(__method__, options)

app = ensure_app(options)
config = app.current_configuration
env = config ? config.env : {}
Expand All @@ -49,6 +54,8 @@ def config
'Add an ENV variable to an app'
app_options
define_method 'config:add' do |*args|
telemetry(__method__, options)

# FIXME: define_method - ?! Seriously, WTF Thor.
app = ensure_app(options)
env = extract_env(args)
Expand All @@ -61,13 +68,16 @@ def config
'Add an ENV variable to an app'
app_options
define_method 'config:set' do |*args|
telemetry(__method__, options)
send('config:add', *args)
end

desc 'config:rm [VAR1] [VAR2] [...]',
'Remove an ENV variable from an app'
app_options
define_method 'config:rm' do |*args|
telemetry(__method__, options)

# FIXME: define_method - ?! Seriously, WTF Thor.
app = ensure_app(options)
env = Hash[args.map do |arg|
Expand All @@ -84,6 +94,7 @@ def config
'Remove an ENV variable from an app'
app_options
define_method 'config:unset' do |*args|
telemetry(__method__, options)
send('config:rm', *args)
end
end
Expand Down
Loading