为来自 Ruby 的系统调用的控制台输出添加前缀
Prefixing console ouput of system calls from Ruby
我想创建一个 Ruby 脚本作为控制台输出的前缀。例如:
我想实现这样的接口:
puts 'MainLogger: Saying hello'
prefix_output_with('MainLogger') do
system 'echo hello'
end
所以这显示在控制台中:
MainLogger: Saying hello
MainLogger: hello
在所有系统调用输出前加上一些记录器的好方法是什么?
注意:我不关心我们是否回显系统调用是什么
这里的重点是没有办法知道 system
是否真的会产生输出。我假设您不希望在系统调用不打印任何内容时出现空白 MainLogger:
,因此您需要在 shell:
中添加前缀
def prefix_system_calls pre
sys = Kernel.instance_method(:system)
# redefine to add prefix
Kernel.send(:define_method, :system) do |cmd|
sys.bind(self)["#{cmd} | sed -e 's/^/#{pre}: /'"]
end
yield
# redefine to call original method
Kernel.send(:define_method, :system) do |*args|
sys.bind(self)[*args]
end
end
system "echo foo"
prefix_system_calls("prefix") do
system "echo bar"
end
system "echo baz"
# foo
# prefix: bar
# baz
不过,此实现非常脆弱。它不处理 all the different ways you can call system
,并且包含特殊 shell 字符的前缀可能会导致错误。
我想创建一个 Ruby 脚本作为控制台输出的前缀。例如:
我想实现这样的接口:
puts 'MainLogger: Saying hello'
prefix_output_with('MainLogger') do
system 'echo hello'
end
所以这显示在控制台中:
MainLogger: Saying hello
MainLogger: hello
在所有系统调用输出前加上一些记录器的好方法是什么?
注意:我不关心我们是否回显系统调用是什么
这里的重点是没有办法知道 system
是否真的会产生输出。我假设您不希望在系统调用不打印任何内容时出现空白 MainLogger:
,因此您需要在 shell:
def prefix_system_calls pre
sys = Kernel.instance_method(:system)
# redefine to add prefix
Kernel.send(:define_method, :system) do |cmd|
sys.bind(self)["#{cmd} | sed -e 's/^/#{pre}: /'"]
end
yield
# redefine to call original method
Kernel.send(:define_method, :system) do |*args|
sys.bind(self)[*args]
end
end
system "echo foo"
prefix_system_calls("prefix") do
system "echo bar"
end
system "echo baz"
# foo
# prefix: bar
# baz
不过,此实现非常脆弱。它不处理 all the different ways you can call system
,并且包含特殊 shell 字符的前缀可能会导致错误。