rack-lineprof 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/lib/rack-lineprof.rb +7 -0
- data/lib/rack/lineprof.rb +48 -0
- data/lib/rack/lineprof/sample.rb +34 -0
- data/lib/rack/lineprof/source.rb +82 -0
- metadata +90 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 03560e926089c3bc3b5661cf3ddb7ae0c70db85e
|
4
|
+
data.tar.gz: 0a89ee2f73f88de070f9d115285d62bde7d28409
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 7f3ad2c44b24253ef67769d1c964b38f3b5ad0d4bec7bd0ad779b323157dfdf2025d0830400bc33fb8a707cedfac398c24bc524b9cbccd16fe8bc8163a77e228
|
7
|
+
data.tar.gz: 034f9ea9d291872f848f752523ab541570b84a138e8987c4811cc02d4b12575ca5c0c9749153c25a0e7da3ee97cf7d41af4edabbd798d0b085f47746549de9ac
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'rblineprof'
|
2
|
+
require 'term/ansicolor'
|
3
|
+
|
4
|
+
module Rack
|
5
|
+
class Lineprof
|
6
|
+
|
7
|
+
autoload :Sample, 'rack/lineprof/sample'
|
8
|
+
autoload :Source, 'rack/lineprof/source'
|
9
|
+
|
10
|
+
CONTEXT = 0
|
11
|
+
NOMINAL = 1
|
12
|
+
WARNING = 2
|
13
|
+
CRITICAL = 3
|
14
|
+
|
15
|
+
attr_reader :app, :options
|
16
|
+
|
17
|
+
def initialize app, options = {}
|
18
|
+
@app, @options = app, options
|
19
|
+
end
|
20
|
+
|
21
|
+
def call env
|
22
|
+
request = Rack::Request.new(env)
|
23
|
+
matcher = request.params['lineprof']
|
24
|
+
|
25
|
+
return @app.call env unless matcher
|
26
|
+
|
27
|
+
response = nil
|
28
|
+
profile = lineprof(%r{#{matcher}}) { response = @app.call env }
|
29
|
+
|
30
|
+
Thread.new do
|
31
|
+
sleep 0.01
|
32
|
+
puts Term::ANSIColor.blue("\n[Rack::Lineprof] #{'=' * 63}") + "\n\n" +
|
33
|
+
format_profile(profile) + "\n"
|
34
|
+
end
|
35
|
+
|
36
|
+
response
|
37
|
+
end
|
38
|
+
|
39
|
+
def format_profile profile
|
40
|
+
sources = profile.map do |filename, samples|
|
41
|
+
Source.new filename, samples, options
|
42
|
+
end
|
43
|
+
|
44
|
+
sources.map(&:format).compact.join "\n"
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Rack
|
2
|
+
class Lineprof
|
3
|
+
class Sample < Struct.new :line, :ms, :code, :level
|
4
|
+
|
5
|
+
def format colorize = true
|
6
|
+
formatted = if level == CONTEXT
|
7
|
+
sprintf " | % 3i %s", line, code
|
8
|
+
else
|
9
|
+
sprintf "% 8.1fms | % 3i %s", ms, line, code
|
10
|
+
end
|
11
|
+
|
12
|
+
return formatted unless colorize
|
13
|
+
|
14
|
+
case level
|
15
|
+
when CRITICAL
|
16
|
+
color.red formatted
|
17
|
+
when WARNING
|
18
|
+
color.yellow formatted
|
19
|
+
when NOMINAL
|
20
|
+
color.white formatted
|
21
|
+
else # CONTEXT
|
22
|
+
color.intense_black formatted
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def color
|
29
|
+
Term::ANSIColor
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
module Rack
|
2
|
+
class Lineprof
|
3
|
+
class Source
|
4
|
+
|
5
|
+
attr_reader :file_name, :raw_samples, :options
|
6
|
+
|
7
|
+
def initialize file_name, raw_samples, options = {}
|
8
|
+
@file_name, @raw_samples, @options = file_name, raw_samples, options
|
9
|
+
end
|
10
|
+
|
11
|
+
def format colorize = true
|
12
|
+
return nil if samples.empty?
|
13
|
+
|
14
|
+
formatted = file_name.sub(Dir.pwd + '/', '') + "\n"
|
15
|
+
|
16
|
+
prev_line = samples.first.line - 1
|
17
|
+
samples.each do |sample|
|
18
|
+
if sample.line != prev_line + 1
|
19
|
+
formatted << color.intense_black(' ' * 10 + '.' * 7) + "\n"
|
20
|
+
end
|
21
|
+
prev_line = sample.line
|
22
|
+
|
23
|
+
formatted << sample.format
|
24
|
+
end
|
25
|
+
|
26
|
+
formatted
|
27
|
+
end
|
28
|
+
|
29
|
+
def samples
|
30
|
+
@samples ||= begin
|
31
|
+
parsed = []
|
32
|
+
|
33
|
+
raw_samples.each_with_index do |sample, line|
|
34
|
+
next if line == 0 # drop file info
|
35
|
+
|
36
|
+
ms = sample[0] / 1000.0
|
37
|
+
|
38
|
+
clocked = ms >= 0.2 # info
|
39
|
+
near_clocked = (line-context..line+context).any? do |near|
|
40
|
+
near = [1, near].max
|
41
|
+
next unless raw_samples[near]
|
42
|
+
(raw_samples[near][0] / 1000.0) >= 0.2 # info
|
43
|
+
end
|
44
|
+
|
45
|
+
next unless clocked or near_clocked
|
46
|
+
|
47
|
+
threshold = thresholds.detect { |boundary, _| ms > boundary }
|
48
|
+
level = threshold ? threshold.last : CONTEXT
|
49
|
+
|
50
|
+
next unless code = source_code[line - 1]
|
51
|
+
parsed << Sample.new(line, ms, code, level)
|
52
|
+
end
|
53
|
+
|
54
|
+
parsed
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def source_code
|
59
|
+
@source_code ||= ::File.open(file_name, 'r').to_a
|
60
|
+
end
|
61
|
+
|
62
|
+
private
|
63
|
+
|
64
|
+
def color
|
65
|
+
Term::ANSIColor
|
66
|
+
end
|
67
|
+
|
68
|
+
def context
|
69
|
+
options.fetch :context, 2
|
70
|
+
end
|
71
|
+
|
72
|
+
def thresholds
|
73
|
+
@thresholds ||= {
|
74
|
+
CRITICAL => 50,
|
75
|
+
WARNING => 5,
|
76
|
+
NOMINAL => 0.2
|
77
|
+
}.merge(options.fetch :thresholds, {}).invert
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
metadata
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rack-lineprof
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Evan Owen
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-04-19 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rack
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rblineprof
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 0.3.1
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ~>
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 0.3.1
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: term-ansicolor
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
description: Rack middleware for rblineprof (github.com/tmm1/rblineprof)
|
56
|
+
email:
|
57
|
+
- kainosnoema@gmail.com
|
58
|
+
executables: []
|
59
|
+
extensions: []
|
60
|
+
extra_rdoc_files: []
|
61
|
+
files:
|
62
|
+
- lib/rack/lineprof/sample.rb
|
63
|
+
- lib/rack/lineprof/source.rb
|
64
|
+
- lib/rack/lineprof.rb
|
65
|
+
- lib/rack-lineprof.rb
|
66
|
+
homepage: https://github.com/kainosnoema/rack-lineprof
|
67
|
+
licenses:
|
68
|
+
- MIT
|
69
|
+
metadata: {}
|
70
|
+
post_install_message:
|
71
|
+
rdoc_options: []
|
72
|
+
require_paths:
|
73
|
+
- lib
|
74
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
75
|
+
requirements:
|
76
|
+
- - '>='
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: '0'
|
79
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - '>='
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '0'
|
84
|
+
requirements: []
|
85
|
+
rubyforge_project:
|
86
|
+
rubygems_version: 2.0.0
|
87
|
+
signing_key:
|
88
|
+
specification_version: 4
|
89
|
+
summary: Makes line-by-line source code profiling easy.
|
90
|
+
test_files: []
|