class RuntimeProfiler::Data
Attributes
controller_data[R]
sql_data[R]
Public Class Methods
new(controller_data: nil, sql_data: nil)
click to toggle source
# File lib/runtime_profiler/data.rb, line 5 def initialize(controller_data: nil, sql_data: nil) @controller_data = controller_data || {} @sql_data = sql_data end
Public Instance Methods
persist!()
click to toggle source
# File lib/runtime_profiler/data.rb, line 10 def persist! File.open(output_file, 'w') do |f| f.write JSON.dump(profiling_data) end puts "\n" puts 'Profiling data written at ' + output_file.to_s puts 'You can view profiling data via: bundle exec runtime_profiler view ' + output_file.to_s puts "\n" end
Private Instance Methods
method_calls_data()
click to toggle source
# File lib/runtime_profiler/data.rb, line 59 def method_calls_data @method_calls_data ||= begin profiled_methods = {} # TODO: Group methods under a key and under an object MethodMeter.measurement.each_pair do |key, data| data.each do |d| object = d[:method].split(separator = '.') object = d[:method].split(separator = '#') if object.length == 1 d[:method] = separator + object.second if profiled_methods[object.first] profiled_methods[object.first] << d else profiled_methods[object.first] = [d] end end end profiled_methods = profiled_methods.inject({}) do |hash, (key, value)| val = value.sort { |a, b| b[:total_runtime] <=> a[:total_runtime] } hash[key] = val hash end slowest_method = {total_runtime: 0} mostly_called_method = {total_calls: 0} profiled_methods.each do |profiled_object_name, methods| # sort using `total_runtime` in DESC order _methods = methods.sort { |a, b| b[:total_runtime] <=> a[:total_runtime] } slowest = _methods[0] if slowest[:total_runtime] > slowest_method[:total_runtime] slowest_method[:method] = [profiled_object_name, slowest[:method]].join slowest_method[:total_runtime] = slowest[:total_runtime] end # sort using `total_calls` in DESC order and GET first item mostly_called = methods.sort { |a, b| b[:total_calls] <=> a[:total_calls] } [0] if mostly_called[:total_calls] > mostly_called_method[:total_calls] mostly_called_method[:method] = [profiled_object_name, mostly_called[:method]].join mostly_called_method[:total_runtime] = mostly_called[:total_runtime] mostly_called_method[:total_calls] = mostly_called[:total_calls] mostly_called_method[:min] = mostly_called[:min] mostly_called_method[:max] = mostly_called[:max] end end { profiled_methods: profiled_methods, slowest_method: slowest_method, mostly_called_method: mostly_called_method } end end
output_file()
click to toggle source
# File lib/runtime_profiler/data.rb, line 23 def output_file FileUtils.mkdir_p(RuntimeProfiler.output_path) filename = ['rp', Process.pid, Time.now.to_i].join('-') + '.json' File.join(RuntimeProfiler.output_path, filename) end
profiled_api()
click to toggle source
# File lib/runtime_profiler/data.rb, line 29 def profiled_api return unless controller_data[:payload] @profiled_api ||= [ controller_data[:payload][:controller], controller_data[:payload][:action] ].join('#') end
profiling_data()
click to toggle source
# File lib/runtime_profiler/data.rb, line 37 def profiling_data @profiling_data ||= { profiling: { profiled_api: profiled_api, summary: { db_runtime: controller_data[:db_runtime], view_runtime: controller_data[:view_runtime], total_runtime: controller_data[:total_runtime], slowest_sql: sql_calls_data[:slowest_sql], mostly_called_sql: sql_calls_data[:mostly_called_sql], total_sql_calls: sql_calls_data[:total_sql_calls], total_unique_sql_calls: sql_calls_data[:total_unique_sql_calls], slowest_method: method_calls_data[:slowest_method], mostly_called_method: method_calls_data[:mostly_called_method] }, profiled_sql_calls: sql_calls_data[:profiled_sql_calls], profiled_methods: method_calls_data[:profiled_methods], profiled_at: Time.now } } end
sql_calls_data()
click to toggle source
# File lib/runtime_profiler/data.rb, line 118 def sql_calls_data @sql_calls_data ||= begin profiled_sql_calls = [] slowest_sql = {total_runtime: 0} mostly_called_sql = {total_calls: 0} sql_data.values.each do |value| total_calls = value[:runtimes].size total_runtime = value[:runtimes].map { |runtime| runtime[0] }.reduce(:+) average = total_runtime / total_calls # sort using `runtimes` in DESC order runtimes = value[:runtimes].sort { |a, b| b[0] <=> a[0] } slowest = runtimes[0] fastest = runtimes[runtimes.size - 1] if slowest[0] > slowest_sql[:total_runtime] slowest_sql[:sql] = value[:sql] slowest_sql[:total_runtime] = slowest[0] slowest_sql[:source] = slowest[1] end profiled_sql_calls << { sql: value[:sql], runtimes: runtimes, total_calls: total_calls, total_runtime: total_runtime, average: average, min: fastest[0], max: slowest[0] } if total_calls > mostly_called_sql[:total_calls] mostly_called_sql[:sql] = value[:sql] mostly_called_sql[:runtimes] = value[:runtimes] mostly_called_sql[:total_calls] = total_calls mostly_called_sql[:total_runtime] = total_runtime mostly_called_sql[:average] = average mostly_called_sql[:min] = fastest[0] mostly_called_sql[:max] = slowest[0] end end { profiled_sql_calls: profiled_sql_calls.sort { |a, b| b[:max] <=> a[:max] }, total_sql_calls: profiled_sql_calls.map { |sql_call| sql_call[:total_calls] }.reduce(:+), total_unique_sql_calls: profiled_sql_calls.size, slowest_sql: slowest_sql, mostly_called_sql: mostly_called_sql } end end