diff -urN squid-2.5.STABLE10/src/access_log.c squid-2.5.STABLE10-loghelper/src/access_log.c
--- squid-2.5.STABLE10/src/access_log.c	2005-03-30 09:13:11.000000000 +1000
+++ squid-2.5.STABLE10-loghelper/src/access_log.c	2005-08-26 13:40:51.000000000 +1000
@@ -245,21 +245,39 @@
 	client = inet_ntoa(al->cache.caddr);
     user = accessLogFormatName(al->cache.authuser ?
 	al->cache.authuser : al->cache.rfc931);
-    logfilePrintf(logfile, "%9ld.%03d %6d %s %s/%03d %" PRINTF_OFF_T " %s %s %s %s%s/%s %s",
-	(long int) current_time.tv_sec,
-	(int) current_time.tv_usec / 1000,
-	al->cache.msec,
-	client,
-	log_tags[al->cache.code],
-	al->http.code,
-	al->cache.size,
-	al->private.method_str,
-	al->url,
-	user && *user ? user : dash_str,
-	al->hier.ping.timedout ? "TIMEOUT_" : "",
-	hier_strings[al->hier.code],
-	al->hier.host,
-	al->http.content_type);
+    if (!Config.Program.loghelper) {
+        logfilePrintf(logfile, "%9ld.%03d %6d %s %s/%03d %" PRINTF_OFF_T " %s %s %s %s%s/%s %s",
+            (long int) current_time.tv_sec,
+            (int) current_time.tv_usec / 1000,
+            al->cache.msec,
+            client,
+            log_tags[al->cache.code],
+            al->http.code,
+            al->cache.size,
+            al->private.method_str,
+            al->url,
+            user && *user ? user : dash_str,
+            al->hier.ping.timedout ? "TIMEOUT_" : "",
+            hier_strings[al->hier.code],
+            al->hier.host,
+            al->http.content_type);
+    } else {
+        logHelperStart("%9ld.%03d %6d %s %s/%03d %" PRINTF_OFF_T " %s %s %s %s%s/%s %s\n",
+            (long int) current_time.tv_sec,
+            (int) current_time.tv_usec / 1000,
+            al->cache.msec,
+            client,
+            log_tags[al->cache.code],
+            al->http.code,
+            al->cache.size,
+            al->private.method_str,
+            al->url,
+            user && *user ? user : dash_str,
+            al->hier.ping.timedout ? "TIMEOUT_" : "",
+            hier_strings[al->hier.code],
+            al->hier.host,
+            al->http.content_type);
+    }
     safe_free(user);
 }
 
@@ -274,18 +292,33 @@
 	client = inet_ntoa(al->cache.caddr);
     user1 = accessLogFormatName(al->cache.authuser);
     user2 = accessLogFormatName(al->cache.rfc931);
-    logfilePrintf(logfile, "%s %s %s [%s] \"%s %s HTTP/%d.%d\" %d %" PRINTF_OFF_T " %s:%s",
-	client,
-	user2 ? user2 : dash_str,
-	user1 ? user1 : dash_str,
-	mkhttpdlogtime(&squid_curtime),
-	al->private.method_str,
-	al->url,
-	al->http.version.major, al->http.version.minor,
-	al->http.code,
-	al->cache.size,
-	log_tags[al->cache.code],
-	hier_strings[al->hier.code]);
+    if (!Config.Program.loghelper) {
+        logfilePrintf(logfile, "%s %s %s [%s] \"%s %s HTTP/%d.%d\" %d %" PRINTF_OFF_T " %s:%s",
+            client,
+            user2 ? user2 : dash_str,
+            user1 ? user1 : dash_str,
+            mkhttpdlogtime(&squid_curtime),
+            al->private.method_str,
+            al->url,
+            al->http.version.major, al->http.version.minor,
+            al->http.code,
+            al->cache.size,
+            log_tags[al->cache.code],
+            hier_strings[al->hier.code]);
+    } else {
+        logHelperStart("%s %s %s [%s] \"%s %s HTTP/%d.%d\" %d %" PRINTF_OFF_T " %s:%s\n",
+            client,
+            user2 ? user2 : dash_str,
+            user1 ? user1 : dash_str,
+            mkhttpdlogtime(&squid_curtime),
+            al->private.method_str,
+            al->url,
+            al->http.version.major, al->http.version.minor,
+            al->http.code,
+            al->cache.size,
+            log_tags[al->cache.code],
+            hier_strings[al->hier.code]);
+    }
     safe_free(user1);
     safe_free(user2);
 }
@@ -313,11 +346,15 @@
     if (Config.onoff.log_mime_hdrs) {
 	char *ereq = log_quote(al->headers.request);
 	char *erep = log_quote(al->headers.reply);
-	logfilePrintf(logfile, " [%s] [%s]\n", ereq, erep);
+        if (!Config.Program.loghelper) {
+            logfilePrintf(logfile, " [%s] [%s]\n", ereq, erep);
+        }
 	safe_free(ereq);
 	safe_free(erep);
     } else {
-	logfilePrintf(logfile, "\n");
+        if (!Config.Program.loghelper) {
+            logfilePrintf(logfile, "\n");
+        }
     }
     logfileFlush(logfile);
 #if MULTICAST_MISS_STREAM
diff -urN squid-2.5.STABLE10/src/cache_cf.c squid-2.5.STABLE10-loghelper/src/cache_cf.c
--- squid-2.5.STABLE10/src/cache_cf.c	2005-05-07 08:33:53.000000000 +1000
+++ squid-2.5.STABLE10-loghelper/src/cache_cf.c	2005-08-26 09:22:46.000000000 +1000
@@ -393,6 +393,9 @@
 #if USE_UNLINKD
     requirePathnameExists("unlinkd_program", Config.Program.unlinkd);
 #endif
+    if (Config.Program.loghelper) {
+        requirePathnameExists("loghelper_program", Config.Program.loghelper->key);
+    }
     if (Config.Program.redirect)
 	requirePathnameExists("redirect_program", Config.Program.redirect->key);
     requirePathnameExists("Icon Directory", Config.icons.directory);
diff -urN squid-2.5.STABLE10/src/cbdata.c squid-2.5.STABLE10-loghelper/src/cbdata.c
--- squid-2.5.STABLE10/src/cbdata.c	2003-07-16 17:18:43.000000000 +1000
+++ squid-2.5.STABLE10-loghelper/src/cbdata.c	2005-08-24 16:00:54.000000000 +1000
@@ -139,6 +139,7 @@
     CREATE_CBDATA(ErrorState);
     CREATE_CBDATA(FwdState);
     CREATE_CBDATA(generic_cbdata);
+    CREATE_CBDATA(LogHelper);
     CREATE_CBDATA(helper);
     CREATE_CBDATA(helper_server);
     CREATE_CBDATA(statefulhelper);
diff -urN squid-2.5.STABLE10/src/cf.data.pre squid-2.5.STABLE10-loghelper/src/cf.data.pre
--- squid-2.5.STABLE10/src/cf.data.pre	2005-05-11 09:08:40.000000000 +1000
+++ squid-2.5.STABLE10-loghelper/src/cf.data.pre	2005-08-26 09:16:50.000000000 +1000
@@ -1220,6 +1220,14 @@
 	Specify the location of the executable for the pinger process.
 DOC_END
 
+NAME: loghelper_program
+TYPE: wordlist
+LOC: Config.Program.loghelper
+DEFAULT: none
+DOC_START
+	Specify the location of the executable for the log helper.
+	If unused logging is to the standard log setup.
+DOC_END
 
 NAME: redirect_program
 TYPE: wordlist
diff -urN squid-2.5.STABLE10/src/enums.h squid-2.5.STABLE10-loghelper/src/enums.h
--- squid-2.5.STABLE10/src/enums.h	2005-03-26 13:50:52.000000000 +1100
+++ squid-2.5.STABLE10-loghelper/src/enums.h	2005-08-24 15:36:04.000000000 +1000
@@ -696,6 +696,7 @@
     CBDATA_ErrorState,
     CBDATA_FwdState,
     CBDATA_generic_cbdata,
+    CBDATA_LogHelper,
     CBDATA_helper,
     CBDATA_helper_server,
     CBDATA_statefulhelper,
diff -urN squid-2.5.STABLE10/src/logHelper.c squid-2.5.STABLE10-loghelper/src/logHelper.c
--- squid-2.5.STABLE10/src/logHelper.c	1970-01-01 11:00:00.000000000 +1100
+++ squid-2.5.STABLE10-loghelper/src/logHelper.c	2005-08-26 15:24:19.000000000 +1000
@@ -0,0 +1,239 @@
+
+/*
+ * $Id: ???
+ *
+ * DEBUG: section ??    LogHelper?
+ * AUTHOR: Matthew Smith
+ *
+ * SQUID Web Proxy Cache          http://www.squid-cache.org/
+ * ----------------------------------------------------------
+ *
+ *  Squid is the result of efforts by numerous individuals from
+ *  the Internet community; see the CONTRIBUTORS file for full
+ *  details.   Many organizations have provided support for Squid's
+ *  development; see the SPONSORS file for full details.  Squid is
+ *  Copyrighted (C) 2001 by the Regents of the University of
+ *  California; see the COPYRIGHT file for full details.  Squid
+ *  incorporates software developed and/or copyrighted by other
+ *  sources; see the CREDITS file for full details.
+ *
+ *  This program is free 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 of the License, or
+ *  (at your option) any later version.
+ *  
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
+ *
+ */
+
+#include "squid.h"
+
+static LogHelper *log_helper = NULL;
+static PF LogHelperFree;
+static PF logHelperHandleRead;
+
+#define HELPER_MAX_ARGS 64
+
+/* ====================================================================== */
+/* LOCAL FUNCTIONS */
+/* ====================================================================== */
+
+static void
+LogHelperFree(int fd, void *data)
+{
+    LogHelper *hlp = data;
+    assert(hlp->rfd == fd);
+    if (hlp->buf) {
+        memFree(hlp->buf, MEM_8K_BUF);
+        hlp->buf = NULL;
+    }
+    if (hlp->wfd != hlp->rfd && hlp->wfd != -1) {
+        comm_close(hlp->wfd);
+    }
+    // what happens if the LogHelper is dieing?
+}
+
+static void
+logHelperHandleRead(int fd, void *data)
+{
+    int len;
+    char *t = NULL;
+    LogHelper *hlp = data;
+    assert(fd == hlp->rfd);
+    //assert(cbdataValid(data));
+    len = FD_READ_METHOD(fd, hlp->buf + hlp->offset, hlp->buf_sz - hlp->offset);
+    fd_bytes(fd, len, FD_READ);
+    /*debug(84, 5) ("logHelperHandleRead: %d bytes from %s #%d.\n",
+        len, hlp->id_name, srv->index + 1);*/
+    if (len <= 0) {
+        if (len < 0)
+            //debug(84, 1) ("logHelperHandleRead: FD %d read: %s\n", fd, xstrerror());
+        comm_close(fd);
+        return;
+    }
+    commSetSelect(hlp->rfd, COMM_SELECT_READ, logHelperHandleRead, hlp, 0);
+    hlp->offset += len;
+    hlp->buf[hlp->offset] = '\0';
+    if ((t = strchr(hlp->buf, '\n'))) {
+        /* end of reply found */
+        //debug(84, 3) ("logHelperHandleRead: end of reply found\n");
+        *t = '\0';
+        hlp->offset = 0;
+        // should we close the wfd?
+        /*if () {
+            int wfd = hlp->wfd;
+            hlp->wfd = -1;
+            comm_close(wfd);
+        }*/
+    }
+}
+
+void
+LogHelperOpen(LogHelper *hlp)
+{
+    char *s;
+    char *progname;
+    char *shortname;
+    char *procname;
+    const char *args[HELPER_MAX_ARGS];
+    char fd_note_buf[FD_DESC_SZ];
+    int nargs = 0;
+    int k = 0;
+    int x;
+    int rfd;
+    int wfd;
+    wordlist *w;
+    if (hlp->cmdline == NULL) {
+        return;
+    }
+    progname = hlp->cmdline->key;
+    if ((s = strrchr(progname, '/'))) {
+        shortname = xstrdup(s + 1);
+    } else {
+        shortname = xstrdup(progname);
+    }
+    procname = xmalloc(strlen(shortname) + 3);
+    snprintf(procname, strlen(shortname) + 3, "(%s)", shortname);
+    args[nargs++] = procname;
+    for (w = hlp->cmdline->next; w && nargs < HELPER_MAX_ARGS; w = w->next) {
+        args[nargs++] = w->key;
+    }
+    args[nargs++] = NULL;
+    assert(nargs <= HELPER_MAX_ARGS);
+    getCurrentTime();
+    rfd = wfd = -1;
+    x = ipcCreate(hlp->ipc_type,
+        progname,
+        args,
+        shortname,
+        &rfd,
+        &wfd);
+    if (x < 0) {
+        debug(84, 1) ("WARNING: Cannot run '%s' process.\n", progname);
+    }
+    hlp->pid = x;
+    hlp->rfd = rfd;
+    hlp->wfd = wfd;
+    hlp->buf = memAllocate(MEM_8K_BUF);
+    hlp->buf_sz = 8192;
+    hlp->offset = 0;
+    if (rfd == wfd) {
+        snprintf(fd_note_buf, FD_DESC_SZ, "%s #%d", shortname, k + 1);
+        fd_note(rfd, fd_note_buf);
+    } else {
+        snprintf(fd_note_buf, FD_DESC_SZ, "reading %s #%d", shortname, k + 1);
+        fd_note(rfd, fd_note_buf);
+        snprintf(fd_note_buf, FD_DESC_SZ, "writing %s #%d", shortname, k + 1);
+        fd_note(wfd, fd_note_buf);
+    }
+
+    //commSetNonBlocking(rfd);
+    //if (wfd != rfd) {
+    //    commSetNonBlocking(wfd);
+    //}
+
+    comm_add_close_handler(rfd, LogHelperFree, hlp);
+    commSetSelect(hlp->rfd, COMM_SELECT_READ, logHelperHandleRead, hlp, 0);
+    safe_free(shortname);
+    safe_free(procname);
+}
+
+/**** PUBLIC FUNCTIONS ****/
+
+// some sort of logThisLine func is needed
+void
+#if STDC_HEADERS
+logHelperStart(const char *fmt,...)
+#else
+logHelperStart(va_alist)
+     va_dcl
+#endif
+{
+    va_list args;
+    char buf[8192];
+    char * msg;
+    int s;
+#if STDC_HEADERS
+    va_start(args, fmt);
+#else
+    const char *fmt;
+    va_start(args);
+    fmt = va_arg(args, char *);
+#endif
+    s = vsnprintf(buf, 8192, fmt, args);
+    if (s > 8192) {
+        s = 8192;
+        if (fmt[strlen(fmt) - 1] == '\n') {
+            buf[8191] = '\n';
+        }
+    }
+
+    msg = xstrdup(buf);
+    comm_write(log_helper->wfd,
+        msg,
+        strlen(msg),
+        NULL,           /* Handler */
+        NULL,           /* Handler-data */
+        NULL);          /* free */
+    va_end(args);
+}
+
+void
+logHelperInit(void)
+{
+    if (!Config.Program.loghelper) {
+        return;
+    }
+    if (log_helper == NULL) {
+        log_helper = cbdataAlloc(LogHelper);
+    }
+    log_helper->cmdline = Config.Program.loghelper;
+    log_helper->ipc_type = IPC_TCP_SOCKET;
+    LogHelperOpen(log_helper);
+    debug(84, 1) ("logHelper Initialised\n");
+}
+
+void
+logHelperShutdown(void)
+{
+    int wfd;
+
+    if (!log_helper) {
+        return;
+    }
+
+    wfd = log_helper->wfd;
+    log_helper->wfd = -1;
+    comm_close(wfd);
+
+    cbdataFree(log_helper);
+    log_helper = NULL;
+    debug(84, 1) ("LogHelper has Shutdown\n");
+}
diff -urN squid-2.5.STABLE10/src/main.c squid-2.5.STABLE10-loghelper/src/main.c
--- squid-2.5.STABLE10/src/main.c	2005-04-21 07:52:26.000000000 +1000
+++ squid-2.5.STABLE10-loghelper/src/main.c	2005-08-24 15:36:04.000000000 +1000
@@ -354,6 +354,7 @@
     redirectShutdown();
     authenticateShutdown();
     externalAclShutdown();
+    logHelperShutdown();
     storeDirCloseSwapLogs();
     storeLogClose();
     accessLogClose();
@@ -381,6 +382,7 @@
     redirectInit();
     authenticateInit(&Config.authConfig);
     externalAclInit();
+    logHelperInit();
 #if USE_WCCP
     wccpInit();
 #endif
@@ -409,6 +411,7 @@
     redirectShutdown();
     authenticateShutdown();
     externalAclShutdown();
+    logHelperShutdown();
     _db_rotate_log();		/* cache.log */
     storeDirWriteCleanLogs(1);
     storeLogRotate();		/* store.log */
@@ -425,6 +428,7 @@
     redirectInit();
     authenticateInit(&Config.authConfig);
     externalAclInit();
+    logHelperInit();
 }
 
 static void
@@ -510,6 +514,7 @@
     redirectInit();
     authenticateInit(&Config.authConfig);
     externalAclInit();
+    logHelperInit();
     useragentOpenLog();
     refererOpenLog();
     httpHeaderInitModule();	/* must go before any header processing (e.g. the one in errorInitialize) */
@@ -962,6 +967,7 @@
 #endif
     redirectShutdown();
     externalAclShutdown();
+    logHelperShutdown();
     icpConnectionClose();
 #if USE_HTCP
     htcpSocketClose();
diff -urN squid-2.5.STABLE10/src/Makefile.am squid-2.5.STABLE10-loghelper/src/Makefile.am
--- squid-2.5.STABLE10/src/Makefile.am	2005-04-23 11:32:27.000000000 +1000
+++ squid-2.5.STABLE10-loghelper/src/Makefile.am	2005-08-24 15:36:04.000000000 +1000
@@ -174,6 +174,7 @@
 	peer_select.c \
 	protos.h \
 	redirect.c \
+	logHelper.c \
 	referer.c \
 	refresh.c \
 	send-announce.c \
diff -urN squid-2.5.STABLE10/src/Makefile.in squid-2.5.STABLE10-loghelper/src/Makefile.in
--- squid-2.5.STABLE10/src/Makefile.in	2005-04-24 10:12:08.000000000 +1000
+++ squid-2.5.STABLE10-loghelper/src/Makefile.in	2005-08-24 15:36:04.000000000 +1000
@@ -270,6 +270,7 @@
 	peer_select.c \
 	protos.h \
 	redirect.c \
+	logHelper.c \
 	referer.c \
 	refresh.c \
 	send-announce.c \
@@ -500,7 +501,7 @@
 	MemPool.$(OBJEXT) MemBuf.$(OBJEXT) mime.$(OBJEXT) \
 	multicast.$(OBJEXT) neighbors.$(OBJEXT) net_db.$(OBJEXT) \
 	Packer.$(OBJEXT) pconn.$(OBJEXT) peer_digest.$(OBJEXT) \
-	peer_select.$(OBJEXT) redirect.$(OBJEXT) referer.$(OBJEXT) \
+	peer_select.$(OBJEXT) redirect.$(OBJEXT) logHelper.$(OBJEXT)  referer.$(OBJEXT) \
 	refresh.$(OBJEXT) send-announce.$(OBJEXT) $(am__objects_7) \
 	ssl.$(OBJEXT) $(am__objects_8) stat.$(OBJEXT) \
 	StatHist.$(OBJEXT) String.$(OBJEXT) stmem.$(OBJEXT) \
diff -urN squid-2.5.STABLE10/src/protos.h squid-2.5.STABLE10-loghelper/src/protos.h
--- squid-2.5.STABLE10/src/protos.h	2005-04-20 08:19:27.000000000 +1000
+++ squid-2.5.STABLE10-loghelper/src/protos.h	2005-08-25 10:51:03.000000000 +1000
@@ -725,6 +725,16 @@
 extern void redirectInit(void);
 extern void redirectShutdown(void);
 
+#if STDC_HEADERS
+extern void
+logHelperStart(const char *fmt,...) PRINTF_FORMAT_ARG1;
+#else
+extern void logHelperStart(va_alist);
+#endif
+
+extern void logHelperInit(void);
+extern void logHelperShutdown(void);
+
 /* auth_modules.c */
 extern void authSchemeSetup(void);
 
diff -urN squid-2.5.STABLE10/src/structs.h squid-2.5.STABLE10-loghelper/src/structs.h
--- squid-2.5.STABLE10/src/structs.h	2005-05-05 04:03:47.000000000 +1000
+++ squid-2.5.STABLE10-loghelper/src/structs.h	2005-08-26 09:19:46.000000000 +1000
@@ -487,6 +487,7 @@
 	char *dnsserver;
 #endif
 	wordlist *redirect;
+	wordlist *loghelper;
 #if USE_ICMP
 	char *pinger;
 #endif
@@ -2025,6 +2026,16 @@
 
 #endif
 
+struct _LogHelper {
+    wordlist *cmdline;
+    int ipc_type;
+    int pid;
+    int rfd;
+    int wfd;
+    char *buf;
+    size_t buf_sz;
+    int offset;
+};
 
 struct _helper_request {
     char *buf;
diff -urN squid-2.5.STABLE10/src/typedefs.h squid-2.5.STABLE10-loghelper/src/typedefs.h
--- squid-2.5.STABLE10/src/typedefs.h	2005-03-27 10:20:13.000000000 +1000
+++ squid-2.5.STABLE10-loghelper/src/typedefs.h	2005-08-24 15:36:04.000000000 +1000
@@ -194,6 +194,7 @@
 typedef struct _Version Version;
 typedef struct _FwdState FwdState;
 typedef struct _FwdServer FwdServer;
+typedef struct _LogHelper LogHelper;
 typedef struct _helper helper;
 typedef struct _helper_stateful statefulhelper;
 typedef struct _helper_server helper_server;

