Received: (from majordom@localhost) by hyperreal.org (8.8.5/8.8.5) id BAA00399; Tue, 26 Aug 1997 01:37:01 -0700 (PDT) Received: from twinlark.arctic.org (twinlark.arctic.org [204.62.130.91]) by hyperreal.org (8.8.5/8.8.5) with SMTP id BAA00392 for ; Tue, 26 Aug 1997 01:36:58 -0700 (PDT) Received: (qmail 2124 invoked from network); 26 Aug 1997 08:36:56 -0000 Received: from benchlark.arctic.org (206.221.201.235) by twinlark.arctic.org with SMTP; 26 Aug 1997 08:36:56 -0000 Date: Tue, 26 Aug 1997 01:37:09 -0700 (PDT) From: Dean Gaudet To: new-httpd@apache.org Subject: [PATCH] buffered logs Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Sender: new-httpd-owner@apache.org Precedence: bulk Reply-To: new-httpd@apache.org I never got time to make this a runtime option. But here it is as a compile-time option. It only seems worth about 4% more r/s in some lame benchmarking I did. Not a heck of a lot... but that number probably differs on different unixes. Dean Index: modules/standard/mod_log_config.c =================================================================== RCS file: /export/home/cvs/apachen/src/modules/standard/mod_log_config.c,v retrieving revision 1.36 diff -u -r1.36 mod_log_config.c --- mod_log_config.c 1997/08/23 02:59:45 1.36 +++ mod_log_config.c 1997/08/26 08:30:28 @@ -164,6 +164,7 @@ #include "httpd.h" #include "http_config.h" #include "http_core.h" /* For REMOTE_NAME */ +#include module MODULE_VAR_EXPORT config_log_module; @@ -175,6 +176,21 @@ static mode_t xfer_mode = ( S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH ); #endif +/* POSIX.1 defines PIPE_BUF as the maximum number of bytes that is + * guaranteed to be atomic when writing a pipe. And PIPE_BUF >= 512 + * is guaranteed. So we'll just guess 512 in the event the system + * doesn't have this. Now, for file writes there is actually no limit, + * the entire write is atomic. Whether all systems implement this + * correctly is another question entirely ... so we'll just use PIPE_BUF + * because it's probably a good guess as to what is implemented correctly + * everywhere. + */ +#ifdef PIPE_BUF +#define LOG_BUFSIZE PIPE_BUF +#else +#define LOG_BUFSIZE (512) +#endif + /* * multi_log_state is our per-(virtual)-server configuration. We store * an array of the logs we are going to use, each of type config_log_state. @@ -209,6 +225,10 @@ char *fname; array_header *format; int log_fd; +#ifdef BUFFERED_LOGS + int outcnt; + char outbuf[LOG_BUFSIZE]; +#endif } config_log_state; /* @@ -525,6 +545,16 @@ return cp ? cp : "-"; } +#ifdef BUFFERED_LOGS +static void flush_log (config_log_state *cls) +{ + if (cls->outcnt && cls->log_fd != -1) { + write (cls->log_fd, cls->outbuf, cls->outcnt); + cls->outcnt = 0; + } +} +#endif + static int config_log_transaction(request_rec *r, config_log_state *cls, array_header *default_format) { array_header *strsa; @@ -562,8 +592,20 @@ strcpy (s, strs[i]); s += strlen (strs[i]); } - - write(cls->log_fd, str, strlen(str)); + +#ifdef BUFFERED_LOGS + if (len + cls->outcnt > LOG_BUFSIZE) { + flush_log (cls); + } + if (len >= LOG_BUFSIZE) { + write (cls->log_fd, str, len); + } else { + memcpy (&cls->outbuf[cls->outcnt], str, len); + cls->outcnt += len; + } +#else + write (cls->log_fd, str, len); +#endif return OK; } @@ -606,7 +648,7 @@ (multi_log_state *)palloc(p, sizeof (multi_log_state)); mls->config_logs = - make_array(p, 5, sizeof (config_log_state)); + make_array(p, 1, sizeof (config_log_state)); mls->default_format = NULL; mls->server_config_logs = NULL; @@ -736,6 +778,9 @@ exit(1); } } +#ifdef BUFFERED_LOGS + cls->outcnt = 0; +#endif return cls; } @@ -784,6 +829,32 @@ for (s = s->next; s; s = s->next) open_multi_logs (s, p); } +#ifdef BUFFERED_LOGS +static void flush_all_logs (server_rec *s, pool *p) +{ + multi_log_state *mls; + array_header *log_list; + config_log_state *clsarray; + int i; + + for (; s; s = s->next) { + mls = get_module_config(s->module_config, &config_log_module); + log_list = NULL; + if (mls->config_logs->nelts) { + log_list = mls->config_logs; + } else if (mls->server_config_logs) { + log_list = mls->server_config_logs; + } + if (log_list) { + clsarray = (config_log_state *)log_list->elts; + for (i = 0; i < log_list->nelts; ++i) { + flush_log (&clsarray[i]); + } + } + } +} +#endif + module MODULE_VAR_EXPORT config_log_module = { STANDARD_MODULE_STUFF, init_config_log, /* initializer */ @@ -802,6 +873,10 @@ multi_log_transaction, /* logger */ NULL, /* header parser */ NULL, /* child_init */ - NULL, /* child_exit */ +#ifdef BUFFERED_LOGS + flush_all_logs, /* child_exit */ +#else + NULL, +#endif NULL /* post read-request */ };