sigdump 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (4) hide show
  1. data/ChangeLog +5 -0
  2. data/README.md +69 -3
  3. data/lib/sigdump.rb +17 -4
  4. metadata +2 -2
data/ChangeLog CHANGED
@@ -1,4 +1,9 @@
1
1
 
2
+ 2013-04-24 version 0.1.1:
3
+
4
+ * Signal handler dumps GC statistics as well if GC::Profiler is enabled
5
+ (by @mrkn / Kenta Murata)
6
+
2
7
  2013-04-23 version 0.1.0:
3
8
 
4
9
  * First release
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, and it's really helpful.
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
- # Install
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
- # Usage
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
+
@@ -1,5 +1,5 @@
1
1
  module Sigdump
2
- VERSION = "0.1.0"
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.0
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-23 00:00:00.000000000 Z
12
+ date: 2013-04-24 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake