Josh Bodah
Josh Bodah

Reputation: 1243

Prefixing console ouput of system calls from Ruby

I'd like to create a Ruby script that prefixes the console output. For example:

I want to implement an interface like this:

puts 'MainLogger: Saying hello'
prefix_output_with('MainLogger') do
  system 'echo hello'
end

So this shows up in the console:

MainLogger: Saying hello
MainLogger: hello

What would be a good approach to prefix all of the syscall output to have some logger?

Note: I don't care if we echo what the system call is or not

Upvotes: 0

Views: 63

Answers (1)

Max
Max

Reputation: 22365

The important point here is that there's no way to know if system will actually produce output. I'm assuming you don't want a blank MainLogger: whenever a system call doesn't print anything, so you'll need to do the prefixes in the 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

This implementation is pretty fragile, though. It doesn't handle all the different ways you can call system, and prefixes containing special shell characters could cause an error.

Upvotes: 1

Related Questions