#include "icp_opcode.h"
#include "ip/Address.h"
#include "LogTags.h"
+#include "MessageCounters.h"
#include "Notes.h"
#if ICAP_CLIENT
#include "adaptation/icap/Elements.h"
public:
HttpDetails() : method(Http::METHOD_NONE), code(0), content_type(NULL),
- timedout(false), aborted(false) {}
+ timedout(false),
+ aborted(false),
+ clientRequest()
+ {}
HttpRequestMethod method;
int code;
const char *statusSfx() const {
return timedout ? "_TIMEDOUT" : (aborted ? "_ABORTED" : "");
}
+
+ /// counters for the original request received from client
+ // TODO calculate header and payload better (by parser)
+ // XXX payload encoding overheads not calculated at all yet.
+ MessageCounters clientRequest;
+
+ /// counters for the response sent to client
+ // TODO calculate header and payload better (by parser)
+ // XXX payload encoding overheads not calculated at all yet.
+ MessageCounters adaptedReply;
+
} http;
/** \brief This subclass holds log info for ICP protocol
public:
CacheDetails() : caddr(),
- requestSize(0),
- replySize(0),
- requestHeadersSize(0),
- replyHeadersSize(0),
highOffset(0),
objectSize(0),
code (LOG_TAG_NONE),
}
Ip::Address caddr;
- int64_t requestSize;
- int64_t replySize;
- int requestHeadersSize; ///< received, including request line
- int replyHeadersSize; ///< sent, including status line
int64_t highOffset;
int64_t objectSize;
LogTags code;
MemBuf.cc \
MemObject.cc \
MemObject.h \
+ MessageCounters.h \
mime.h \
mime.cc \
mime_header.h \
--- /dev/null
+#ifndef SQUID_SRC_MESSAGECOUNTERS_H
+#define SQUID_SRC_MESSAGECOUNTERS_H
+
+/**
+ * Counters used to collate the traffic size measurements
+ * for a transaction message.
+ */
+class MessageCounters
+{
+public:
+ MessageCounters() : headerSz(0), payloadDataSz(0), payloadTeSz(0) {}
+
+ /// size of message header block (if any)
+ uint64_t headerSz;
+
+ /// total size of payload block(s) excluding transfer encoding overheads
+ uint64_t payloadDataSz;
+
+ /// total size of extra bytes added by transfer encoding
+ uint64_t payloadTeSz;
+
+ // total message size
+ uint64_t total() const {return headerSz + payloadDataSz + payloadTeSz;}
+
+ /// total payload size including transfer encoding overheads
+ uint64_t payloadTotal() const {return payloadDataSz + payloadTeSz;}
+};
+
+#endif /* SQUID_SRC_MESSAGECOUNTERS_H */
al.cache.ssluser = h->ssluser.termedBuf();
#endif
al.cache.code = h->logType;
- al.cache.requestSize = h->req_sz;
+ // XXX: should use icap-specific counters instead ?
+ al.http.clientRequest.payloadDataSz = h->req_sz;
// leave al.icap.bodyBytesRead negative if no body
if (replyHttpHeaderSize >= 0 || replyHttpBodySize >= 0) {
al.http.code = reply_->sline.status();
al.http.content_type = reply_->content_type.termedBuf();
if (replyHttpBodySize >= 0) {
- al.cache.replySize = replyHttpBodySize + reply_->hdr_sz;
+ // XXX: should use icap-specific counters instead ?
+ al.http.adaptedReply.payloadDataSz = replyHttpBodySize;
+ al.http.adaptedReply.headerSz = reply_->hdr_sz;
al.cache.highOffset = replyHttpBodySize;
}
//don't set al.cache.objectSize because it hasn't exist yet
HTTP related format codes:
+ REQUEST
+
+ [http::]rm Request method (GET/POST etc)
+ [http::]>rm Request method from client
+ [http::]<rm Request method sent to server or peer
+ [http::]ru Request URL from client (historic, filtered for logging)
+ [http::]>ru Request URL from client
+ [http::]<ru Request URL sent to server or peer
+ [http::]rp Request URL-Path excluding hostname
+ [http::]>rp Request URL-Path excluding hostname from client
+ [http::]<rp Request URL-Path excluding hostname sent to server or peer
+ [http::]rv Request protocol version
+ [http::]>rv Request protocol version from client
+ [http::]<rv Request protocol version sent to server or peer
+
[http::]>h Original received request header.
Usually differs from the request header sent by
Squid, although most fields are often preserved.
Usually differs from the request header sent by
Squid, although most fields are often preserved.
Optional header name argument as for >h
+
+
+ RESPONSE
+
+ [http::]<Hs HTTP status code received from the next hop
+ [http::]>Hs HTTP status code sent to the client
+
[http::]<h Reply header. Optional header name argument
as for >h
- [http::]>Hs HTTP status code sent to the client
- [http::]<Hs HTTP status code received from the next hop
+
+ [http::]mt MIME content type
+
+
+ SIZE COUNTERS
+
+ [http::]st Total size of request + reply traffic with client
+ [http::]>st Total size of request received from client.
+ Excluding chunked encoding bytes.
+ [http::]<st Total size of reply sent to client (after adaptation)
+
+ [http::]>sh Size of request headers received from client
+ [http::]<sh Size of reply headers sent to client (after adaptation)
+
+ [http::]<sH Reply high offset sent
+ [http::]<sS Upstream object size
+
[http::]<bs Number of HTTP-equivalent message body bytes
received from the next hop, excluding chunked
transfer encoding and control messages.
Generated FTP/Gopher listings are treated as
received bodies.
- [http::]mt MIME content type
- [http::]rm Request method (GET/POST etc)
- [http::]>rm Request method from client
- [http::]<rm Request method sent to server or peer
- [http::]ru Request URL from client (historic, filtered for logging)
- [http::]>ru Request URL from client
- [http::]<ru Request URL sent to server or peer
- [http::]rp Request URL-Path excluding hostname
- [http::]>rp Request URL-Path excluding hostname from client
- [http::]<rp Request URL-Path excluding hostname sento to server or peer
- [http::]rv Request protocol version
- [http::]>rv Request protocol version from client
- [http::]<rv Request protocol version sent to server or peer
- [http::]<st Sent reply size including HTTP headers
- [http::]>st Received request size including HTTP headers. In the
- case of chunked requests the chunked encoding metadata
- are not included
- [http::]>sh Received HTTP request headers size
- [http::]<sh Sent HTTP reply headers size
- [http::]st Request+Reply size including HTTP headers
- [http::]<sH Reply high offset sent
- [http::]<sS Upstream object size
+
+
+ TIMING
+
[http::]<pt Peer response time in milliseconds. The timer starts
when the last request byte is sent to the next hop
and stops when the last response byte is received.
aLogEntry->http.version = request->http_ver;
aLogEntry->hier = request->hier;
if (request->content_length > 0) // negative when no body or unknown length
- aLogEntry->cache.requestSize += request->content_length;
+ aLogEntry->http.clientRequest.payloadDataSz += request->content_length; // XXX: actually adaptedRequest payload size ??
aLogEntry->cache.extuser = request->extacl_user.termedBuf();
// Adapted request, if any, inherits and then collects all the stats, but
debugs(33, 9, "clientLogRequest: http.code='" << al->http.code << "'");
if (loggingEntry() && loggingEntry()->mem_obj)
- al->cache.objectSize = loggingEntry()->contentLen();
+ al->cache.objectSize = loggingEntry()->contentLen(); // payload duplicate ?? with or without TE ?
al->cache.caddr.setNoAddr();
al->cache.port = cbdataReference(getConn()->port);
}
- al->cache.requestSize = req_sz;
- al->cache.requestHeadersSize = req_sz;
-
- al->cache.replySize = out.size;
- al->cache.replyHeadersSize = out.headers_sz;
+ al->http.clientRequest.headerSz = req_sz;
+ al->http.adaptedReply.headerSz = out.headers_sz;
+ // XXX: calculate without payload encoding or headers !!
+ al->http.adaptedReply.payloadDataSz = out.size - out.headers_sz; // pretend its all un-encoded data for now.
al->cache.highOffset = out.offset;
LFT_SERVER_REQ_VERSION,
/* request meta details */
- LFT_REQUEST_SIZE_TOTAL,
- /*LFT_REQUEST_SIZE_LINE, */
- LFT_REQUEST_SIZE_HEADERS,
+ LFT_CLIENT_REQUEST_SIZE_TOTAL,
+ LFT_CLIENT_REQUEST_SIZE_HEADERS,
/*LFT_REQUEST_SIZE_BODY, */
/*LFT_REQUEST_SIZE_BODY_NO_TE, */
/* LFT_ADAPTED_REPLY_ALL_HEADERS, */
/* response meta details */
- LFT_REPLY_SIZE_TOTAL,
+ LFT_ADAPTED_REPLY_SIZE_TOTAL,
LFT_REPLY_HIGHOFFSET,
LFT_REPLY_OBJECTSIZE,
- /*LFT_REPLY_SIZE_LINE, */
- LFT_REPLY_SIZE_HEADERS,
+ LFT_ADAPTED_REPLY_SIZE_HEADERS,
/*LFT_REPLY_SIZE_BODY, */
/*LFT_REPLY_SIZE_BODY_NO_TE, */
+ LFT_CLIENT_IO_SIZE_TOTAL,
+
/* client credentials */
LFT_USER_NAME, /* any source will do */
LFT_USER_LOGIN,
LFT_MIME_TYPE,
LFT_TAG,
- LFT_IO_SIZE_TOTAL,
LFT_EXT_LOG,
LFT_SEQUENCE_NUMBER,
}
break;
- case LFT_REQUEST_SIZE_TOTAL:
- outoff = al->cache.requestSize;
+ case LFT_CLIENT_REQUEST_SIZE_TOTAL:
+ outoff = al->http.clientRequest.total();
dooff = 1;
break;
- /*case LFT_REQUEST_SIZE_LINE: */
- case LFT_REQUEST_SIZE_HEADERS:
- outoff = al->cache.requestHeadersSize;
+ case LFT_CLIENT_REQUEST_SIZE_HEADERS:
+ outoff = al->http.clientRequest.headerSz;
dooff =1;
break;
+
/*case LFT_REQUEST_SIZE_BODY: */
/*case LFT_REQUEST_SIZE_BODY_NO_TE: */
- case LFT_REPLY_SIZE_TOTAL:
- outoff = al->cache.replySize;
+ case LFT_ADAPTED_REPLY_SIZE_TOTAL:
+ outoff = al->http.adaptedReply.total();
dooff = 1;
break;
break;
- /*case LFT_REPLY_SIZE_LINE: */
- case LFT_REPLY_SIZE_HEADERS:
- outint = al->cache.replyHeadersSize;
+ case LFT_ADAPTED_REPLY_SIZE_HEADERS:
+ outint = al->http.adaptedReply.headerSz;
doint = 1;
break;
+
/*case LFT_REPLY_SIZE_BODY: */
/*case LFT_REPLY_SIZE_BODY_NO_TE: */
+ case LFT_CLIENT_IO_SIZE_TOTAL:
+ outint = al->http.clientRequest.total() + al->http.adaptedReply.total();
+ doint = 1;
+ break;
+ /*case LFT_SERVER_IO_SIZE_TOTAL: */
+
case LFT_TAG:
if (al->request)
out = al->request->tag.termedBuf();
break;
- case LFT_IO_SIZE_TOTAL:
- outint = al->cache.requestSize + al->cache.replySize;
- doint = 1;
- break;
-
case LFT_EXT_LOG:
if (al->request)
out = al->request->extacl_log.termedBuf();
/*{"<rq", LFT_SERVER_REQ_QUERY},*/
{"<rv", LFT_SERVER_REQ_VERSION},
- {">st", LFT_REQUEST_SIZE_TOTAL },
- /*{ ">sl", LFT_REQUEST_SIZE_LINE }, * / / * the request line "GET ... " */
- {">sh", LFT_REQUEST_SIZE_HEADERS },
+ {">st", LFT_CLIENT_REQUEST_SIZE_TOTAL },
+ {">sh", LFT_CLIENT_REQUEST_SIZE_HEADERS },
/*{ ">sb", LFT_REQUEST_SIZE_BODY }, */
/*{ ">sB", LFT_REQUEST_SIZE_BODY_NO_TE }, */
- {"<st", LFT_REPLY_SIZE_TOTAL},
+ {"<st", LFT_ADAPTED_REPLY_SIZE_TOTAL}, // XXX: adapted should be code: <sta
{"<sH", LFT_REPLY_HIGHOFFSET},
{"<sS", LFT_REPLY_OBJECTSIZE},
- /*{ "<sl", LFT_REPLY_SIZE_LINE }, * / / * the reply line (protocol, code, text) */
- {"<sh", LFT_REPLY_SIZE_HEADERS },
+ {"<sh", LFT_ADAPTED_REPLY_SIZE_HEADERS }, // XXX: adapted should be code: <sha
/*{ "<sb", LFT_REPLY_SIZE_BODY }, */
/*{ "<sB", LFT_REPLY_SIZE_BODY_NO_TE }, */
+ {"st", LFT_CLIENT_IO_SIZE_TOTAL}, // XXX: total from client should be stC ??
+ /*{"stP", LFT_SERVER_IO_SIZE_TOTAL},*/
+
{"et", LFT_TAG},
- {"st", LFT_IO_SIZE_TOTAL},
{"ea", LFT_EXT_LOG},
{"sn", LFT_SEQUENCE_NUMBER},
al->cache.caddr = caddr;
- al->cache.replySize = len;
+ // XXX: move to use icp.clientReply instead
+ al->http.adaptedReply.payloadDataSz = len;
al->cache.code = logcode;
AnyP::ProtocolType_str[al->http.version.protocol],
al->http.version.major, al->http.version.minor,
al->http.code,
- al->cache.replySize,
+ al->http.adaptedReply.total(),
referer,
agent,
LogTags_str[al->cache.code],
AnyP::ProtocolType_str[al->http.version.protocol],
al->http.version.major, al->http.version.minor,
al->http.code,
- al->cache.replySize,
+ al->http.adaptedReply.total(),
LogTags_str[al->cache.code],
al->http.statusSfx(),
hier_code_str[al->hier.code],
LogTags_str[al->cache.code],
al->http.statusSfx(),
al->http.code,
- al->cache.replySize,
+ al->http.adaptedReply.total(),
al->_private.method_str,
al->url,
user ? user : dash_str,