--- server/modules/logging/vhostlog.pike | 119 ++++++++++++++++++++++++++++++++++ 1 files changed, 119 insertions(+), 0 deletions(-) create mode 100644 server/modules/logging/vhostlog.pike
diff --git a/server/modules/logging/vhostlog.pike b/server/modules/logging/vhostlog.pike new file mode 100644 index 0000000..9b61f7e --- /dev/null +++ b/server/modules/logging/vhostlog.pike @@ -0,0 +1,119 @@ +// This is a roxen module which provides splitted virtual host logging. +// Copyright (c) 2007-2009, Stephen R. van den Berg, The Netherlands. +// <[email protected]> +// +// This module is open source software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation; either version 2, or (at your option) any +// later version. +// + +constant thread_safe=1; + +#include <config.h> +inherit "module"; +#include <module.h> + +constant module_type = MODULE_LOGGER; +constant module_name = "Logger: Virtual host logger"; +constant module_doc = + "This module provides separated virtual host logging.<br>" + "<p>Copyright © 2007-2009, by " + "<a href='mailto:[email protected]'>Stephen R. van den Berg</a>, " + "The Netherlands.</p>" + "<p>This module is open source software; you can redistribute it and/or " + "modify it under the terms of the GNU General Public License as published " + "by the Free Software Foundation; either version 2, or (at your option) any " + "later version.</p>"; + +string create() +{ + set_module_creator("Stephen R. van den Berg <[email protected]>"); + defvar("block", 0, "Only log in userlog", TYPE_FLAG, + "If set, no entry will be written to the normal log.\n"); + + defvar("LogFormat", + "*: $ip_number - $user [$cern_date] \"$method $full_resource $protocol\" $response $length \"$referrer\" \"$user_agent_raw\"" + , + + "Logging Format", + TYPE_TEXT_FIELD, + + "What format to use for logging. See standard logspecs for reference.\n" + ); + + defvar("LogFile", "$LOGDIR/vhostlogs/%v/Log", + "Logging: Log file", TYPE_FILE, + "The log file. " + "" + "A file name. Some substitutions will be done:" + "<pre>" + "%y Year (e.g. '1997')\n" + "%m Month (e.g. '08')\n" + "%d Day (e.g. '10' for the tenth)\n" + "%h Hour (e.g. '00')\n" + "%H Hostname\n" + "%v Virtual hostname\n" + "</pre>" + ); +} + +mapping(int:string) log_format = ([]); +mapping(string:object) logfiles = ([]); + +private void parse_log_formats() +{ string b; + array foo=query("LogFormat")/"\n"; + log_format = ([]); + foreach(foo, b) + if(strlen(b) && b[0] != '#' && sizeof(b/":")>1) + log_format[(int)(b/":")[0]]=String.trim_whites((b/":")[1..]*":"); +} + +string start() +{ parse_log_formats(); +} + +static string lastfile,lasthost; + +string status() { + return sprintf("Total logfiles accessed: %d<br />" + "Last logfile opened: %s<br />" + "Last virtual host accessed: %s", + sizeof(logfiles),lastfile||"NONE",lasthost||"NONE"); +} + +int log(RequestID id, mapping file) +{ object curlogfile; + { string vhost; + sscanf(id->url_base(), "%*[a-z]://%[^:/]", vhost); + if(!(curlogfile=logfiles[vhost])) + { string logfile; + logfile=replace(query("LogFile"),"%v",vhost); + + if(file->error==404 || file->error==200 && + "/"==(string)(id->raw_url + ||(id->misc->common && id->misc->common->orig_url) + ||id->not_query)) + { string dirn=dirname(logfile); + if(!dirn || !file_stat(dirn)) + return 0; // Do not create vhosts on 404 errors or / fetches + } + logfiles[vhost]=curlogfile=roxen.LogFile(lastfile=logfile, + ""/*query("LogFileCompressor")*/); // FIXME from the global config? + } + lasthost=vhost; + } + if(curlogfile) + { string form; + if(!(form=log_format[file->error])) + form=log_format[0]; + if(form) + catch + { roxen.run_log_format(form, curlogfile->write, id, file); + if(query("block")) + return 1; + }; + } + return 0; +}
