/* Web Polygraph http://www.web-polygraph.org/ * (C) 2003-2006 The Measurement Factory * Licensed under the Apache License, Version 2.0 */ #include "base/polygraph.h" #include "xstd/h/math.h" #include "xstd/h/iostream.h" #include "xstd/h/iomanip.h" #include "xstd/Socket.h" #include "xstd/Ssl.h" #include "base/ILog.h" #include "base/OLog.h" #include "base/StatIntvlRec.h" #include "xstd/gadgets.h" EmbedStats TheEmbedStats; StatIntvlRec::StatIntvlRec(): theXactCnt(0), theXactErrCnt(0), theXactRetrCnt(0) { } void StatIntvlRec::restart() { thePopulusLvl.restart(); theWaitLvl.restart(); theXactLvl.restart(); theOpenLvl.restart(); theEstbLvl.restart(); theConnLifeTm.reset(); theConnUseCnt.reset(); theConnPipelineDepth.reset(); theIdealHR.reset(); theRealHR.reset(); theChbR.reset(); theFill.reset(); theRediredReq.reset(); theRepToRedir.reset(); theIms.reset(); theReload.reset(); theHead.reset(); thePost.reset(); thePut.reset(); theAbort.reset(); thePage.reset(); theXactCnt = theXactErrCnt = theXactRetrCnt = 0; theIcpStat.reset(); theSslStat.restart(); theDuration = Time(); } OLog &StatIntvlRec::store(OLog &log) const { Assert(theDuration >= 0); return log << thePopulusLvl << theWaitLvl << theXactLvl << theOpenLvl << theEstbLvl << theConnLifeTm << theConnUseCnt << theIdealHR << theRealHR << theChbR << theFill << theRediredReq << theRepToRedir << theIms << theReload << theHead << thePost << thePut << theAbort << thePage << theXactCnt << theXactErrCnt << theXactRetrCnt << theIcpStat << theSslStat << theDuration << theConnPipelineDepth ; } ILog &StatIntvlRec::load(ILog &log) { return log >> thePopulusLvl >> theWaitLvl >> theXactLvl >> theOpenLvl >> theEstbLvl >> theConnLifeTm >> theConnUseCnt >> theIdealHR >> theRealHR >> theChbR >> theFill >> theRediredReq >> theRepToRedir >> theIms >> theReload >> theHead >> thePost >> thePut >> theAbort >> thePage >> theXactCnt >> theXactErrCnt >> theXactRetrCnt >> theIcpStat >> theSslStat >> theDuration >> theConnPipelineDepth ; } bool StatIntvlRec::sane() const { return thePopulusLvl.sane() && theWaitLvl.sane() && theXactLvl.sane() && theOpenLvl.sane() && theEstbLvl.sane() && theConnLifeTm.sane() && theConnUseCnt.sane() && theConnPipelineDepth.sane() && theRediredReq.sane() && theReload.sane() && theHead.sane() && thePost.sane() && thePut.sane() && theAbort.sane() && thePage.sane() && theSslStat.sane() && theIcpStat.sane() && theXactCnt >= 0 && theXactErrCnt >= 0 && theXactRetrCnt >= 0 && theDuration >= 0; } BigSize StatIntvlRec::totFillSize() const { return BigSize::Byted(theFill.size().sum()); } int StatIntvlRec::totFillCount() const { return theFill.size().count(); } double StatIntvlRec::errRatio() const { return Ratio(theXactErrCnt, xactCnt()); } double StatIntvlRec::errPercent() const { return Percent(theXactErrCnt, xactCnt()); } // XXX: we should have Rate type, not double double StatIntvlRec::reqRate() const { return theDuration > 0 ? Ratio(theXactLvl.incCnt(), theDuration.secd()) : -1; } double StatIntvlRec::repRate() const { return theDuration > 0 ? Ratio(theXactLvl.decCnt(), theDuration.secd()) : -1; } double StatIntvlRec::reqBwidth() const { return theDuration > 0 ? Ratio(reps().size().sum(), theDuration.secd()) : -1; } double StatIntvlRec::repBwidth() const { return theDuration > 0 ? Ratio(reps().size().sum(), theDuration.secd()) : -1; } AggrStat StatIntvlRec::repTime() const { return reps().time(); } AggrStat StatIntvlRec::repSize() const { return reps().size(); } TmSzStat StatIntvlRec::reps() const { TmSzStat reps; reps += theRealHR.xacts(); reps += theRediredReq; reps += theRepToRedir; reps += theIms; reps += theReload; reps += theHead; reps += thePost; reps += thePut; return reps; } void StatIntvlRec::keepLevels(const StatIntvlRec &prevIntvl) { thePopulusLvl.keepLevel(prevIntvl.thePopulusLvl); theWaitLvl.keepLevel(prevIntvl.theWaitLvl); theXactLvl.keepLevel(prevIntvl.theXactLvl); theOpenLvl.keepLevel(prevIntvl.theOpenLvl); theEstbLvl.keepLevel(prevIntvl.theEstbLvl); theSslStat.keepLevel(prevIntvl.theSslStat); } void StatIntvlRec::concat(const StatIntvlRec &s) { if (theDuration >= 0) theDuration += s.theDuration; thePopulusLvl.concat(s.thePopulusLvl); theWaitLvl.concat(s.theWaitLvl); theXactLvl.concat(s.theXactLvl); theOpenLvl.concat(s.theOpenLvl); theEstbLvl.concat(s.theEstbLvl); theSslStat.concat(s.theSslStat); join(s); } void StatIntvlRec::merge(const StatIntvlRec &s) { if (theDuration >= 0) theDuration = Max(theDuration, s.theDuration); thePopulusLvl.merge(s.thePopulusLvl); theWaitLvl.merge(s.theWaitLvl); theXactLvl.merge(s.theXactLvl); theOpenLvl.merge(s.theOpenLvl); theEstbLvl.merge(s.theEstbLvl); theSslStat.merge(s.theSslStat); join(s); } void StatIntvlRec::join(const StatIntvlRec &s) { Assert(s.theDuration >= 0); if (theDuration < 0) theDuration = s.theDuration; theConnLifeTm += s.theConnLifeTm; theConnUseCnt += s.theConnUseCnt; theConnPipelineDepth += s.theConnPipelineDepth; theIdealHR += s.theIdealHR; theRealHR += s.theRealHR; theChbR += s.theChbR; theFill += s.theFill; theRediredReq += s.theRediredReq; theRepToRedir += s.theRepToRedir; theIms += s.theIms; theReload += s.theReload; theHead += s.theHead; thePost += s.thePost; thePut += s.thePut; theAbort += s.theAbort; thePage += s.thePage; theXactCnt += s.theXactCnt; theXactErrCnt += s.theXactErrCnt; theXactRetrCnt += s.theXactRetrCnt; theIcpStat += s.theIcpStat; } ostream &StatIntvlRec::print(ostream &os, const String &pfx) const { os << pfx << "req.rate:\t " << reqRate() << endl; os << pfx << "rep.rate:\t " << repRate() << endl; reps().print(os, pfx + "rep."); theRealHR.xacts().print(os, pfx + "basic."); theIdealHR.print(os, "hit", "miss", pfx + "offered."); theRealHR.print(os, "hit", "miss", pfx); theChbR.print(os, "cachable", "uncachable", pfx); theFill.print(os, pfx + "fill."); theRediredReq.print(os, pfx + "redired_req."); theRepToRedir.print(os, pfx + "rep_to_redir."); theIms.print(os, pfx + "ims."); theReload.print(os, pfx + "reload."); theHead.print(os, pfx + "head."); thePost.print(os, pfx + "post."); thePut.print(os, pfx + "put."); theAbort.print(os, pfx + "abort."); thePage.print(os, pfx + "page."); theXactLvl.print(os, pfx + "xact."); os << pfx << "ok_xact.count: \t " << theXactCnt << endl; os << pfx << "err_xact.ratio:\t " << errPercent() << endl; os << pfx << "err_xact.count:\t " << theXactErrCnt << endl; os << pfx << "retr_xact.count:\t " << theXactRetrCnt << endl; thePopulusLvl.print(os, pfx + "populus."); theWaitLvl.print(os, pfx + "wait."); theOpenLvl.print(os, pfx + "conn.open."); theEstbLvl.print(os, pfx + "conn.estb."); theConnLifeTm.print(os, pfx + "conn.ttl."); theConnUseCnt.print(os, pfx + "conn.use."); theConnPipelineDepth.print(os, pfx + "conn.pipeline.depth."); theIcpStat.print(os, pfx + "icp.", theDuration); theSslStat.print(os, pfx + "ssl.", theDuration); os << pfx << "duration:\t " << theDuration.secd() << endl; return os; } void StatIntvlRec::linePrintSsl(ostream &os, bool includeLevels) const { os << ' ' << setw(6) << TheProgress.sslXacts() << ' ' << setw(6) << theSslStat.repRate(theDuration) << ' ' << setw(6) << (int)rint(theSslStat.doneXacts().xacts().time().mean()) << ' ' << setw(6) << theSslStat.doneXacts().dhp() << ' ' << setw(3) << theSslStat.errXacts() ; if (includeLevels) os << ' ' << setw(4) << Ssl::Level(); os << " https"; } void StatIntvlRec::linePrintAll(ostream &os, bool includeLevels) const { os << ' ' << setw(6) << TheProgress.xacts() << ' ' << setw(6) << repRate() << ' ' << setw(6) << (int)rint(repTime().mean()) << ' ' << setw(6) << theRealHR.dhp() << ' ' << setw(3) << theXactErrCnt ; if (includeLevels) os << ' ' << setw(4) << Socket::Level(); if (theSslStat.active()) os << " all"; }