RUBY中保存异常现场
RUBY中保存异常现场无法接触到服务器,但有些问题需要异常的数据,虽然可以在抛出异常时把数据给手动打印到日记,感觉太麻烦了
记得有看豆瓣的架构时,有提到他们在发生异常时,会把当时的所有变量都打印到日记里,方便调试.
在RUBY中实现这个也不难,稍微有点难的是本地变量的保存
实例变量已经在RAILS已经有现在的实现了
引用
http://apidock.com/rails/Object/instance_values
Ruby代码1.# File activesupport/lib/active_support/core_ext/object/instance_variables.rb, line 12
2.def instance_values #:nodoc:
3. Hash, instance_variable_get(name)] }]
4.end
# File activesupport/lib/active_support/core_ext/object/instance_variables.rb, line 12
def instance_values #:nodoc:
Hash, instance_variable_get(name)] }]
end但没有找到local_values这个方法,好吧,我们自己来实现一个
Ruby代码1.def local_values(context, black_list = [])
2.black_list.concat(%w)
3.context.eval <<-EOS
4. local_value_hashs = {}
5. local_variables.each do |var_name|
6. next if [#{black_list.map{|b|"'#{b}'"}.join ','}].include? var_name
7. local_value_hashs = eval(var_name)
8. end
9. local_value_hashs
10.EOS
11.end
def local_values(context, black_list = [])
black_list.concat(%w)
context.eval <<-EOS
local_value_hashs = {}
local_variables.each do |var_name|
next if [#{black_list.map{|b|"'#{b}'"}.join ','}].include? var_name
local_value_hashs = eval(var_name)
end
local_value_hashs
EOSend
这个方法默认只需要一个参数,context参数在发生异常的rescue语句里调用binding方法,black_list参数是一个数组,当你不需要把某些本地变量给打印出来的,把它的名字写到这个数组就行了
小demo
Ruby代码1.require 'pp'
2.class Kitty
3.def hello
4. str = "hello kitty"
5. raise 'test kitty'
6.rescue
7. pp local_values(binding)
8.end
9.
10.def local_values(context, black_list = [])
11. black_list.concat(%w)
12. context.eval <<-EOS
13. local_value_hashs = {}
14. local_variables.each do |var_name|
15. next if [#{black_list.map{|b|"'#{b}'"}.join ','}].include? var_name
16. local_value_hashs = eval(var_name)
17. end
18. local_value_hashs
19. EOS
20.end
21.end
22.
23.Kitty.new.hello
require 'pp'
class Kitty
def hello
str = "hello kitty"
raise 'test kitty'
rescue
pp local_values(binding)
end
def local_values(context, black_list = [])
black_list.concat(%w)
context.eval <<-EOS
local_value_hashs = {}
local_variables.each do |var_name|
next if [#{black_list.map{|b|"'#{b}'"}.join ','}].include? var_name
local_value_hashs = eval(var_name)
end
local_value_hashs
EOS
end
end
Kitty.new.hello
输出结果
引用
{"str"=>"hello kitty"}思路
•通过binding方法获取异常发生的上下文
•调用上下文的eval方法,在eval里通过ruby自带的local_variables,获取所有本地变量的名称
•通过eval获取本地变量的值,把它存起来,返回结果 好好好,很好啊。
页:
[1]