Skip to content

Instantly share code, notes, and snippets.

@solso
Last active August 24, 2020 21:52
Show Gist options
  • Save solso/5065543 to your computer and use it in GitHub Desktop.
Save solso/5065543 to your computer and use it in GitHub Desktop.
def api_call_account_read(domain, provider_key, account_id)
url = "https://#{domain}/admin/api/accounts/#{account_id}.xml?provider_key=#{provider_key}"
response = RestClient.get url
raise Exception.new("Wrong response code (#{response.code}) in request #{url}") if response.code!=200
document = Nokogiri::XML(response.to_str)
account = Hash.new
account["email"] = document.xpath("//users/user/email").text
account["name"] = document.xpath("//users/user/first_name").text + " " + document.xpath("//users/user/last_name").text
return account
end
require 'restclient'
require 'nokogiri'
require 'date'
require 'cgi'
DOMAIN = "YOUR-3SCALE-ADMIN_PORTAL-DOMAIN (e.g. foobar-admin.3scale.net)"
PROVIDER_KEY = "YOUR_PROVIDER_KEY"
PLAN_NAME = "Evaluation Plan"
NUM_OF_DAYS = 10
METRIC = "hits"
def api_call_applications_list(domain, provider_key)
done = false
res = Array.new
page = 1
while !done
url = "https://#{domain}/admin/api/applications.xml?provider_key=#{provider_key}&page=#{page}&per_page=100"
page += 1
response = RestClient.get url
raise Exception.new("Wrong response code (#{response.code}) in request #{url}") if response.code!=200
document = Nokogiri::XML(response.to_str)
done = document.xpath("applications/@current_page").text == document.xpath("applications/@total_pages").text
document.xpath("//application").each do |item|
app = Hash.new
app["created_at"] = DateTime.parse(item.xpath("created_at").text)
app["plan_name"] = item.xpath("plan/name").text
app["service_id"] = item.xpath("plan/service_id").text
app["account_id"] = item.xpath("user_account_id").text
app["id"] = item.xpath("id").text
res << app
end
end
return res
end
def filter_applications(domain, provider_key, plan_name, num_of_days)
res = api_call_applications_list(domain, provider_key)
res.each do |item|
res.delete(item) if item["plan_name"] != plan_name
res.delete(item) if item["created_at"] > (DateTime.now - num_of_days)
end
return res
end
def api_call_application_usage(domain, provider_key, application_id, metric, from, to, granularity)
url = "https://#{domain}/stats/applications/#{application_id}/usage.xml?provider_key=#{provider_key}&metric_name=#{metric}&since=#{from}&until=#{to}&granularity=#{granularity}"
response = RestClient.get url
raise Exception.new("Wrong response code (#{response.code}) in request #{url}") if response.code!=200
document = Nokogiri::XML(response.to_str)
return document.xpath("//usage/data/values").text.split(",")
end
def fetch_stats(applications, domain, provider_key, metric, from, to, granularity)
applications.each do |app|
results = api_call_application_usage(domain, provider_key, app["id"], metric, from, to, granularity)
first_period = results[0..results.size/2]
second_period = results[results.size/2..results.size]
sum = 0
first_period.each do |value|
sum += value.to_i
end
app["hits_first_period"]=sum
sum = 0
second_period.each do |value|
sum += value.to_i
end
app["hits_second_period"]=sum
end
return applications
end
def api_call_account_read(domain, provider_key, account_id)
url = "https://#{domain}/admin/api/accounts/#{account_id}.xml?provider_key=#{provider_key}"
response = RestClient.get url
raise Exception.new("Wrong response code (#{response.code}) in request #{url}") if response.code!=200
document = Nokogiri::XML(response.to_str)
account = Hash.new
account["email"] = document.xpath("//users/user/email").text
account["name"] = document.xpath("//users/user/first_name").text + " " + document.xpath("//users/user/last_name").text
return account
end
def fetch_account_info(applications, domain, provider_key)
accounts = Hash.new
applications.each do |app|
if accounts[app["account_id"]].nil?
accounts[app["account_id"]] = api_call_account_read(domain, provider_key,app["account_id"])
end
end
return accounts
end
##----------------------------------
##----------------------------------
puts "Fetching the full list of applications and filter them..."
applications = filter_applications(DOMAIN,PROVIDER_KEY,PLAN_NAME,NUM_OF_DAYS)
puts "Done! In the last #{NUM_OF_DAYS} days there are #{applications.size} new applications in the plan #{PLAN_NAME}\n"
puts "Fetching the stats for each application..."
applications = fetch_stats(applications,DOMAIN,PROVIDER_KEY,METRIC,CGI.escape((DateTime.now-NUM_OF_DAYS).to_s),CGI.escape(DateTime.now.to_s),"day")
puts "Done! Getting the contact information for each application..."
accounts = fetch_account_info(applications,DOMAIN,PROVIDER_KEY)
puts "Done! Printing the analytics...\n"
accounts_active = Hash.new
list_of_accounts_inactive = Array.new
list_of_accounts_that_have_become_active = Array.new
list_of_accounts_that_have_become_inactive = Array.new
applications.each do |app|
if app["hits_first_period"]==0 && app["hits_second_period"]==0
list_of_accounts_inactive << app["account_id"]
elsif app["hits_first_period"]==0 && app["hits_second_period"]>0
list_of_accounts_that_have_become_active << app["account_id"]
elsif app["hits_first_period"]>0 && app["hits_second_period"]==0
list_of_accounts_that_have_become_inactive << app["account_id"]
else
growth_in_percentage = (((app["hits_second_period"].to_f/app["hits_first_period"].to_f)-1.0)*100.0) if app["hits_first_period"]>0
accounts_active[app["account_id"]] = growth_in_percentage.round(2)
end
end
puts "There are #{list_of_accounts_inactive.size} accounts that have not seen any traffic yet, totally inactive."
puts "There are #{list_of_accounts_that_have_become_inactive.size} accounts that had traffic for first half of the #{NUM_OF_DAYS} days but then stopped the traffic."
if list_of_accounts_that_have_become_inactive.size > 0
puts "Full list:"
list_of_accounts_that_have_become_inactive.each do |account_id|
puts "#{account_id} #{accounts[account_id]["email"]} #{accounts[account_id]["name"]}"
end
end
puts "There are #{list_of_accounts_that_have_become_active.size} accounts that had no traffic for first half of the #{NUM_OF_DAYS} days and they have traffic now."
if list_of_accounts_that_have_become_active.size > 0
puts "Full list:"
list_of_accounts_that_have_become_active.each do |account_id|
puts "#{account_id} #{accounts[account_id]["email"]} #{accounts[account_id]["name"]}"
end
end
puts "\nFinally. List of accounts sorted by percentual growth in the #{NUM_OF_DAYS} period."
sorted_accounts = accounts_active.sort {|a1,a2| a2[1]<=>a1[1]}
sorted_accounts.each do |item|
puts "#{item[0]} #{item[1]}\% #{accounts[item[0]]["email"]} #{accounts[item[0]]["name"]}"
end
def api_call_application_usage(domain, provider_key, application_id, metric, from, to, granularity)
url = "https://#{domain}/stats/applications/#{application_id}/usage.xml?provider_key=#{provider_key}&metric_name=#{metric}&since=#{from}&until=#{to}&granularity=#{granularity}"
response = RestClient.get url
raise Exception.new("Wrong response code (#{response.code}) in request #{url}") if response.code!=200
document = Nokogiri::XML(response.to_str)
return document.xpath("//usage/data/values").text.split(",")
end
def filter_applications(domain, provider_key, plan_name, num_of_days)
res = api_call_applications_list(domain, provider_key)
res.each do |item|
res.delete(item) if item["plan_name"] != plan_name
res.delete(item) if item["created_at"] > (DateTime.now - num_of_days)
end
return res
end
def api_call_applications_list(domain, provider_key)
done = false
res = Array.new
page = 1
while !done
url = "https://#{domain}/admin/api/applications.xml?provider_key=#{provider_key}&page=#{page}&per_page=100"
page += 1
response = RestClient.get url
raise Exception.new("Wrong response code (#{response.code}) in request #{url}") if response.code!=200
document = Nokogiri::XML(response.to_str)
done = document.xpath("applications/@current_page").text == document.xpath("applications/@total_pages").text
document.xpath("//application").each do |item|
app = Hash.new
app["created_at"] = DateTime.parse(item.xpath("created_at").text)
app["plan_name"] = item.xpath("plan/name").text
app["service_id"] = item.xpath("plan/service_id").text
app["account_id"] = item.xpath("user_account_id").text
app["id"] = item.xpath("id").text
res << app
end
end
return res
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment