require 'builder_apm/doctor/backtrace_reducer' require 'builder_apm/doctor/ai_doctor' module BuilderApm class DiagnoseRequestController < ApplicationController before_action :fetch_deeper_diagnosis, only: [:deeper_analysis] before_action :fetch_existing_diagnosis, only: [:deeper_analysis, :index] before_action :fetch_request_data, only: [:deeper_analysis, :index] def index return render json: { request_id: request_id, full_diagnosis: @existing_diagnosis } if @existing_diagnosis return render json: { error: "No data found for #{request_id}" }, status: :not_found unless @parsed_request_data diagnosis = doctor.diagnose(@parsed_request_data) redis_client.set(redis_diagnosis_key, diagnosis) render json: { request_id: request_id, full_diagnosis: diagnosis } end def deeper_analysis return render json: { request_id: request_id, deeper_diagnosis: @existing_deeper_diagnosis } if @existing_deeper_diagnosis return render json: { error: "No diagnosis found for #{request_id}" }, status: :not_found unless @existing_diagnosis return render json: { error: "No data found for #{request_id}" }, status: :not_found unless @parsed_request_data return render json: { error: "No file or line number passed" }, status: :not_found unless files diagnosis = doctor.deeper_analysis(@parsed_request_data, @existing_diagnosis, files) redis_client.set(redis_deeper_diagnosis_key, diagnosis) render json: { request_id: request_id, deeper_diagnosis: diagnosis } end private def doctor @doctor ||= BuilderApm::Doctor::AiDoctor.new end def fetch_deeper_diagnosis @existing_deeper_diagnosis = redis_client.get(redis_deeper_diagnosis_key) end def fetch_existing_diagnosis @existing_diagnosis = redis_client.get(redis_diagnosis_key) end def fetch_request_data @request_data = redis_client.get(redis_request_key) @parsed_request_data = @request_data ? JSON.parse(@request_data) : nil end def redis_keys { request: "builder_apm:Request:#{request_id}", diagnosis: "builder_apm:RequestDiagnosis:#{request_id}", deeper_diagnosis: "builder_apm:RequestDiagnosis:Deeper:#{request_id}" } end def redis_request_key redis_keys[:request] end def redis_diagnosis_key redis_keys[:diagnosis] end def redis_deeper_diagnosis_key redis_keys[:deeper_diagnosis] end def request_id @request_id ||= params[:request_id] end def files @files ||= params[:files] end end end