#include "squid.h"
#include "MasterXaction.h"
-InstanceIdDefinitions(MasterXaction, "MXID_");
+InstanceIdDefinitions(MasterXaction, "master", uint64_t);
explicit MasterXaction(const XactionInitiator anInitiator) : initiator(anInitiator) {};
/// transaction ID.
- InstanceId<MasterXaction> id;
+ InstanceId<MasterXaction, uint64_t> id;
/// the listening port which originated this transaction
AnyP::PortCfgPointer squidPort;
#include <iosfwd>
+typedef unsigned int InstanceIdDefaultValueType;
/** Identifier for class instances
* - unique IDs for a large number of concurrent instances, but may wrap;
* - useful for debugging and insecure request/response matching;
* - sequential IDs within a class except when wrapping;
* - always positive IDs.
- * \todo: add storage type parameter to support configurable Value types?
* \todo: add creation/destruction debugging?
*/
-template <class Class>
+template <class Class, class ValueType = InstanceIdDefaultValueType>
class InstanceId
{
public:
- typedef unsigned int Value; ///< id storage type; \todo: parameterize?
+ typedef ValueType Value; ///< id storage type
InstanceId() {change();}
const char * prefix() const;
public:
- Value value = 0; ///< instance identifier
+ Value value = Value(); ///< instance identifier
private:
InstanceId(const InstanceId &); ///< not implemented; IDs are unique
InstanceId& operator=(const InstanceId &); ///< not implemented
};
-/// convenience macro to instantiate Class-specific stuff in .cc files
-#define InstanceIdDefinitions(Class, pfx) \
+/// An InstanceIdDefinitions() helper. Avoid direct use.
+#define InstanceIdDefinitions3(Class, pfx, ValueType, ...) \
template<> const char * \
- InstanceId<Class>::prefix() const { \
+ InstanceId<Class, ValueType>::prefix() const { \
return pfx; \
} \
template<> std::ostream & \
- InstanceId<Class>::print(std::ostream &os) const { \
+ InstanceId<Class, ValueType>::print(std::ostream &os) const { \
return os << pfx << value; \
} \
template<> void \
- InstanceId<Class>::change() { \
- static InstanceId<Class>::Value Last = 0; \
+ InstanceId<Class, ValueType>::change() { \
+ static auto Last = Value(); \
value = ++Last ? Last : ++Last; \
}
+/// convenience macro to instantiate Class-specific stuff in .cc files
+#define InstanceIdDefinitions(...) InstanceIdDefinitions3(__VA_ARGS__, InstanceIdDefaultValueType)
+
/// print the id
-template <class Class>
+template <class Class, class ValueType>
inline
-std::ostream &operator <<(std::ostream &os, const InstanceId<Class> &id)
+std::ostream &operator <<(std::ostream &os, const InstanceId<Class, ValueType> &id)
{
return id.print(os);
}
individual notes. There is currently no way to
specify both value and notes separators when logging
all notes with %note.
+ master_xaction The master transaction identifier is an unsigned
+ integer. These IDs are guaranteed to monotonically
+ increase within a single worker process lifetime, with
+ higher values corresponding to transactions that were
+ accepted or initiated later. Due to current implementation
+ deficiencies, some IDs are skipped (i.e. never logged).
+ Concurrent workers and restarted workers use similar,
+ overlapping sequences of master transaction IDs.
Connection related format codes:
LFT_NOTE,
LFT_PERCENT, /* special string cases for escaped chars */
+ LFT_MASTER_XACTION,
// TODO assign better bytecode names and Token strings for these
#if USE_OPENSSL
#include "MemBuf.h"
#include "proxyp/Header.h"
#include "rfc1738.h"
+#include "sbuf/Stream.h"
#include "sbuf/StringConvert.h"
#include "security/CertError.h"
#include "security/NegotiationHistory.h"
struct timeval outtv = {0, 0};
int doMsec = 0;
int doSec = 0;
+ bool doUint64 = false;
+ uint64_t outUint64 = 0;
switch (fmt->type) {
if (!al->lastAclData.isEmpty())
out = al->lastAclData.c_str();
break;
+
+ case LFT_MASTER_XACTION:
+ if (al->request) {
+ doUint64 = true;
+ outUint64 = static_cast<uint64_t>(al->request->masterXaction->id.value);
+ break;
+ }
}
if (dooff) {
} else if (doint) {
sb.appendf("%0*ld", fmt->zero && fmt->widthMin >= 0 ? fmt->widthMin : 0, outint);
out = sb.c_str();
+ } else if (doUint64) {
+ sb.appendf("%0*" PRIu64, fmt->zero && fmt->widthMin >= 0 ? fmt->widthMin : 0, outUint64);
+ out = sb.c_str();
} else if (doMsec) {
if (fmt->widthMax < 0) {
sb.appendf("%0*ld", fmt->zero && fmt->widthMin >= 0 ? fmt->widthMin : 0, tvToMsec(outtv));
}
// enforce width limits if configured
- const bool haveMaxWidth = fmt->widthMax >=0 && !doint && !dooff && !doMsec && !doSec;
+ const bool haveMaxWidth = fmt->widthMax >=0 && !doint && !dooff && !doMsec && !doSec && !doUint64;
if (haveMaxWidth || fmt->widthMin) {
const int minWidth = fmt->widthMin >= 0 ?
fmt->widthMin :0;
TokenTableEntry("err_detail", LFT_SQUID_ERROR_DETAIL ),
TokenTableEntry("note", LFT_NOTE ),
TokenTableEntry("credentials", LFT_CREDENTIALS),
+ TokenTableEntry("master_xaction", LFT_MASTER_XACTION),
/*
* Legacy external_acl_type format tokens
*/