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.
            Asked
            
        
        
            Active
            
        
            Viewed 2.5k times
        
    18
            
            
         
    
    
        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 Answers
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
- 
                    1Thanks, 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
- 
                    2what 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
- 
                    1The 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
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
- 
                    17This 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
