lib/stackprof-webnav/server.rb in stackprof-webnav-0.1.0 vs lib/stackprof-webnav/server.rb in stackprof-webnav-1.0.0
- old
+ new
@@ -1,98 +1,147 @@
require 'sinatra'
require 'haml'
require "stackprof"
-require 'net/http'
require_relative 'presenter'
+require_relative 'dump'
+require 'pry'
+require "sinatra/reloader" if development?
+require 'ruby-graphviz'
module StackProf
module Webnav
class Server < Sinatra::Application
class << self
- attr_accessor :cmd_options, :report_dump_path, :report_dump_uri, :report_dump_listing
+ attr_accessor :cmd_options
+ end
- def presenter regenerate=false
- return @presenter unless regenerate || @presenter.nil?
- process_options
- if self.report_dump_path || self.report_dump_uri
- report_contents = if report_dump_path.nil?
- Net::HTTP.get(URI.parse(report_dump_uri))
- else
- File.open(report_dump_path).read
- end
- report = StackProf::Report.new(Marshal.load(report_contents))
- end
- @presenter = Presenter.new(report)
- end
+ configure :development do
+ register Sinatra::Reloader
+ end
- private
- def process_options
- if cmd_options[:filepath]
- self.report_dump_path = cmd_options[:filepath]
- elsif cmd_options[:uri]
- self.report_dump_uri = cmd_options[:uri]
- elsif cmd_options[:bucket]
- self.report_dump_listing = cmd_options[:bucket]
+ configure :production do
+ set :show_exceptions, false
+ end
+
+ error do
+ @error = env['sinatra.error']
+ haml :error
+ end
+
+ before do
+ unless request.path_info == '/'
+ if params[:dump] != current_dump.path
+ current_dump.path = params[:dump]
end
end
-
end
helpers do
- def presenter
- Server.presenter
+ def current_dump
+ Thread.current[:cache] = {}
+ Thread.current[params[:dump]] ||= Dump.new(params[:dump])
end
- def method_url name
- "/method?name=#{URI.escape(name)}"
+ def current_report
+ StackProf::Report.new(
+ Marshal.load(current_dump.content)
+ )
end
- def file_url path
- "/file?path=#{URI.escape(path)}"
+ def presenter
+ Presenter.new(current_report)
end
- def overview_url path
- "/overview?path=#{URI.escape(path)}"
+ def ensure_file_generated(path, &block)
+ return if File.exist?(path)
+ File.open(path, 'wb', &block)
end
+
+ def url_for(path, options={})
+ query = URI.encode_www_form({dump: params[:dump]}.merge(options))
+ path + "?" + query
+ end
end
get '/' do
- presenter
- if Server.report_dump_listing
- redirect '/listing'
- else
- redirect '/overview'
+ if Server.cmd_options[:filepath]
+ query = URI.encode_www_form(dump: Server.cmd_options[:filepath])
+ next redirect to("/overview?#{query}")
end
+
+ @directory = File.expand_path(Server.cmd_options[:directory] || '.')
+ @files = Dir.entries(@directory).sort.map do |file|
+ path = File.expand_path(file, @directory)
+
+ OpenStruct.new(
+ name: file,
+ path: path,
+ modified: File.mtime(path)
+ )
+ end.select do |file|
+ File.file?(file.path)
+ end
+
+ haml :index
end
get '/overview' do
- if params[:path]
- Server.report_dump_uri = params[:path]
- Server.presenter(true)
- end
- @file = Server.report_dump_path || Server.report_dump_uri
@action = "overview"
- @frames = presenter.overview_frames
- haml :overview
+
+ begin
+ @frames = presenter.overview_frames
+ haml :overview
+ rescue => error
+ haml :invalid_dump
+ end
end
- get '/listing' do
- @file = Server.report_dump_listing
- @action = "listing"
- @dumps = presenter.listing_dumps
- haml :listing
+ get '/flames.json' do
+ ensure_file_generated(current_dump.flame_graph_path) do |file|
+ current_report.print_flamegraph(file, true, true)
+ end
+
+ send_file(current_dump.flame_graph_path, type: 'text/javascript')
end
+ get '/graph.png' do
+ ensure_file_generated(current_dump.graph_path) do |file|
+ current_report.print_graphviz({}, file)
+ end
+
+ ensure_file_generated(current_dump.graph_image_path) do |file|
+ GraphViz
+ .parse(current_dump.graph_path)
+ .output(png: current_dump.graph_image_path)
+ end
+
+ send_file(current_dump.graph_image_path, type: 'image/png')
+ end
+
+ get '/graph' do
+ haml :graph
+ end
+
+ get '/flamegraph' do
+ haml :flamegraph
+ end
+
get '/method' do
@action = params[:name]
@frames = presenter.method_info(params[:name])
haml :method
end
get '/file' do
path = params[:path]
- @path = path
- @data = presenter.file_overview(path)
+
+ if File.exist?(path)
+ @path = path
+ @data = presenter.file_overview(path)
+ else
+ @data = nil
+ end
+
haml :file
end
end
end
end