sigdump 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/ChangeLog +5 -0
- data/README.md +69 -3
- data/lib/sigdump.rb +17 -4
- metadata +2 -2
data/ChangeLog
CHANGED
data/README.md
CHANGED
@@ -1,16 +1,18 @@
|
|
1
1
|
# sigdump
|
2
2
|
|
3
|
-
Server applications (like Rails app) cause performance problems, deadlock or memory swapping from time to time. But it's painful to reproduce such kind of problems. If we can get information from a running process without restarting it,
|
3
|
+
Server applications (like Rails app) cause performance problems, deadlock or memory swapping from time to time. But it's painful to reproduce such kind of problems. If we can get information from a running process without restarting it, it's really helpful.
|
4
4
|
|
5
5
|
`sigdump` gem installs a signal handler which dumps backtrace of running threads and number of allocated objects per class.
|
6
6
|
|
7
|
-
|
7
|
+
If GC profiler is enabled (`GC::Profiler.enable` is called), it also dumps GC statistics.
|
8
|
+
|
9
|
+
## Install
|
8
10
|
|
9
11
|
Just install one gem `sigdump` and require `sigdump/setup`:
|
10
12
|
|
11
13
|
gem 'sigdump', :require => 'sigdump/setup'
|
12
14
|
|
13
|
-
|
15
|
+
## Usage
|
14
16
|
|
15
17
|
Send `SIGCONT` signal to dump backtrace and heap status to `/tmp/sigdump-<pid>.log`:
|
16
18
|
|
@@ -20,3 +22,67 @@ Set `SIGDUMP_SIGNAL` environment variable to change the signal (default: SIGCONT
|
|
20
22
|
|
21
23
|
Set `SIGDUMP_PATH` environment variable to change the output path (default: /tmp/sigdump-\<pid\>.log). You can set "-" here to dump to STDOUT, "+" to dump to STDERR.
|
22
24
|
|
25
|
+
## Sample outout
|
26
|
+
|
27
|
+
$ cat /tmp/sigdump-9218.log
|
28
|
+
Sigdump at 2013-04-24 16:57:12 +0000 process 9218 (unicorn worker[3] -E staging -c /etc/unicorn/staging.rb -E staging)
|
29
|
+
Thread #<Thread:0x00000001424518> status=run priority=0
|
30
|
+
/srv/staging/current/vendor/bundle/ruby/1.9.1/gems/sigdump-0.1.0/lib/sigdump.rb:32:in `dump_backtrace'
|
31
|
+
/srv/staging/current/vendor/bundle/ruby/1.9.1/gems/sigdump-0.1.0/lib/sigdump.rb:19:in `block in dump_all_thread_backtrace'
|
32
|
+
/srv/staging/current/vendor/bundle/ruby/1.9.1/gems/sigdump-0.1.0/lib/sigdump.rb:18:in `each'
|
33
|
+
/srv/staging/current/vendor/bundle/ruby/1.9.1/gems/sigdump-0.1.0/lib/sigdump.rb:18:in `dump_all_thread_backtrace'
|
34
|
+
/srv/staging/current/vendor/bundle/ruby/1.9.1/gems/sigdump-0.1.0/lib/sigdump.rb:9:in `block (2 levels) in install_thread_dump_handler'
|
35
|
+
/srv/staging/current/vendor/bundle/ruby/1.9.1/gems/sigdump-0.1.0/lib/sigdump.rb:91:in `open'
|
36
|
+
/srv/staging/current/vendor/bundle/ruby/1.9.1/gems/sigdump-0.1.0/lib/sigdump.rb:91:in `_open_dump_path'
|
37
|
+
/srv/staging/current/vendor/bundle/ruby/1.9.1/gems/sigdump-0.1.0/lib/sigdump.rb:7:in `block in install_thread_dump_handler'
|
38
|
+
/srv/staging/current/vendor/bundle/ruby/1.9.1/gems/unicorn-4.3.1/lib/unicorn/http_server.rb:626:in `call'
|
39
|
+
/srv/staging/current/vendor/bundle/ruby/1.9.1/gems/unicorn-4.3.1/lib/unicorn/http_server.rb:626:in `select'
|
40
|
+
/srv/staging/current/vendor/bundle/ruby/1.9.1/gems/unicorn-4.3.1/lib/unicorn/http_server.rb:626:in `worker_loop'
|
41
|
+
/srv/staging/current/vendor/bundle/ruby/1.9.1/gems/unicorn-4.3.1/lib/unicorn/http_server.rb:487:in `spawn_missing_workers'
|
42
|
+
/srv/staging/current/vendor/bundle/ruby/1.9.1/gems/unicorn-4.3.1/lib/unicorn/http_server.rb:137:in `start'
|
43
|
+
/srv/staging/current/vendor/bundle/ruby/1.9.1/gems/unicorn-4.3.1/bin/unicorn:121:in `<top (required)>'
|
44
|
+
/srv/staging/current/vendor/bundle/ruby/1.9.1/bin/unicorn:23:in `load'
|
45
|
+
/srv/staging/current/vendor/bundle/ruby/1.9.1/bin/unicorn:23:in `<main>'
|
46
|
+
Built-in objects:
|
47
|
+
367,492: TOTAL
|
48
|
+
208,193: T_STRING
|
49
|
+
61,817: T_ARRAY
|
50
|
+
37,343: T_DATA
|
51
|
+
28,293: T_NODE
|
52
|
+
10,678: T_OBJECT
|
53
|
+
6,385: T_HASH
|
54
|
+
5,957: T_CLASS
|
55
|
+
2,300: T_ICLASS
|
56
|
+
2,184: T_REGEXP
|
57
|
+
1,547: T_MODULE
|
58
|
+
900: T_FLOAT
|
59
|
+
677: T_STRUCT
|
60
|
+
497: T_BIGNUM
|
61
|
+
432: T_MATCH
|
62
|
+
251: T_RATIONAL
|
63
|
+
29: T_FILE
|
64
|
+
8: FREE
|
65
|
+
1: T_COMPLEX
|
66
|
+
All objects:
|
67
|
+
207,335: String
|
68
|
+
32,987: Array
|
69
|
+
28,665: RubyVM::InstructionSequence
|
70
|
+
5,863: Hash
|
71
|
+
3,759: RubyVM::Env
|
72
|
+
3,680: Proc
|
73
|
+
2,338: Class
|
74
|
+
2,184: Regexp
|
75
|
+
1,632: MIME::Type
|
76
|
+
1,547: Module
|
77
|
+
1,040: Gem::Version
|
78
|
+
982: Gem::Requirement
|
79
|
+
945: Float
|
80
|
+
920: Journey::Nodes::Cat
|
81
|
+
804: Time
|
82
|
+
660: Gem::Dependency
|
83
|
+
497: Bignum
|
84
|
+
...
|
85
|
+
String 7,556,137 bytes
|
86
|
+
Array 821 elements
|
87
|
+
Hash 90 pairs
|
88
|
+
|
data/lib/sigdump.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
module Sigdump
|
2
|
-
VERSION = "0.1.
|
2
|
+
VERSION = "0.1.1"
|
3
3
|
|
4
4
|
def self.install_thread_dump_handler(signal, path=nil)
|
5
5
|
Kernel.trap(signal) do
|
@@ -8,6 +8,7 @@ module Sigdump
|
|
8
8
|
io.write "Sigdump at #{Time.now} process #{Process.pid} (#{$0})\n"
|
9
9
|
dump_all_thread_backtrace(io)
|
10
10
|
dump_object_count(io)
|
11
|
+
dump_gc_profiler_result(io)
|
11
12
|
end
|
12
13
|
rescue
|
13
14
|
end
|
@@ -29,10 +30,8 @@ module Sigdump
|
|
29
30
|
status = "error"
|
30
31
|
end
|
31
32
|
|
32
|
-
backtrace = thread.backtrace
|
33
|
-
|
34
33
|
io.write " Thread #{thread} status=#{status} priority=#{thread.priority}\n"
|
35
|
-
backtrace.each {|bt|
|
34
|
+
thread.backtrace.each {|bt|
|
36
35
|
io.write " #{bt}\n"
|
37
36
|
}
|
38
37
|
|
@@ -75,6 +74,18 @@ module Sigdump
|
|
75
74
|
nil
|
76
75
|
end
|
77
76
|
|
77
|
+
def self.dump_gc_profiler_result(io)
|
78
|
+
return unless defined?(GC::Profiler) && GC::Profiler.enabled?
|
79
|
+
|
80
|
+
io.write " GC profiling result:\n"
|
81
|
+
io.write " Total garbage collection time: %f\n" % GC::Profiler.total_time
|
82
|
+
io.write GC::Profiler.result
|
83
|
+
GC::Profiler.clear
|
84
|
+
|
85
|
+
io.flush
|
86
|
+
nil
|
87
|
+
end
|
88
|
+
|
78
89
|
def self._fn(num)
|
79
90
|
s = num.to_s
|
80
91
|
if formatted = s.gsub!(/(\d)(?=(?:\d{3})+(?!\d))/, "\\1,")
|
@@ -83,6 +94,7 @@ module Sigdump
|
|
83
94
|
s
|
84
95
|
end
|
85
96
|
end
|
97
|
+
private_class_method :_fn
|
86
98
|
|
87
99
|
def self._open_dump_path(path, &block)
|
88
100
|
case path
|
@@ -99,4 +111,5 @@ module Sigdump
|
|
99
111
|
File.open(path, "a", &block)
|
100
112
|
end
|
101
113
|
end
|
114
|
+
private_class_method :_open_dump_path
|
102
115
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sigdump
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-04-
|
12
|
+
date: 2013-04-24 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|