18

I am working on creating a daemon in Ruby using the daemons gem. I want to add output from the daemon into a log file. I am wondering what is the easiest way to redirect puts from the console to a log file.

tshepang
  • 12,111
  • 21
  • 91
  • 136
Josh Moore
  • 13,338
  • 15
  • 58
  • 74
  • Use this `LOGGER ||= Logger.new("| tee #{settings.root}/log/migration_script_logger.log", "monthly")` , this will do both – vs4vijay Mar 31 '16 at 12:12

4 Answers4

39

If you need to capture both STDERR and STDOUT and don't want to resort to logging:

$stdout.reopen("my.log", "w")
$stdout.sync = true
$stderr.reopen($stdout)

To restore:

$stdout = STDOUT
user664833
  • 18,397
  • 19
  • 91
  • 140
Eric Walker
  • 7,063
  • 3
  • 35
  • 38
  • 1
    Thanks, that worked mighty fine in conjunction with [this](http://stackoverflow.com/questions/1993071/how-to-controller-start-kill-a-background-process-server-app-in-ruby)! – TheDeadSerious Feb 05 '11 at 17:01
  • 2
    what if you want puts to still go to terminal, as well as to log file? e.g. behaviour like `ruby myscript.rb | tee my.log` – wim Apr 05 '13 at 16:38
  • 1
    @wim I know this comment is a bit old, but there are some solutions listed here http://stackoverflow.com/questions/6407141/how-can-i-have-ruby-logger-log-output-to-stdout-as-well-as-file/ – Jerska Dec 11 '13 at 10:23
  • 1
    The command `$stdout.reopen("my.log", "w")` breaks my rails console (I have to kill the process). Looking into other solutions. – Alex C Jan 21 '16 at 19:23
  • @AlexC, in Rails there's the Rails logger: http://guides.rubyonrails.org/debugging_rails_applications.html#the-logger. – Eric Walker Jan 21 '16 at 23:39
14

Try

$stdout = File.new( '/tmp/output', 'w' )

To restore:

$stdout = STDOUT
Pistos
  • 23,070
  • 14
  • 64
  • 77
13

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"
Vitalie
  • 736
  • 3
  • 9
  • 17
    This doesn't really answer the question. What if you can't control who is doing the _puts_ and you want to to capture things that would normally write to STDOUT and instead write them to a file? – silvamerica Apr 25 '11 at 19:17
0

Or you can redefine the puts command? Works probably only in a single file/class

def puts(message)
   #write message to file
end
Peterdk
  • 15,625
  • 20
  • 101
  • 140