Module: GCHacks

Extended by:
GCHacks
Included in:
GCHacks
Defined in:
lib/gc_hacks.rb,
lib/gc_hacks/railtie.rb,
lib/gc_hacks/version.rb

Defined Under Namespace

Classes: Railtie

Constant Summary collapse

VERSION =
"0.0.3"

Instance Method Summary collapse

Instance Method Details

#can_dump?Boolean

Returns:

  • (Boolean)


85
86
87
# File 'lib/gc_hacks.rb', line 85

def can_dump?
  GC.respond_to?(:dump_file_and_line_info)
end

#can_trace?Boolean

Returns:

  • (Boolean)


81
82
83
# File 'lib/gc_hacks.rb', line 81

def can_trace?
  GC.respond_to?(:log_file)
end

#check_and_run_commandsObject



54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/gc_hacks.rb', line 54

def check_and_run_commands
  read_command_file.each_line do |cmd|
    # puts "received cmd #{cmd}"
    case c = cmd.chomp
    when 'HEAPDUMP'   then heap_dump
    when 'STARTTRACE' then start_trace
    when 'STOPTRACE'  then stop_trace
    else
      logger.info "unknown gc command: '#{c}'"
    end
  end
ensure
  remove_command_file
end

#cmd_fileObject



69
70
71
# File 'lib/gc_hacks.rb', line 69

def cmd_file
  "#{tmp_dir}/gc_command.txt"
end

#cwd_is_a_rails_project?Boolean

Returns:

  • (Boolean)


40
41
42
# File 'lib/gc_hacks.rb', line 40

def cwd_is_a_rails_project?
  File.exist?("config/environment.rb") && File.directory?("tmp") && File.directory?("log")
end

#find_rails_rootObject



29
30
31
32
33
34
35
36
37
38
# File 'lib/gc_hacks.rb', line 29

def find_rails_root
  while !cwd_is_a_rails_project?
    if FileUtils.pwd == "/"
      $stderr.puts "could not determine rails project root. please cd into your rails project"
      exit 1
    end
    FileUtils.cd ".."
  end
  FileUtils.pwd
end

#heap_dumpObject



124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# File 'lib/gc_hacks.rb', line 124

def heap_dump
  unless can_dump?
    logger.info "cannot dump heap. GC.dump_file_and_line_info is undefined"
    return
  end
  @heap_dump_count ||= 0
  filename = "#{tmp_dir}/heap.#{Process.pid}.#{@heap_dump_count}.dump"
  msg = "** Dumping heap ..."
  $stderr.puts msg; logger.info msg
  GC.start;GC.start # two calls to get rid of finalizer created garbage
  GC.dump_file_and_line_info(filename, true)
  msg = "** Run 'railsbench analyze_heap_dump #{filename}' to analyze."
  $stderr.puts msg; logger.info msg
  @heap_dump_count += 1
end

#install_signal_handlersObject



44
45
46
47
# File 'lib/gc_hacks.rb', line 44

def install_signal_handlers
  # WINCH is the only signal we can receive without mongrel/passenger side effects
  trap("WINCH"){ check_and_run_commands }
end

#log_dirObject



89
90
91
# File 'lib/gc_hacks.rb', line 89

def log_dir
  @log_dir ||= File.expand_path("#{root}/log")
end

#log_dir=(dir) ⇒ Object



93
94
95
# File 'lib/gc_hacks.rb', line 93

def log_dir=(dir)
  @log_dir = File.expand_path(dir)
end

#loggerObject



7
8
9
10
11
12
13
14
15
16
# File 'lib/gc_hacks.rb', line 7

def logger
  @logger ||=
    if defined?(Rails)
      Rails.logger
    elsif defined?(RAILS_DEFAULT_LOGGER)
      RAILS_DEFAULT_LOGGER
    else
      Logger.new($stdout)
    end
end

#read_command_fileObject



73
74
75
# File 'lib/gc_hacks.rb', line 73

def read_command_file
  File.exist?(cmd_file) ? File.read(cmd_file) : ""
end

#remove_command_fileObject



77
78
79
# File 'lib/gc_hacks.rb', line 77

def remove_command_file
  File.exist?(cmd_file) && File.unlink(cmd_file)
end

#rootObject



18
19
20
21
22
23
24
25
26
27
# File 'lib/gc_hacks.rb', line 18

def root
  @root ||=
    if defined?(Rails) && Rails.respond_to?(:application)
      Rails.application.root.to_s
    elsif defined?(RAILS_ROOT)
      RAILS_ROOT
    else
      find_rails_root
    end
end

#send_command(cmd, pid) ⇒ Object



49
50
51
52
# File 'lib/gc_hacks.rb', line 49

def send_command(cmd, pid)
  File.open(cmd_file, "w"){|f| f.puts cmd}
  Process.kill("WINCH", pid)
end

#start_traceObject



105
106
107
108
109
110
111
112
113
# File 'lib/gc_hacks.rb', line 105

def start_trace
  unless can_trace?
    logger.info "cannot start GC trace. GC.enable_trace is undefined"
    return
  end
  GC.log_file "#{log_dir}/gctrace-#{Process.pid}.log" unless GC.log_file
  GC.enable_trace
  logger.info "GC-tracing: enabled"
end

#stop_traceObject



115
116
117
118
119
120
121
122
# File 'lib/gc_hacks.rb', line 115

def stop_trace
  unless can_trace?
    logger.info "cannot stop GC trace. GC.disable_trace is undefined"
    return
  end
  GC.disable_trace
  logger.info "GC-tracing: disabled"
end

#tmp_dirObject



97
98
99
# File 'lib/gc_hacks.rb', line 97

def tmp_dir
  @tmp_dir ||= File.expand_path("#{root}/tmp")
end

#tmp_dir=(dir) ⇒ Object



101
102
103
# File 'lib/gc_hacks.rb', line 101

def tmp_dir=(dir)
  @tmp_dir = File.expand_path(dir)
end