Stream Console Output Through Http (With Ruby)

Stream console output through HTTP (with Ruby)

If you're on a synchronous server (i.e. Mongrel, Unicorn, not Thin), you can just return an IO object:

require 'sinatra'

get '/log' do
content_type :txt
IO.popen('tail -f some.log')
end

If that doesn't work (if you're on Thin, for instance), you can use the new streaming API:

require 'sinatra'

get '/log' do
content_type :txt
IO.popen('tail -f some.log') do |io|
stream do |out|
io.each { |s| out << s }
end
end
end

You can also use the bcat gem, which will colorize your output, if it contains ANSI color codes:

require 'sinatra'
require 'bcat'

get '/log' do
command = %[tail -f some.log]
bcat = Bcat.new(command, :command => true)
bcat.to_app.call(env)
end

Note: For infinitely running process you'll have to take care of killing the process yourself if someone closes the connection. With the first solution some servers might take care of that for you.

Streaming data from Sinatra/Rack application

Neither Webrick nor Thin support streaming that way. You could try Mongrel or Unicorn. If you want to use Thin or Rainbows!, you have to hook into the event loop in order to achieve streaming:

require 'sinatra'

class Stream
include EventMachine::Deferrable
def initialize
@counter = 0
end

def each(&block)
if @counter > 10
succeed
else
EM.next_tick do
yield counter
each(&block)
end
end
end
end

get '/' do
Stream.new
end

I recently wrote a EventSource implementation that way:

require 'sinatra'

class EventStream
include EventMachine::Deferrable
def each
count = 0
timer = EventMachine::PeriodicTimer.new(1) do
yield "data: #{count += 1}\n\n"
end
errback { timer.cancel }
end
end

get '/' do
EventMachine.next_tick do
request.env['async.callback'].call [
200, {'Content-Type' => 'text/event-stream'},
EventStream.new ]
end
[-1, {}, []]
end

If you want to use Webrick for Streaming: here is a patch.

How can I have console output display to stdout AND store it in a variable?

This is a solution with IO.popen:

require 'stringio'

output = StringIO.new

IO.popen("ls") do |pipe|
pipe.each do |line|
output.puts line
puts line
end
end

puts output.string # => Outputs the contents of `output` as a string

How do I view the HTTP response to an ActiveResource request?

It's easy. Just look at the response that comes back. :)

Two options:

  • You have the source file on your computer. Edit it. Put a puts response.inspect at the appropriate place. Remember to remove it.
  • Ruby has open classes. Find the right method and redefine it to do exactly what you want, or use aliases and call chaining to do this. There's probably a method that returns the response -- grab it, print it, and then return it.

Here's a silly example of the latter option.

# Somewhere buried in ActiveResource:
class Network
def get
return get_request
end

def get_request
"I'm a request!"
end
end

# Somewhere in your source files:
class Network
def print_request
request = old_get_request
puts request
request
end
alias :old_get_request :get_request
alias :get_request :print_request
end

Imagine the first class definition is in the ActiveRecord source files. The second class definition is in your application somewhere.

$ irb -r openclasses.rb 
>> Network.new.get
I'm a request!
=> "I'm a request!"

You can see that it prints it and then returns it. Neat, huh?

(And although my simple example doesn't use it since it isn't using Rails, check out alias_method_chain to combine your alias calls.)

What is Java using to output in console, and how can I capture it in ruby?

Java is using STDERR to print its version information. You can capture that easily by routing STDERR to STDOUT's stream, and capturing both.

asdf = `java -version 2>&1`
puts asdf

will output:

java version "1.6.0_33"
Java(TM) SE Runtime Environment (build 1.6.0_33-b03-424-10M3720)
Java HotSpot(TM) 64-Bit Server VM (build 20.8-b03-424, mixed mode)

This is a very common technique when working at the command-line. Do a man sh at the command-line, and search for REDIRECTION using "/REDIRECTION" and read from there.

Ruby: console.log?

puts is the equivalent in ruby.

Example

puts 'Hello World!'


Related Topics



Leave a reply



Submit