/
profiler_middleware.rb
78 lines (64 loc) · 2 KB
/
profiler_middleware.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
module Rack::PerftoolsProfiler
class ProfilerArgumentError < RuntimeError; end;
class ProfilerMiddleware
include Rack::Utils
PRINTER_CONTENT_TYPE = {
:text => 'text/plain',
:gif => 'image/gif',
:pdf => 'application/pdf',
:callgrind => 'text/plain',
:raw => 'application/octet-stream'
}
PRINTERS = PRINTER_CONTENT_TYPE.keys
def initialize(app, options = {})
@app = app
@profiler = Profiler.new(@app, options.clone)
end
def call(env)
# I used to clone the env, but it broke any apps that used Warden
# ex) @env = env.clone
@env = env
action = Action.for_env(@env, @profiler, self)
action.act
action.response
rescue ProfilerArgumentError => err
@env['rack.errors'].write(err.message)
[400, {'Content-Type' => 'text/plain'}, [err.message]]
rescue ProfilingError => err
@env['rack.errors'].write(err.message + "\n" + err.stderr)
[500, {'Content-Type' => 'text/plain'}, [err.message+"\n\n", "Standard error:\n"+err.stderr+"\n"]]
end
def call_app(env)
@app.call(env)
end
def force_stop
@profiler.stop
end
def profiler_data_response(profiling_data)
format, body = profiling_data
body = Array(body)
if format==:none
message = 'No profiling data available. Visit /__stop__ and then visit /__data__'
[404, {'Content-Type' => 'text/plain'}, [message]]
else
[200, headers(format, body), Array(body)]
end
end
private
def headers(printer, body)
headers = {
'Content-Type' => PRINTER_CONTENT_TYPE[printer],
'Content-Length' => content_length(body)
}
if printer==:pdf
filetype = printer
filename='profile_data'
headers['Content-Disposition'] = %(attachment; filename="#{filename}.#{filetype}")
end
headers
end
def content_length(body)
body.inject(0) { |len, part| len + bytesize(part) }.to_s
end
end
end