Added %err_code and %err_detail logformat codes to record details about transaction failures. For example, when Squid responds with 500 Internal Server Error, it is often useful to know what went wrong. === modified file 'src/HttpRequest.cc' --- src/HttpRequest.cc 2009-04-28 23:00:49 +0000 +++ src/HttpRequest.cc 2010-06-29 22:22:34 +0000 @@ -89,6 +89,7 @@ body_pipe = NULL; // hier errType = ERR_NONE; + errDetail = ERR_DETAIL_NONE; peer_login = NULL; // not allocated/deallocated by this class peer_domain = NULL; // not allocated/deallocated by this class vary_headers = NULL; === modified file 'src/HttpRequest.h' --- src/HttpRequest.h 2009-04-28 23:00:49 +0000 +++ src/HttpRequest.h 2010-06-29 19:36:35 +0000 @@ -117,6 +117,7 @@ HierarchyLogEntry hier; err_type errType; + int errDetail; ///< errType-specific detail about the transaction error char *peer_login; /* Configured peer login:password */ === modified file 'src/Server.cc' --- src/Server.cc 2009-04-28 23:00:49 +0000 +++ src/Server.cc 2010-06-29 22:28:50 +0000 @@ -630,10 +630,14 @@ debugs(11,9, HERE << "creating ICAP error entry after ICAP failure"); ErrorState *err = errorCon(ERR_ICAP_FAILURE, HTTP_INTERNAL_SERVER_ERROR, request); - err->xerrno = errno; + err->xerrno = ERR_DETAIL_ICAP_RESPMOD_EARLY; fwd->fail(err); fwd->dontRetry(true); } + else if (request) { // update logged info + request->errType = ERR_ICAP_FAILURE; + request->errDetail = ERR_DETAIL_ICAP_RESPMOD_LATE; + } abortTransaction("ICAP failure"); } @@ -660,7 +664,7 @@ // handle start failure for an essential ICAP service ErrorState *err = errorCon(ERR_ICAP_FAILURE, HTTP_INTERNAL_SERVER_ERROR, originalRequest()); - err->xerrno = errno; + err->xerrno = ERR_DETAIL_ICAP_RESPMOD_START; errorAppendEntry(entry, err); abortTransaction("ICAP start failure"); return; === modified file 'src/access_log.cc' --- src/access_log.cc 2010-05-13 04:20:47 +0000 +++ src/access_log.cc 2010-06-29 21:58:23 +0000 @@ -41,6 +41,7 @@ #include "Store.h" #include "ACLChecklist.h" +#include "errorpage.h" #include "HttpReply.h" #include "HttpRequest.h" @@ -367,7 +368,8 @@ /*LFT_HTTP_STATUS, */ LFT_SQUID_STATUS, - /*LFT_SQUID_ERROR, */ + LFT_SQUID_ERROR, + LFT_SQUID_ERROR_DETAIL, LFT_SQUID_HIERARCHY, LFT_MIME_TYPE, @@ -520,7 +522,8 @@ /*{ "Ht", LFT_HTTP_STATUS }, */ {"Ss", LFT_SQUID_STATUS}, - /*{ "Se", LFT_SQUID_ERROR }, */ + {"err_code", LFT_SQUID_ERROR }, + {"err_detail", LFT_SQUID_ERROR_DETAIL }, {"Sh", LFT_SQUID_HIERARCHY}, {"mt", LFT_MIME_TYPE}, @@ -991,7 +994,17 @@ break; - /* case LFT_SQUID_ERROR: */ + case LFT_SQUID_ERROR: + if (al->request && al->request->errType != ERR_NONE) + out = errorPageName(al->request->errType); + break; + + case LFT_SQUID_ERROR_DETAIL: + if (al->request && al->request->errDetail >= 0) { + outint = al->request->errDetail; + doint = 1; + } + break; case LFT_SQUID_HIERARCHY: if (al->hier.ping.timedout) === modified file 'src/cf.data.pre' --- src/cf.data.pre 2010-05-13 04:20:47 +0000 +++ src/cf.data.pre 2010-06-29 23:19:12 +0000 @@ -2042,6 +2042,9 @@ starts with the first connect request (or write I/O) sent to the first selected peer. The timer stops with the last I/O with the last peer. + err_code The ID of an error response served by Squid or + a similar internal error identifier. + err_detail Additional err_code-dependent error information. % a literal % character If ICAP is enabled, the following two codes become available (as === modified file 'src/client_side_request.cc' --- src/client_side_request.cc 2009-04-28 23:00:49 +0000 +++ src/client_side_request.cc 2010-06-29 22:28:50 +0000 @@ -1258,6 +1258,9 @@ (c != NULL && c->auth_user_request ? c->auth_user_request : request->auth_user_request)); + if (request->errDetail < 0) + request->errDetail = ERR_DETAIL_ICAP_REQMOD; + node = (clientStreamNode *)client_stream.tail->data; clientStreamRead(node, this, node->readBuffer); } === modified file 'src/enums.h' --- src/enums.h 2009-04-28 23:00:49 +0000 +++ src/enums.h 2010-06-29 22:32:39 +0000 @@ -100,6 +100,16 @@ ERR_MAX } err_type; +typedef enum { + ERR_DETAIL_NONE = -1, + ERR_DETAIL_START = 100000, // to avoid clashes with most OS error numbers + ERR_DETAIL_ICAP_REQMOD, // ICAP REQMOD failure + ERR_DETAIL_ICAP_RESPMOD_START, // ICAP RESPMOD failed to start + ERR_DETAIL_ICAP_RESPMOD_EARLY, // ICAP RESPMOD failed w/o store entry + ERR_DETAIL_ICAP_RESPMOD_LATE, // ICAP RESPMOD failed with a store entry + ERR_DETAIL_MAX +} err_detail_type; + enum fd_type { FD_NONE, FD_LOG, === modified file 'src/errorpage.cc' --- src/errorpage.cc 2008-07-12 12:24:42 +0000 +++ src/errorpage.cc 2010-06-29 21:04:24 +0000 @@ -303,7 +303,7 @@ return (err_type)id; } -static const char * +const char * errorPageName(int pageId) { if (pageId >= ERR_NONE && pageId < ERR_MAX) /* common case */ @@ -331,6 +331,7 @@ if (request != NULL) { err->request = HTTPMSGLOCK(request); err->src_addr = request->client_addr; + request->errType = type; } return err; === modified file 'src/errorpage.h' --- src/errorpage.h 2007-05-09 13:45:58 +0000 +++ src/errorpage.h 2010-06-29 21:05:17 +0000 @@ -92,6 +92,7 @@ SQUIDCEXTERN void errorStateFree(ErrorState * err); SQUIDCEXTERN err_type errorReservePageId(const char *page_name); SQUIDCEXTERN ErrorState *errorCon(err_type type, http_status, HttpRequest * request); +SQUIDCEXTERN const char *errorPageName(int pageId); ///< error ID to string #endif /* SQUID_ERRORPAGE_H */ === modified file 'src/forward.cc' --- src/forward.cc 2010-05-13 04:24:52 +0000 +++ src/forward.cc 2010-06-29 19:45:29 +0000 @@ -296,6 +296,10 @@ if (!errorState->request) errorState->request = HTTPMSGLOCK(request); + + request->errType = errorState->type; + if (request->errDetail < 0) + request->errDetail = errorState->xerrno; } /* === modified file 'src/ftp.cc' --- src/ftp.cc 2009-02-08 09:47:46 +0000 +++ src/ftp.cc 2010-06-29 22:01:28 +0000 @@ -3135,6 +3135,9 @@ http_code = HTTP_INTERNAL_SERVER_ERROR; } + if (ftpState->request) + ftpState->request->errDetail = code; + err = errorCon(err_code, http_code, ftpState->request); if (ftpState->old_request)