lib/rorvswild.rb in rorvswild-0.0.6 vs lib/rorvswild.rb in rorvswild-0.0.7

- old
+ new

@@ -1,12 +1,25 @@ require "rorvswild/version" module RorVsWild def self.new(*args) + warn "WARNING: RorVsWild.new is deprecated. Use RorVsWild::Client.new instead." Client.new(*args) # Compatibility with 0.0.1 end + def self.register_default_client(client) + @default_client = client + end + + def self.default_client + @default_client + end + + def self.measure_job(code) + default_client ? default_client.measure_job(code) : eval(code) + end + class Client def self.default_config { api_url: "http://www.rorvswild.com/api", explain_sql_threshold: 500, @@ -22,20 +35,21 @@ @log_sql_threshold = config[:log_sql_threshold] @api_url = config[:api_url] @api_key = config[:api_key] @app_id = config[:app_id] setup_callbacks + RorVsWild.register_default_client(self) end def setup_callbacks ActiveSupport::Notifications.subscribe("sql.active_record", &method(:after_sql_query)) ActiveSupport::Notifications.subscribe("render_template.action_view", &method(:after_view_rendering)) ActiveSupport::Notifications.subscribe("process_action.action_controller", &method(:after_http_request)) ActiveSupport::Notifications.subscribe("start_processing.action_controller", &method(:before_http_request)) - this = self - ApplicationController.rescue_from(StandardError) { |exception| this.after_exception(exception, self) } + client = self + ActionController::Base.rescue_from(StandardError) { |exception| client.after_exception(exception, self) } end def before_http_request(name, start, finish, id, payload) @request = {controller: payload[:controller], action: payload[:action], path: payload[:path]} @queries = [] @@ -91,10 +105,37 @@ } end raise exception end + def measure_job(code) + @queries = [] + @job = {name: code} + started_at = Time.now + cpu_time_offset = cpu_time + eval(code) + rescue => exception + file, line = exception.backtrace.first.split(":") + job[:error] = { + line: line.to_i, + file: relative_path(file), + message: exception.message, + backtrace: exception.backtrace, + exception: exception.class.to_s, + } + raise + ensure + job[:runtime] = (Time.now - started_at) * 1000 + job[:cpu_runtime] = cpu_time - cpu_time_offset + post_job + end + + def cpu_time + time = Process.times + time.utime + time.stime + time.cutime + time.cstime + end + ####################### ### Private methods ### ####################### private @@ -105,10 +146,14 @@ def views @views end + def job + @job + end + def push_query(query) if query[:sql] || query[:plan] queries << query else if hash = queries.find { |hash| hash[:line] == query[:line] && hash[:file] == query[:file] } @@ -134,9 +179,15 @@ rescue => ex end def post_request post("/requests", request: request.merge(queries: slowest_queries, views: slowest_views, error: error)) + rescue => exception + log_error(exception) + end + + def post_job + post("/jobs", job: job.merge(queries: slowest_queries)) rescue => exception log_error(exception) end def extract_file_and_line_from_call_stack(stack)