Rails - Redirecting Console Output to a File

rails - Redirecting console output to a file

You can use override $stdout to redirect the console output:

$stdout = File.new('console.out', 'w')

You may also need to call this once:

$stdout.sync = true

To restore:

$stdout = STDOUT

Redirect the puts command output to a log file

I should recommend to use ruby logger, it is better than puts, you can have multiple log levels that you can turn on/off: debug, warn, info,error, etc.

 logger = Logger.new(STDOUT)
logger = Logger.new("/var/log/my-daemon.log")

I use runit package to manage ruby services, it has svlogd than will redirect daemon output to log file, here is run script for logger process:

#!/bin/sh
set -e

LOG=/var/log/my-daemon

test -d "$LOG" || mkdir -p -m2750 "$LOG" && chown nobody:adm "$LOG"
exec chpst -unobody svlogd -tt "$LOG"

Ruby redirect output to file

You either can write to a file explicitly (open file and write to it)

file = File.open('target.file', 'w') do |file|
File.foreach('links.txt') do |li|
file.puts(li) if li['PersonNight']
end
end

Or redirect from outside your script, using regular unix machinery

ruby my_script.rb > target.file

How to redirect tracepoint output to a file in Ruby?

As a comment said, the p prints to stdout. To redirect the output to another TTY (or another file), the file needs to be opened and the .print method can be used. The following code gets the desired functionality:

def start_trace
file = File.open("/dev/ttys007", "w")
trace =
TracePoint.new(:call) { |tp|
file.print [tp.path, tp.lineno, tp.event, tp.method_id]
file.puts()
}
trace.enable
yield
trace.disable
file.close
end


def fun1
puts("This is fun1")
end

def fun2
puts("This is fun2")
end

def fun3(num)
puts("This is fun3: " + num)
fun2
end

start_trace { fun3("bye") }

Log rails console always to file in production env

Here's a solution with only one file for a whole system, no modification to your Rails projects and no modification to your console command.

You can put this in your ~/.irbrc, I tested it with Ruby 2.1.5 and Rails 3.2/4.0/4.2 :

# ~/.irbrc for http://stackoverflow.com/questions/39411783/log-rails-console-always-to-file-in-production-env
if defined? Rails
puts "Loading configuration for Rails console from #{__FILE__}"
time = Time.now.strftime('%Y_%m_%d__%H_%M_%S')
log_file = File.join(Rails.root, "log", "rails_console_#{Rails.env}_#{time}.log")
#log_file = "/home/sshuser/myproject/console_sessions/#{time}.txt"
puts " logging to #{log_file}"
logger = Logger.new(log_file)
Rails.logger = logger
ActiveRecord::Base.logger = logger if defined? ActiveRecord

# Intercepts STDIN from IRB
module Readline
module History
def self.write_log(line)
Rails.logger.info(line)
end

def self.start_session_log
write_log("# session start: #{Time.now}")
at_exit { write_log(" # session stop: #{Time.now}") }
end
end

alias :old_readline :readline
def readline(*args)
ln = old_readline(*args)
begin
History.write_log("STDIN : #{ln}")
rescue
end
ln
end
end

# $stdout writes to STDOUT and Rails.logger
# $stderr writes to STDERR and Rails.logger
class MultiLog
def initialize(io)
@io = io
@desc = io.inspect[/STD\w+/]
end

def write(str)
Rails.logger.info("#{@desc} : #{str}")
@io.write(str)
end

def close
@io.close
end
end

$stdout = MultiLog.new(STDOUT)
$stderr = MultiLog.new(STDERR)

Readline::History.start_session_log
end

For Pry, you should use this ~/.pryrc :

# ~/.pryrc for http://stackoverflow.com/questions/39411783/log-rails-console-always-to-file-in-production-env

if defined? Rails
puts "Loading configuration for Rails console from #{__FILE__}"
time = Time.now.strftime('%Y_%m_%d__%H_%M_%S')
log_file = File.join(Rails.root, "log", "rails_console_#{Rails.env}_#{time}.log")
#log_file = "/home/sshuser/myproject/console_sessions/#{time}.txt"
puts " logging to #{log_file}"
logger = Logger.new(log_file)
Rails.logger = logger
ActiveRecord::Base.logger = logger if defined? ActiveRecord

# Intercepts STDIN from pry (from http://www.hardscrabble.net/2015/how-to-log-all-input-in-your-pry-rails-console)
class LoggingReadline
delegate :completion_proc, :completion_proc=, to: Readline

def readline(prompt)
Readline.readline(prompt).tap do |user_input|
Rails.logger.info("STDIN : #{user_input}")
end
end
end

Pry.config.input = LoggingReadline.new

# $stdout writes to STDOUT and Rails.logger
# $stderr writes to STDERR and Rails.logger
class MultiLog
# Needed for #tty?, #flush : https://github.com/pry/pry/issues/1464
def method_missing(sym,*p)
@io.send(sym,*p)
end

def initialize(io)
@io = io
@desc = io.inspect[/STD\w+/]
end

def write(str)
Rails.logger.info("#{@desc} : #{str}")
@io.write(str)
end

alias_method :print, :write
end

$stdout = MultiLog.new(STDOUT)
$stderr = MultiLog.new(STDERR)

end

It saves console input, output and errors, as well as database queries into the specified file.
For example :

 ~/www/my_movies> bundle exec rails console -e development                                                                  
Loading development environment (Rails 4.0.4)
Loading configuration for Rails console from /home/ricou/.irbrc
logging to /home/ricou/www/my_movies/log/rails_console_development_2016_10_28__11_58_41.log
2.1.5 :001 > Movie.first
=> Est - Ouest
2.1.5 :002 > puts 2+2
4
=> nil
2.1.5 :003 > exit

outputs this log file :

# Logfile created on 2016-10-28 11:58:41 +0200 by logger.rb/44203
I, [2016-10-28T11:58:41.062811 #3860] INFO -- : # session start: 2016-10-28 11:58:41 +0200
I, [2016-10-28T11:58:46.822753 #3860] INFO -- : STDIN : Movie.first
D, [2016-10-28T11:58:46.883974 #3860] DEBUG -- : Movie Load (0.7ms) SELECT "movies".* FROM "movies" ORDER BY "movies"."id" ASC LIMIT 1
I, [2016-10-28T11:58:46.896787 #3860] INFO -- : STDOUT : => Est - Ouest

I, [2016-10-28T11:58:48.922083 #3860] INFO -- : STDIN : puts 2+2
I, [2016-10-28T11:58:48.922486 #3860] INFO -- : STDOUT : 4
I, [2016-10-28T11:58:48.922524 #3860] INFO -- : STDOUT :

I, [2016-10-28T11:58:48.922584 #3860] INFO -- : STDOUT : => nil

I, [2016-10-28T11:58:50.341326 #3860] INFO -- : STDIN : exit
I, [2016-10-28T11:58:50.342142 #3860] INFO -- : # session stop: 2016-10-28 11:58:50 +0200

How do I dump Pry output to a file or Vim?


I have a hash, with nested hashes/objects, which I need to send over to a 3rd party for work with an API. They need a dump of the data so they can set up the receiving end of my call. I'm just going to do this in Ruby now, but it would have made more sense to dump the data through PRY, rather than edit my ruby object to dump the data, which I only need once.

If you can start the server from a local command-line, or SSH to the host and run an instance there, you can use Pry for this. Basically you need to add these lines to your code at the appropriate place:

require 'pry-debugger'; binding.pry

which will stop your code and put you at the Pry prompt. At that point you can enter something like:

require 'json'
File.write('test.data', hash.to_json)

Read the Pry.debugger documentation for information about using Pry with remote Rails sessions, which might work better for you.

How replicate rails console output style in runner script?

This formatting is a result of PrettyPrint module - PP:

u = User.first
pp u #=> Which is basically a shortcut for: PP.pp(u)

Note however, that by default this will not generate a colourful output. Pry additionally process the formatted string through another gem - coderay, which is responsible for ruby syntax highlighting. If you want to print in colour, then:

u = User.first
Pry::ColorPrinter.pp(u)


Related Topics



Leave a reply



Submit