PagerDuty / blender

A modular orchestration engine
https://github.com/PagerDuty/blender
Other
183 stars 8 forks source link

SSH-Driver: get stdout/stderr - Output #44

Closed jsiegele closed 9 years ago

jsiegele commented 9 years ago

Hi, is there a way to get the stdout/stderr Output of the ssh-Job? Right now i just found the debug Option for the Tool itself. (json-File with "log_level": "debug") But i didnt found a way to redirect the stdout/stderr of the SSH-Job.

Thanks for your help.

MfG Johann

robottaway commented 9 years ago

Hola Johann,

The short answer is you can use StringIO, passing it as the stdout,stderr or both via options. If you require more help could you please link me to the code you are using if possible, thanks!

jkleinlercher commented 9 years ago

Hi,

I work with Johann on the same code. Our chef.rb just for a simple test looks like this

require 'blender/chef' config(:chef, config_file: '/etc/chef/client.rb') config(:ssh, stdout: File.open('blendstdout.log','w')) members(search(:chef, ':_')) ssh_task 'while true; do date ; sleep 3; done'

stdout is now written to blend_stdout.log . Is this the right configuration? However 2 questions remain:

1) How do we add the stderr configuration? 2) We see that stdout is only written at the end of the job. Is there a way to stream stdout of the job, so that we see the output of the job during the job run?

Thanks for your help!

ranjib commented 9 years ago

@jkleinlercher you can pass stderr option, similar to stdout to capture stderr. to store it in file, as well as stream it in console, you have to do some IO multiplexing. here is an example. You can drop this file in lib/ subdirectory, and directly require it in your blender script. then create a multiio object and do

multio << FIle.open('path/to/file', 'w')
multio << STDOUT
config(:ssh, stdout: multio)
ranjib commented 9 years ago

@jkleinlercher @jsiegele i just tried the multio class, it did not work. In-stead i used the IO::Tee style of multiplexing, which worked well. Here is a full working example: in lib/io_tee.rb

require 'stringio'
require 'thread'

module IO::Tee                                                                                                             
  def tee *a                                                                                                               
    a.reject! do |i|                                                                                                       
      i == self                                                                                                            
    end                                                                                                                    
    class << self                                                                                                          
      self
    end.class_eval do
      define_method :write do |str|
        Thread.exclusive do
          super(str)
          a.each do |i|
            i.write str
          end
        end
      end
    end
  end
end
class IO
  include IO::Tee
end
class StringIO
  include IO::Tee
end

and in the blender script: foo.rb

require 'io_tee'
file = File.open('out.log', 'w')
file.tee $stdout
members(['example.domain.com'])
config(:ssh, stdout: file)
ssh_task 'lsb_release -r'

cheers

jkleinlercher commented 9 years ago

Hi Ranjib,

do you also have a nice way to write a seperate logfile for each ssh host, instead of one out.log for all the hosts?

Thanks!

best regards, Johannes

ranjib commented 9 years ago

@jkleinlercher not yet. but this what I am planning to add for next minor release. it will be very helpful if you can raise an issue with your expected usage, so that we can start a discussion :-)