Network.FastCGI does not emit stderr outputs to lighttpd's error.log?

Hi, I'm trying Network.FastCGI + lighttpd 1.4.9 to develop a RESTful service platform. I've found that stderr (especially those from Debug.Trace) get lost in the error.log file. But plain CGI mode with Network.CGI works perfectly (all stderr outputs appear in error.log). Besides, my Perl fastcgi script also logs stderr with the same lighttpd. So it does seem that my lighttpd's mod_fastcgi module is OK. Is this a known issue in the Haskell fastcgi library? Is there a workaround or a fix? Thanks in advance :) Cheers, -agentzh

agentzh:
Hi,
I'm trying Network.FastCGI + lighttpd 1.4.9 to develop a RESTful service platform. I've found that stderr (especially those from Debug.Trace) get lost in the error.log file. But plain CGI mode with Network.CGI works perfectly (all stderr outputs appear in error.log). Besides, my Perl fastcgi script also logs stderr with the same lighttpd. So it does seem that my lighttpd's mod_fastcgi module is OK.
Is this a known issue in the Haskell fastcgi library? Is there a workaround or a fix? Thanks in advance :)
We've had no problems with this and apache at least. Is lighttpd doing something funny with error logging? -- Don

On Thu, Jul 31, 2008 at 1:56 AM, Don Stewart
We've had no problems with this and apache at least. Is lighttpd doing something funny with error logging?
It seems that Apache is doing something funny :) According to my teammate chaoslawful, apache redirects stderr to its error log files (if any) but the fastcgi spec actually says everything should go through the socket. And lighttpd seems to be following the spec exactly :) chaoslawful++ finally come up with the following patch for lighttpd 1.4.19 to make lighttpd behave in the same way as apache. Devel.Debug is now finally working for me for my Haskell fastcgi hacking :)) --- lighttpd-1.4.19/src/log.c 2007-08-22 01:40:03.000000000 +0800 +++ lighttpd-1.4.19-patched/src/log.c 2008-07-31 15:13:10.000000000 +0800 @@ -83,9 +83,14 @@ /* move stderr to /dev/null */ if (close_stderr && -1 != (fd = open("/dev/null", O_WRONLY))) { - close(STDERR_FILENO); + // XXX: modified by chaoslawful, don't close stderr when log into file + close(STDERR_FILENO); + if (srv->errorlog_mode == ERRORLOG_FILE && srv->errorlog_fd >=0 ) { + dup2(srv->errorlog_fd,STDERR_FILENO); + } else { dup2(fd, STDERR_FILENO); - close(fd); + } + close(fd); } return 0; } Best, -agentzh

agentzh:
On Thu, Jul 31, 2008 at 1:56 AM, Don Stewart
wrote: We've had no problems with this and apache at least. Is lighttpd doing something funny with error logging?
It seems that Apache is doing something funny :) According to my teammate chaoslawful, apache redirects stderr to its error log files (if any) but the fastcgi spec actually says everything should go through the socket. And lighttpd seems to be following the spec exactly :)
chaoslawful++ finally come up with the following patch for lighttpd 1.4.19 to make lighttpd behave in the same way as apache. Devel.Debug is now finally working for me for my Haskell fastcgi hacking :))
--- lighttpd-1.4.19/src/log.c 2007-08-22 01:40:03.000000000 +0800 +++ lighttpd-1.4.19-patched/src/log.c 2008-07-31 15:13:10.000000000 +0800 @@ -83,9 +83,14 @@ /* move stderr to /dev/null */ if (close_stderr && -1 != (fd = open("/dev/null", O_WRONLY))) { - close(STDERR_FILENO); + // XXX: modified by chaoslawful, don't close stderr when log into file + close(STDERR_FILENO); + if (srv->errorlog_mode == ERRORLOG_FILE && srv->errorlog_fd >=0 ) { + dup2(srv->errorlog_fd,STDERR_FILENO); + } else { dup2(fd, STDERR_FILENO); - close(fd); + } + close(fd); } return 0; }
Best, -agentzh
Interesting result, thanks for looking into this.

On Thu, Jul 31, 2008 at 6:37 PM, Don Stewart
agentzh:
On Thu, Jul 31, 2008 at 1:56 AM, Don Stewart
wrote: We've had no problems with this and apache at least. Is lighttpd doing something funny with error logging?
It seems that Apache is doing something funny :) According to my teammate chaoslawful, apache redirects stderr to its error log files (if any) but the fastcgi spec actually says everything should go through the socket. And lighttpd seems to be following the spec exactly :)
chaoslawful++ finally come up with the following patch for lighttpd 1.4.19 to make lighttpd behave in the same way as apache. Devel.Debug is now finally working for me for my Haskell fastcgi hacking :))
--- lighttpd-1.4.19/src/log.c 2007-08-22 01:40:03.000000000 +0800 +++ lighttpd-1.4.19-patched/src/log.c 2008-07-31 15:13:10.000000000 +0800 @@ -83,9 +83,14 @@ /* move stderr to /dev/null */ if (close_stderr && -1 != (fd = open("/dev/null", O_WRONLY))) { - close(STDERR_FILENO); + // XXX: modified by chaoslawful, don't close stderr when log into file + close(STDERR_FILENO); + if (srv->errorlog_mode == ERRORLOG_FILE && srv->errorlog_fd >=0 ) { + dup2(srv->errorlog_fd,STDERR_FILENO); + } else { dup2(fd, STDERR_FILENO); - close(fd); + } + close(fd); } return 0; }
Best, -agentzh
Interesting result, thanks for looking into this.
You could also handle this issue without modifying Lighttpd by redirecting stderr to a file. Put this in your Haskell program: import System.Posix.Files import System.Posix.IO stderrToFile :: FilePath -> IO () stderrToFile file = do let mode = ownerModes `unionFileModes` groupReadMode `unionFileModes` otherReadMode fileFd <- openFd file WriteOnly (Just mode) (defaultFileFlags { append = True }) dupTo fileFd stdError return () main = do stderrToFile "my-fastcgi-log.log" runFastCGI ... Another way is to have a small wrapper shell script around your FastCGI program that does the same redirection. /Björn
participants (3)
-
Agent Zhang
-
Bjorn Bringert
-
Don Stewart