Tuesday, April 29, 2008

[SYSCTL] Lighttpd separate Error Log for 404's

You might have seen that my lighttpd conf doesn't include an access log... in fact I don't even load mod_accesslog.

Why would I want or even need to log access to my static content... you might need it, but I don't. Also, since I run multiple workers, even if I wanted to log server accesses, the log file would be broken (logs + multiple workers are not handled well at the moment).

However, if I don't care about 200s, I do need to get my 404 errors logged...
Apache logs 404s and > 400 in the error_log file, but Lighty doesn't (it uses access.log for that). However there's a nice feature called "server.error-handler-404" to bypass this issue.

This is how I use it... in the conf file :
server.error-handler-404 = "/errors/log_errors.x"
static-file.exclude-extensions = ( ".x" )
fastcgi.server = ( "/your_noatime_.../static/errors/log_errors.x" => ((
"bin-path" => "/usr/local/bin/log_errors.x",
"host" => "",
"port" => 8200, # (why not...)
"min-procs" => 1,
"max-procs" => 1,
"check-local" => "disable"

touch /your_noatime_mounted_partition/static/errors/log_errors.x

Install FastCGI dev lib from :

Then edit log_errors.c :
#include <time.h>
#include <stdio.h>
#include "fcgi_config.h"
#include "fcgi_stdio.h"
#include <stdlib.h>
int main () {
FCGI_FILE *err = FCGI_fopen("/your/path/to/error.log","a");
if(!err) return 1;
while (FCGI_Accept() >= 0) {
time_t rawtime;
char buf [80];
strftime(buf,80,"%Y-%m-%d %H:%M:%S",localtime(&(rawtime)));
char *uri = getenv("REQUEST_URI");
FCGI_fprintf(err,"[%s] 404 : %s\n",buf,uri);
// FCGI_fflush(err); - if low traffic and realtime logs desired
printf("Content-type: text/html\r\nRefresh: 0;url=/nice_message.html\r\n\r\n");
return 0;
// EOF

Then :
gcc -I/usr/local/include -L/usr/local/lib -Wall -O2 -o log_errors.x log_errors.c -lfcgi
mv log_errors.x /usr/local/bin/log_errors.x

And that's it...
Oh, this is not the most beautiful piece of code you can find... but it does the job.
I'll be happy to get better code if you write it...

Tuesday, April 15, 2008

[SYSCTL] Testing Lighttpd

In need for a server that would serve only static content (small files), but at the highest rate possible, I've tested Nginx, Lighty and Apache.

While Apache is clearly out of the game, Nginx wasn't that bad, however lighty 1.4.19 clearly achieved the best performance (even better than 1.5.0 with sendfile-aio) and was much better documented.

Since I thought I was really wasting my time testing different parameters (which many other probably already did) to achieve the best performance, I'm posting my config file here in hope it will be useful.

server.document-root = "/your_noatime_mounted_partition/static"
server.errorlog = "/your_noatime_.../logs/lighttpd.error.log"
server.event-handler = "linux-sysepoll" = "linux-sendfile"
server.max-fds = 8192
server.max-connections = 4096
server.stat-cache-engine = "simple"
server.max-worker = 4 # (= number of CPU)
server.max-read-idle = 60
server.max-write-idle = 360
server.max-keep-alive-requests = 1024
server.max-keep-alive-idle = 16
server.bind = ""
server.port = 80
dir-listing.activate = "disable"
etag.use-inode = "enable"
etag.use-mtime = "enable"
static-file.etags = "enable"
server.username = "your_favorite_anonymous_user"
server.groupname = "your_favorite_anonymous_group"
mimetype.assign = (
".swf" => "application/x-shockwave-flash",
".gif" => "image/gif",
".jpg" => "image/jpeg",
".jpeg" => "image/jpeg",
".png" => "image/png"

You can then use mod_mem_cache if you want even better performance...