Re: Raised exceptions are not logged when USR2

2010-01-04 Thread Iñaki Baz Castillo
El Lunes, 4 de Enero de 2010, Eric Wong escribió:
> Iñaki Baz Castillo  wrote:
> > El Domingo, 3 de Enero de 2010, Eric Wong escribió:
> > >   # Totally untested, stick this in your Unicorn config file and let
> > >   # us know if it works or blows up badly:
> > >
> > >   require 'syslog_logger'
> > >
> > >   class MySyslogLogger < SyslogLogger
> > > alias puts error
> > > alias write error
> > > def flush; self; end
> > >   end
> > >
> > >   $stderr = MySyslogLogger.new('foo')
> >
> > Unfortunatelly it doesn'w work very well. First of all Sysloglogger
> > relies on a constant called SYSLOG created in "initialize" method so it's
> > required to add the above methods to SyslogLogger class rather than
> > subclass.
> >
> > Anyhow, the main problem is that by doing "$stderr =
> > SyslogLogger.new('foo')" the std error is not redirected as /proc/PID/fd
> > still shows:
> >
> >   2 -> /dev/pts/2
> 
> Yup, that's expected.  _Assigning_ $stderr does not do a redirect at the
> OS-level, only at th Ruby level (sufficient for env["rack.errors"],
> Kernel#warn).
> 
> > Of course by calling $stderr.puts "error" the above works, but when a
> > real error raised it's is printed in the screen (/dev/pts/2).
> >
> > I strongly think that IO#reopen is required. IO#reopen accepts a string
> > (file path) or other IO, so "converting" SyslogLogger into a IO is
> > required.
> >
> > I'll try to achieve it.
> 
> Yes, you need to do something that'll dup()/dup2() internally like
> IO#reopen to replace fd=2.  But when you have the raw file descriptor,
> you won't get syslog formatting...
> 
> The only way I can think of is to redirect fd=2 to the stdin of a
> separate process to add formatting in...
> 
>   r, w = IO.pipe
>   fork {
>  $stdin.reopen(r)
>  w.close
>  exec('ruby', '-rsyslog', '-ane',
>   'BEGIN{Syslog.open("foo")}; Syslog.warning $_')
>   }
>   r.close
>   $stderr.reopen(w)
> 
> Not pretty...


Thanks. Definitively it seems too much complex so I'll change myidea and will 
use a normal text file for stderr when running daemonized.

Thanks a lot.


-- 
Iñaki Baz Castillo 
___
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying


Re: Raised exceptions are not logged when USR2

2010-01-04 Thread Eric Wong
Iñaki Baz Castillo  wrote:
> El Domingo, 3 de Enero de 2010, Eric Wong escribió:
> 
> >   # Totally untested, stick this in your Unicorn config file and let
> >   # us know if it works or blows up badly:
> > 
> >   require 'syslog_logger'
> > 
> >   class MySyslogLogger < SyslogLogger
> > alias puts error
> > alias write error
> > def flush; self; end
> >   end
> > 
> >   $stderr = MySyslogLogger.new('foo')
> 
> Unfortunatelly it doesn'w work very well. First of all Sysloglogger relies on 
> a constant called SYSLOG created in "initialize" method so it's required to 
> add the above methods to SyslogLogger class rather than subclass.
> 
> Anyhow, the main problem is that by doing "$stderr = SyslogLogger.new('foo')" 
> the std error is not redirected as /proc/PID/fd still shows:
> 
>   2 -> /dev/pts/2

Yup, that's expected.  _Assigning_ $stderr does not do a redirect at the
OS-level, only at th Ruby level (sufficient for env["rack.errors"],
Kernel#warn).

> Of course by calling $stderr.puts "error" the above works, but when a real 
> error raised it's is printed in the screen (/dev/pts/2).

> I strongly think that IO#reopen is required. IO#reopen accepts a string (file 
> path) or other IO, so "converting" SyslogLogger into a IO is required.
> 
> I'll try to achieve it.

Yes, you need to do something that'll dup()/dup2() internally like
IO#reopen to replace fd=2.  But when you have the raw file descriptor,
you won't get syslog formatting...

The only way I can think of is to redirect fd=2 to the stdin of a
separate process to add formatting in...

  r, w = IO.pipe
  fork {
 $stdin.reopen(r)
 w.close
 exec('ruby', '-rsyslog', '-ane',
  'BEGIN{Syslog.open("foo")}; Syslog.warning $_')
  }
  r.close
  $stderr.reopen(w)

Not pretty...

-- 
Eric Wong
___
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying


Re: Raised exceptions are not logged when USR2

2010-01-04 Thread Iñaki Baz Castillo
El Domingo, 3 de Enero de 2010, Eric Wong escribió:

>   # Totally untested, stick this in your Unicorn config file and let
>   # us know if it works or blows up badly:
> 
>   require 'syslog_logger'
> 
>   class MySyslogLogger < SyslogLogger
> alias puts error
> alias write error
> def flush; self; end
>   end
> 
>   $stderr = MySyslogLogger.new('foo')


Unfortunatelly it doesn'w work very well. First of all Sysloglogger relies on 
a constant called SYSLOG created in "initialize" method so it's required to 
add the above methods to SyslogLogger class rather than subclass.

Anyhow, the main problem is that by doing "$stderr = SyslogLogger.new('foo')" 
the std error is not redirected as /proc/PID/fd still shows:

  2 -> /dev/pts/2

Of course by calling $stderr.puts "error" the above works, but when a real 
error raised it's is printed in the screen (/dev/pts/2).

I strongly think that IO#reopen is required. IO#reopen accepts a string (file 
path) or other IO, so "converting" SyslogLogger into a IO is required.

I'll try to achieve it.

Regards.




-- 
Iñaki Baz Castillo 
___
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying


Re: Raised exceptions are not logged when USR2

2010-01-04 Thread Iñaki Baz Castillo
El Domingo, 3 de Enero de 2010, Eric Wong escribió:
> If you really want to, you may be able to subclass SyslogLogger and give
> it IO-like methods (write/puts/flush) are require for Rack::Lint
> compatibility and then set $stderr:
> 
>   # Totally untested, stick this in your Unicorn config file and let
>   # us know if it works or blows up badly:
> 
>   require 'syslog_logger'
> 
>   class MySyslogLogger < SyslogLogger
> alias puts error
> alias write error
> def flush; self; end
>   end
> 
>   $stderr = MySyslogLogger.new('foo')
> 

They would be also needed these methods:

def reopen(v); true; end
def sync=(v); v; end

-- 
Iñaki Baz Castillo 
___
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying


Re: Raised exceptions are not logged when USR2

2010-01-03 Thread Iñaki Baz Castillo
El Domingo, 3 de Enero de 2010, Eric Wong escribió:

> Unfortunately, the stock Syslog module isn't compatible with the Ruby
> Logger implementation.  Try grabbing the "SyslogLogger" gem and using
> that instead.  I haven't had any experience with SyslogLogger, but a
> cursory look says it's OK.

Yes, in fact I already use a "bit" customized SyslogLogger :)

 
> If you really want to, you may be able to subclass SyslogLogger and give
> it IO-like methods (write/puts/flush) are require for Rack::Lint
> compatibility and then set $stderr:
> 
>   # Totally untested, stick this in your Unicorn config file and let
>   # us know if it works or blows up badly:
> 
>   require 'syslog_logger'
> 
>   class MySyslogLogger < SyslogLogger
> alias puts error
> alias write error
> def flush; self; end
>   end
> 
>   $stderr = MySyslogLogger.new('foo')

Really great! It works fine :)

 
> > BTW, how to reset the $stderr so it points again to the default one (the
> > terminal)?
> 
> You would've had to dup stderr in the config file and keep it referenced
> before it got redirected.  But a daemonized process shouldn't be holding
> onto terminals...


Really thanks a lot. 


-- 
Iñaki Baz Castillo 
___
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying


Re: Raised exceptions are not logged when USR2

2010-01-02 Thread Eric Wong
Iñaki Baz Castillo  wrote:
> El Sábado, 2 de Enero de 2010, Iñaki Baz Castillo escribió:
> > A simpler approach would be removing this line at the end of launcher.rb:
> > 
> >   Unicorn::Configurator::DEFAULTS[:stderr_path] = "/dev/null"
> > 
> > With this, errors would be displayed in stderr. Of course for workers
> >  stderr should be reopened to point to /dev/null, but IMHO not for master
> >  process.
> > 
> > Perhaps errors preventing the master process to start should be displayed
> >  to stderr instead of to the logger (as it could be not set yet).
> 
> And the other already available workaround is setting the "stderr_path".
> Unfortunatelly $stderr.reopen requires a file as parameter so is not possible 
> to use Syslog or any other logger, is it?

Hi Iñaki,

Unfortunately, the stock Syslog module isn't compatible with the Ruby
Logger implementation.  Try grabbing the "SyslogLogger" gem and using
that instead.  I haven't had any experience with SyslogLogger, but a
cursory look says it's OK.

I would always keep stderr_path set somewhere in your config file since
by default "rack.errors" points to it, and it's the default place for
Kernel#warn to output to.

If you really want to, you may be able to subclass SyslogLogger and give
it IO-like methods (write/puts/flush) are require for Rack::Lint
compatibility and then set $stderr:

  # Totally untested, stick this in your Unicorn config file and let
  # us know if it works or blows up badly:

  require 'syslog_logger'

  class MySyslogLogger < SyslogLogger
alias puts error
alias write error
def flush; self; end
  end

  $stderr = MySyslogLogger.new('foo')

> BTW, how to reset the $stderr so it points again to the default one (the 
> terminal)?

You would've had to dup stderr in the config file and keep it referenced
before it got redirected.  But a daemonized process shouldn't be holding
onto terminals...

-- 
Eric Wong
___
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying


Re: Raised exceptions are not logged when USR2

2010-01-02 Thread Iñaki Baz Castillo
El Sábado, 2 de Enero de 2010, Iñaki Baz Castillo escribió:
> A simpler approach would be removing this line at the end of launcher.rb:
> 
>   Unicorn::Configurator::DEFAULTS[:stderr_path] = "/dev/null"
> 
> With this, errors would be displayed in stderr. Of course for workers
>  stderr should be reopened to point to /dev/null, but IMHO not for master
>  process.
> 
> Perhaps errors preventing the master process to start should be displayed
>  to stderr instead of to the logger (as it could be not set yet).

And the other already available workaround is setting the "stderr_path".
Unfortunatelly $stderr.reopen requires a file as parameter so is not possible 
to use Syslog or any other logger, is it?

BTW, how to reset the $stderr so it points again to the default one (the 
terminal)?

-- 
Iñaki Baz Castillo 
___
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying


Re: Raised exceptions are not logged when USR2

2010-01-02 Thread Iñaki Baz Castillo
El Sábado, 2 de Enero de 2010, Iñaki Baz Castillo escribió:
> Hi, I use the ready_pipe branch. I set "logger" to log into Syslog, but the
> issue I'll explain here is the same even if I log to a file.
> 
> I runned Unicorn daemonized. Now imagine I do a typo in my Rack config.ru
>  (I use preload=true). When sending USR2 to the master it fails (ok) but
>  the raised exception is not shown in the logger, instead it's lost as
>  $stderr is /dev/null.
> 
> Even worse, imagine Unicorn is not running and I start it daemonized (with
>  a init script). Due to the typo in config.ru I see:
> 
>   "master failed to start, check stderr log for details"
> 
> But the message is useless since stderr is /dev/null so I se nothing in
> Syslog.
> 
> 
> So I suggest the following:
> 
> If the process fails after setting the logger, then rescue any exception,
>  log it to the logger and raise it as normal:
> 
>   rescue => err
> logger.fatal "#{err.class}:
>  #{err.message}\n#{err.backtrace.join("\n")}" raise err
>   end
> 
> I'm trying to figure where exactly to include such code but it seems a bit
> complex. Any tip please?
> 
> Thanks a lot.

A simpler approach would be removing this line at the end of launcher.rb:

  Unicorn::Configurator::DEFAULTS[:stderr_path] = "/dev/null" 

With this, errors would be displayed in stderr. Of course for workers stderr 
should be reopened to point to /dev/null, but IMHO not for master process.

Perhaps errors preventing the master process to start should be displayed to 
stderr instead of to the logger (as it could be not set yet).

Opinnions?


-- 
Iñaki Baz Castillo 
___
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying


Raised exceptions are not logged when USR2

2010-01-02 Thread Iñaki Baz Castillo
Hi, I use the ready_pipe branch. I set "logger" to log into Syslog, but the 
issue I'll explain here is the same even if I log to a file.

I runned Unicorn daemonized. Now imagine I do a typo in my Rack config.ru (I 
use preload=true). When sending USR2 to the master it fails (ok) but the 
raised exception is not shown in the logger, instead it's lost as $stderr is 
/dev/null.

Even worse, imagine Unicorn is not running and I start it daemonized (with a 
init script). Due to the typo in config.ru I see:

  "master failed to start, check stderr log for details"

But the message is useless since stderr is /dev/null so I se nothing in 
Syslog.


So I suggest the following:

If the process fails after setting the logger, then rescue any exception, log 
it to the logger and raise it as normal:

  rescue => err
logger.fatal "#{err.class}: #{err.message}\n#{err.backtrace.join("\n")}"
raise err
  end

I'm trying to figure where exactly to include such code but it seems a bit 
complex. Any tip please?

Thanks a lot.


-- 
Iñaki Baz Castillo 
___
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying