Module: Dike
- Defined in:
- lib/dike.rb,
lib/dike.rb
Defined Under Namespace
Classes: LogFactory
Constant Summary collapse
- Objects =
Hash.new
- Ignore =
Hash.new
Class Method Summary collapse
- .finger(options = {}) ⇒ Object
- .ignore(*list) ⇒ Object
- .ignore_finalizer(object_id) ⇒ Object
- .ignored(&block) ⇒ Object
- .logfactory=(value) ⇒ Object
- .logging(&block) ⇒ Object
- .mark_birth(object, stacktrace) ⇒ Object
- .mark_birth_finalizer(object_id) ⇒ Object
- .on(which = :rails) ⇒ Object
Class Method Details
.finger(options = {}) ⇒ Object
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 |
# File 'lib/dike.rb', line 87 def finger = {} Thread.critical = true begin 42.times{ GC.start } count, code = :remembered Ignore.transaction do count = Hash.new 0 ignore count code = Hash.new do |h,k| sh = Hash.new 0 ignore sh h[k] = sh end ignore code ObjectSpace.each_object(filter) do |object| m = Object::Methods["object_id"].bind object ignore m object_id = m.call next if Ignore[object_id] m = Object::Methods["class"].bind object ignore m klass = m.call defined_at = Objects[object_id] count[klass] += 1 code[klass][defined_at] += 1 end end GC.start worst_klasses = count.to_a.sort_by{|pair| pair.last}.last(threshold.class).reverse count.clear count = nil =begin report = [] =end total = 0 logging do |log| log.puts "---" worst_klasses.each do |klass, count| worst_code = code[klass].to_a.sort_by{|pair| pair.last}.last(threshold.code).reverse name = Class::Methods["name"].bind(klass).call.to_s name = Class::Methods["inspect"].bind(klass).call.to_s if name.empty? name = 'UNKNOWN' if name.empty? worst_code.each do |stacktrace, count| next unless count > threshold.object =begin TODO - figure out why the hell yaml leaks so bad! report << OrderedHash[ 'class', name, 'count', count, 'stacktrace', (stacktrace ? stacktrace.clone : []), ] =end trace = stacktrace ? stacktrace.clone : [] ### roll our own because yaml leaks! log.puts "- class: #{ name }" log.puts " count: #{ count }" if trace.empty? log.puts " trace: []" else log.puts " trace:" trace.each do |line| log.puts " - #{ line }" end end end worst_code.clear worst_code = nil total += count end end =begin logging do |log| log.puts report.to_yaml log.flush end report.clear report = nil GC.start =end worst_klasses.clear worst_klasses = nil code.clear code = nil GC.start total ensure Thread.critical = false end end |
.ignore(*list) ⇒ Object
59 60 61 62 63 64 65 |
# File 'lib/dike.rb', line 59 def ignore *list list.flatten.each do |object| object_id = ::Object::Methods["object_id"].bind(object).call Ignore[object_id] = true #ObjectSpace.define_finalizer object, &ignore_finalizer(object_id) end end |
.ignore_finalizer(object_id) ⇒ Object
73 74 75 |
# File 'lib/dike.rb', line 73 def ignore_finalizer object_id lambda{ Ignore.delete object_id } end |
.ignored(&block) ⇒ Object
67 68 69 70 71 |
# File 'lib/dike.rb', line 67 def ignored &block object = block.call ignore object object end |
.logfactory=(value) ⇒ Object
82 83 84 85 |
# File 'lib/dike.rb', line 82 def logfactory= value @logfactory = LogFactory === value ? value : LogFactory.new(value) end |
.logging(&block) ⇒ Object
205 206 207 |
# File 'lib/dike.rb', line 205 def logging &block logfactory ? logfactory.next(&block) : block.call(log) end |
.mark_birth(object, stacktrace) ⇒ Object
31 32 33 34 35 36 |
# File 'lib/dike.rb', line 31 def mark_birth object, stacktrace object_id = Object::Methods["object_id"].bind(object).call return if Objects[object_id] Objects[object_id] = stacktrace ObjectSpace.define_finalizer object, &mark_birth_finalizer(object_id) end |
.mark_birth_finalizer(object_id) ⇒ Object
38 39 40 |
# File 'lib/dike.rb', line 38 def mark_birth_finalizer object_id lambda{ Objects.delete object_id } end |
.on(which = :rails) ⇒ Object
262 263 264 265 266 267 268 269 270 271 272 273 274 |
# File 'lib/dike.rb', line 262 def self.on which = :rails case which.to_s when %r/^rails$/i Dike.logfactory File.join(RAILS_ROOT, "log", "dike") ActionController::Base.module_eval do after_filter do |controller| Dike.finger true end end end end |