reSIProcate/stack  9694
StatisticsMessage.cxx
Go to the documentation of this file.
00001 #include "resip/stack/StatisticsMessage.hxx"
00002 #include "rutil/Lock.hxx"
00003 #include "rutil/Logger.hxx"
00004 #include "rutil/WinLeakCheck.hxx"
00005 
00006 #include <string.h>
00007 
00008 using namespace resip;
00009 
00010 #define RESIPROCATE_SUBSYSTEM Subsystem::STATS
00011 
00012 StatisticsMessage::StatisticsMessage(const StatisticsMessage::AtomicPayload& payload)
00013    : ApplicationMessage(),
00014      mPayload(payload)
00015 {}
00016 
00017 StatisticsMessage::StatisticsMessage(const StatisticsMessage& rhs)
00018    : ApplicationMessage(rhs),
00019      mPayload(rhs.mPayload)
00020 {}
00021 
00022 StatisticsMessage::~StatisticsMessage()
00023 {}
00024 
00025 EncodeStream&
00026 StatisticsMessage::encodeBrief(EncodeStream& str) const 
00027 {
00028    return str << "StatisticsMessage";
00029 }
00030 
00031 EncodeStream& 
00032 StatisticsMessage::encode(EncodeStream& strm) const 
00033 {
00034    strm << "StatisticsMessage";
00035 /*
00036    strm << " [";
00037    Payload payload;
00038    mPayload.loadOut(payload);
00039    strm << payload << "]";
00040 */
00041    return strm;
00042 }
00043 
00044 unsigned int
00045 StatisticsMessage::Payload::sum2xxIn(MethodTypes method) const
00046 {
00047    unsigned int ret = 0;
00048    for (int code = 200; code < 300; ++code)
00049    {
00050       ret += responsesReceivedByMethodByCode[method][code];
00051    }
00052 
00053    return ret;
00054 }
00055 
00056 unsigned int
00057 StatisticsMessage::Payload::sum2xxOut(MethodTypes method) const
00058 {
00059    unsigned int ret = 0;
00060    for (int code = 200; code < 300; ++code)
00061    {
00062       ret += responsesSentByMethodByCode[method][code];
00063    }
00064 
00065    return ret;
00066 }
00067 
00068 unsigned int
00069 StatisticsMessage::Payload::sumErrIn(MethodTypes method) const
00070 {
00071    unsigned int ret = 0;
00072    for (int code = 300; code < MaxCode; ++code)
00073    {
00074       ret += responsesReceivedByMethodByCode[method][code];
00075    }
00076 
00077    return ret;
00078 }
00079 
00080 unsigned int
00081 StatisticsMessage::Payload::sumErrOut(MethodTypes method) const
00082 {
00083    unsigned int ret = 0;
00084    for (int code = 300; code < MaxCode; ++code)
00085    {
00086       ret += responsesSentByMethodByCode[method][code];
00087    }
00088 
00089    return ret;
00090 }
00091 
00092 void 
00093 StatisticsMessage::logStats(const resip::Subsystem& subsystem, 
00094                             const StatisticsMessage::Payload& stats)
00095 {
00096    WarningLog(<< subsystem
00097               << std::endl
00098               << stats);
00099 }
00100 
00101 
00102 Message*
00103 StatisticsMessage::clone() const
00104 {
00105    return new StatisticsMessage(*this);
00106 }
00107 
00108 StatisticsMessage::Payload::Payload()
00109 {
00110    zeroOut();
00111 }
00112 
00113 void
00114 StatisticsMessage::Payload::zeroOut()
00115 {
00116    tuFifoSize = 0;
00117    transportFifoSizeSum = 0;
00118    transactionFifoSize = 0;
00119    activeTimers = 0;
00120    openTcpConnections = 0;
00121    activeClientTransactions = 0;
00122    activeServerTransactions = 0;
00123    pendingDnsQueries = 0;
00124    requestsSent = 0;
00125    responsesSent = 0;
00126    requestsRetransmitted = 0;
00127    responsesRetransmitted = 0;
00128    requestsReceived = 0;
00129    responsesReceived = 0;
00130    memset(responsesByCode, 0, sizeof(responsesByCode));
00131    memset(requestsSentByMethod, 0, sizeof(requestsSentByMethod));
00132    memset(requestsRetransmittedByMethod, 0, sizeof(requestsRetransmittedByMethod));
00133    memset(requestsReceivedByMethod, 0, sizeof(requestsReceivedByMethod));
00134    memset(responsesSentByMethod, 0, sizeof(responsesSentByMethod));
00135    memset(responsesRetransmittedByMethod, 0, sizeof(responsesRetransmittedByMethod));
00136    memset(responsesReceivedByMethod, 0, sizeof(responsesReceivedByMethod));
00137    memset(responsesSentByMethodByCode, 0, sizeof(responsesSentByMethodByCode));
00138    memset(responsesRetransmittedByMethodByCode, 0, sizeof(responsesRetransmittedByMethodByCode));
00139    memset(responsesReceivedByMethodByCode, 0, sizeof(responsesReceivedByMethodByCode));
00140 }
00141 
00142 StatisticsMessage::Payload&
00143 StatisticsMessage::Payload::operator=(const StatisticsMessage::Payload& rhs)
00144 {
00145    if (&rhs != this)
00146    {
00147       transportFifoSizeSum = rhs.transportFifoSizeSum;
00148       tuFifoSize = rhs.tuFifoSize;
00149       activeTimers = rhs.activeTimers;
00150       transactionFifoSize = rhs.transactionFifoSize;
00151 
00152       openTcpConnections = rhs.openTcpConnections;
00153       activeClientTransactions = rhs.activeClientTransactions;
00154       activeServerTransactions = rhs.activeServerTransactions;
00155       pendingDnsQueries = rhs.pendingDnsQueries;
00156 
00157       requestsSent = rhs.requestsSent;
00158       responsesSent = rhs.responsesSent;
00159       requestsRetransmitted = rhs.requestsRetransmitted;
00160       responsesRetransmitted = rhs.responsesRetransmitted;
00161       requestsReceived = rhs.requestsReceived;
00162       responsesReceived = rhs.responsesReceived;
00163 
00164       memcpy(responsesByCode, rhs.responsesByCode, sizeof(responsesByCode));
00165       memcpy(requestsSentByMethod, rhs.requestsSentByMethod, sizeof(requestsSentByMethod));
00166       memcpy(requestsRetransmittedByMethod, rhs.requestsRetransmittedByMethod, sizeof(requestsRetransmittedByMethod));
00167       memcpy(requestsReceivedByMethod, rhs.requestsReceivedByMethod, sizeof(requestsReceivedByMethod));
00168       memcpy(responsesSentByMethod, rhs.responsesSentByMethod, sizeof(responsesSentByMethod));
00169       memcpy(responsesRetransmittedByMethod, rhs.responsesRetransmittedByMethod, sizeof(responsesRetransmittedByMethod));
00170       memcpy(responsesReceivedByMethod, rhs.responsesReceivedByMethod, sizeof(responsesReceivedByMethod));
00171       memcpy(responsesSentByMethodByCode, rhs.responsesSentByMethodByCode, sizeof(responsesSentByMethodByCode));
00172       memcpy(responsesRetransmittedByMethodByCode, rhs.responsesRetransmittedByMethodByCode, sizeof(responsesRetransmittedByMethodByCode));
00173       memcpy(responsesReceivedByMethodByCode, rhs.responsesReceivedByMethodByCode, sizeof(responsesReceivedByMethodByCode));
00174    }
00175 
00176    return *this;
00177 }
00178 
00179 void 
00180 StatisticsMessage::loadOut(Payload& payload) const
00181 {
00182    mPayload.loadOut(payload);
00183 }
00184 
00185 StatisticsMessage::AtomicPayload::AtomicPayload()
00186 {}
00187 
00188 void
00189 StatisticsMessage::AtomicPayload::loadIn(const Payload& payload)
00190 {
00191    Lock lock(mMutex);
00192    Payload::operator=(payload);
00193 }
00194 
00195 void
00196 StatisticsMessage::AtomicPayload::loadOut(Payload& payload) const
00197 {
00198    Lock lock(mMutex);
00199    payload = (*this);
00200 }
00201 
00202 EncodeStream& 
00203 resip::operator<<(EncodeStream& strm, const StatisticsMessage::Payload& stats)
00204 {
00205    unsigned int retriesFinal = 0;
00206    for (int c = 200; c < 300; ++c)
00207    {
00208       retriesFinal += stats.responsesRetransmittedByMethodByCode[INVITE][c];
00209    }
00210 
00211    unsigned int retriesNonFinal = 0;      
00212    for (int c = 100; c < 200; ++c)
00213    {
00214       retriesNonFinal += stats.responsesRetransmittedByMethodByCode[INVITE][c];
00215    }
00216 
00217    strm << "TU summary: " << stats.tuFifoSize
00218         << " TRANSPORT " << stats.transportFifoSizeSum
00219         << " TRANSACTION " << stats.transactionFifoSize
00220         << " CLIENTTX " << stats.activeClientTransactions
00221         << " SERVERTX " << stats.activeServerTransactions
00222         << " TIMERS " << stats.activeTimers
00223         << std::endl
00224         << "Transaction summary: reqi " << stats.requestsReceived
00225         << " reqo " << stats.requestsSent
00226         << " rspi " << stats.responsesReceived
00227         << " rspo " << stats.responsesSent
00228         << std::endl
00229         << "Details: INVi " << stats.requestsReceivedByMethod[INVITE] << "/S" << stats.sum2xxOut(INVITE) << "/F" << stats.sumErrOut(INVITE)
00230         << " INVo " << stats.requestsSentByMethod[INVITE]-stats.requestsRetransmittedByMethod[INVITE] << "/S" << stats.sum2xxIn(INVITE) << "/F" << stats.sumErrIn(INVITE)
00231         << " ACKi " << stats.requestsReceivedByMethod[ACK]
00232         << " ACKo " << stats.requestsSentByMethod[ACK]-stats.requestsRetransmittedByMethod[ACK]
00233         << " BYEi " << stats.requestsReceivedByMethod[BYE] << "/S" << stats.sum2xxOut(BYE) << "/F" << stats.sumErrOut(BYE)
00234         << " BYEo " << stats.requestsSentByMethod[BYE]-stats.requestsRetransmittedByMethod[BYE] << "/S" << stats.sum2xxIn(BYE) << "/F" << stats.sumErrIn(BYE)
00235         << " CANi " << stats.requestsReceivedByMethod[CANCEL] << "/S" << stats.sum2xxOut(BYE) << "/F" << stats.sumErrOut(BYE)
00236         << " CANo " << stats.requestsSentByMethod[CANCEL]-stats.requestsRetransmittedByMethod[CANCEL] << "/S" << stats.sum2xxIn(CANCEL) << "/F" << stats.sumErrIn(CANCEL)
00237         << " MSGi " << stats.requestsReceivedByMethod[MESSAGE] << "/S" << stats.sum2xxOut(MESSAGE) << "/F" << stats.sumErrOut(MESSAGE)
00238         << " MSGo " << stats.requestsSentByMethod[MESSAGE]-stats.requestsRetransmittedByMethod[MESSAGE] << "/S" << stats.sum2xxIn(MESSAGE) << "/F" << stats.sumErrIn(MESSAGE)
00239         << " OPTi " << stats.requestsReceivedByMethod[OPTIONS] << "/S" << stats.sum2xxOut(OPTIONS) << "/F" << stats.sumErrOut(OPTIONS)
00240         << " OPTo " << stats.requestsSentByMethod[OPTIONS]-stats.requestsRetransmittedByMethod[OPTIONS] << "/S" << stats.sum2xxIn(OPTIONS) << "/F" << stats.sumErrIn(OPTIONS)
00241         << " REGi " << stats.requestsReceivedByMethod[REGISTER] << "/S" << stats.sum2xxOut(REGISTER) << "/F" << stats.sumErrOut(REGISTER)
00242         << " REGo " << stats.requestsSentByMethod[REGISTER]-stats.requestsRetransmittedByMethod[REGISTER] << "/S" << stats.sum2xxIn(REGISTER) << "/F" << stats.sumErrIn(REGISTER)
00243         << " PUBi " << stats.requestsReceivedByMethod[PUBLISH] << "/S" << stats.sum2xxOut(PUBLISH) << "/F" << stats.sumErrOut(PUBLISH)
00244         << " PUBo " << stats.requestsSentByMethod[PUBLISH] << "/S" << stats.sum2xxIn(PUBLISH) << "/F" << stats.sumErrIn(PUBLISH)
00245         << " SUBi " << stats.requestsReceivedByMethod[SUBSCRIBE] << "/S" << stats.sum2xxOut(SUBSCRIBE) << "/F" << stats.sumErrOut(SUBSCRIBE)
00246         << " SUBo " << stats.requestsSentByMethod[SUBSCRIBE] << "/S" << stats.sum2xxIn(SUBSCRIBE) << "/F" << stats.sumErrIn(SUBSCRIBE)
00247         << " NOTi " << stats.requestsReceivedByMethod[NOTIFY] << "/S" << stats.sum2xxOut(NOTIFY) << "/F" << stats.sumErrOut(NOTIFY)
00248         << " NOTo " << stats.requestsSentByMethod[NOTIFY] << "/S" << stats.sum2xxIn(NOTIFY) << "/F" << stats.sumErrIn(NOTIFY)
00249         << " REFi " << stats.requestsReceivedByMethod[REFER] << "/S" << stats.sum2xxOut(REFER) << "/F" << stats.sumErrOut(REFER)
00250         << " REFo " << stats.requestsSentByMethod[REFER] << "/S" << stats.sum2xxIn(REFER) << "/F" << stats.sumErrIn(REFER)
00251         << " INFi " << stats.requestsReceivedByMethod[INFO] << "/S" << stats.sum2xxOut(INFO) << "/F" << stats.sumErrOut(INFO)
00252         << " INFo " << stats.requestsSentByMethod[INFO] << "/S" << stats.sum2xxIn(INFO) << "/F" << stats.sumErrIn(INFO)
00253         << " PRAi " << stats.requestsReceivedByMethod[PRACK] << "/S" << stats.sum2xxOut(PRACK) << "/F" << stats.sumErrOut(PRACK)
00254         << " PRAo " << stats.requestsSentByMethod[PRACK] << "/S" << stats.sum2xxIn(PRACK) << "/F" << stats.sumErrIn(PRACK)
00255         << " SERi " << stats.requestsReceivedByMethod[SERVICE] << "/S" << stats.sum2xxOut(SERVICE) << "/F" << stats.sumErrOut(SERVICE)
00256         << " SERo " << stats.requestsSentByMethod[SERVICE] << "/S" << stats.sum2xxIn(SERVICE) << "/F" << stats.sumErrIn(SERVICE)
00257         << " UPDi " << stats.requestsReceivedByMethod[UPDATE] << "/S" << stats.sum2xxOut(UPDATE) << "/F" << stats.sumErrOut(UPDATE)
00258         << " UPDo " << stats.requestsSentByMethod[UPDATE] << "/S" << stats.sum2xxIn(UPDATE) << "/F" << stats.sumErrIn(UPDATE)
00259         << std::endl
00260         << "Retransmissions: INVx " << stats.requestsRetransmittedByMethod[INVITE]
00261         << " finx " << retriesFinal
00262         << " nonx " << retriesNonFinal
00263         << " BYEx " << stats.requestsRetransmittedByMethod[BYE]
00264         << " CANx " << stats.requestsRetransmittedByMethod[CANCEL]
00265         << " MSGx " << stats.requestsRetransmittedByMethod[MESSAGE]
00266         << " OPTx " << stats.requestsRetransmittedByMethod[OPTIONS]
00267         << " REGx " << stats.requestsRetransmittedByMethod[REGISTER]
00268         << " PUBx " << stats.requestsRetransmittedByMethod[PUBLISH]
00269         << " SUBx " << stats.requestsRetransmittedByMethod[SUBSCRIBE]
00270         << " NOTx " << stats.requestsRetransmittedByMethod[NOTIFY]
00271         << " REFx " << stats.requestsRetransmittedByMethod[REFER]
00272         << " INFx " << stats.requestsRetransmittedByMethod[INFO]
00273         << " PRAx " << stats.requestsRetransmittedByMethod[PRACK]
00274         << " SERx " << stats.requestsRetransmittedByMethod[SERVICE]
00275         << " UPDx " << stats.requestsRetransmittedByMethod[UPDATE];
00276    strm.flush();
00277    return strm;
00278 }
00279 
00280 /* ====================================================================
00281  * The Vovida Software License, Version 1.0 
00282  * 
00283  * Copyright (c) 2004 Vovida Networks, Inc.  All rights reserved.
00284  * 
00285  * Redistribution and use in source and binary forms, with or without
00286  * modification, are permitted provided that the following conditions
00287  * are met:
00288  * 
00289  * 1. Redistributions of source code must retain the above copyright
00290  *    notice, this list of conditions and the following disclaimer.
00291  * 
00292  * 2. Redistributions in binary form must reproduce the above copyright
00293  *    notice, this list of conditions and the following disclaimer in
00294  *    the documentation and/or other materials provided with the
00295  *    distribution.
00296  * 
00297  * 3. The names "VOCAL", "Vovida Open Communication Application Library",
00298  *    and "Vovida Open Communication Application Library (VOCAL)" must
00299  *    not be used to endorse or promote products derived from this
00300  *    software without prior written permission. For written
00301  *    permission, please contact vocal@vovida.org.
00302  *
00303  * 4. Products derived from this software may not be called "VOCAL", nor
00304  *    may "VOCAL" appear in their name, without prior written
00305  *    permission of Vovida Networks, Inc.
00306  * 
00307  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
00308  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00309  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
00310  * NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL VOVIDA
00311  * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
00312  * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
00313  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00314  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00315  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
00316  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00317  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
00318  * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
00319  * DAMAGE.
00320  * 
00321  * ====================================================================
00322  * 
00323  * This software consists of voluntary contributions made by Vovida
00324  * Networks, Inc. and many individuals on behalf of Vovida Networks,
00325  * Inc.  For more information on Vovida Networks, Inc., please see
00326  * <http://www.vovida.org/>.
00327  *
00328  */