reSIProcate/stack  9694
StatisticsManager.cxx
Go to the documentation of this file.
00001 #if defined(HAVE_CONFIG_H)
00002 #include "config.h"
00003 #endif
00004 
00005 #include "rutil/Logger.hxx"
00006 #include "resip/stack/StatisticsManager.hxx"
00007 #include "resip/stack/SipMessage.hxx"
00008 #include "resip/stack/TransactionController.hxx"
00009 #include "resip/stack/SipStack.hxx"
00010 
00011 using namespace resip;
00012 using std::vector;
00013 
00014 #define RESIPROCATE_SUBSYSTEM Subsystem::TRANSACTION
00015 
00016 StatisticsManager::StatisticsManager(SipStack& stack, unsigned long intervalSecs) 
00017    : StatisticsMessage::Payload(),
00018      mStack(stack),
00019      mInterval(intervalSecs*1000),
00020      mNextPoll(Timer::getTimeMs() + mInterval),
00021      mExternalHandler(NULL),
00022      mPublicPayload(NULL)
00023 {}
00024 
00025 StatisticsManager::~StatisticsManager()
00026 {
00027    if ( mPublicPayload )
00028        delete mPublicPayload;
00029 }
00030 
00031 void 
00032 StatisticsManager::setInterval(unsigned long intervalSecs)
00033 {
00034    mInterval = intervalSecs * 1000;
00035 }
00036 
00037 void 
00038 StatisticsManager::poll()
00039 {
00040    // get snapshot data now..
00041    tuFifoSize = mStack.mTransactionController->getTuFifoSize();
00042    transportFifoSizeSum = mStack.mTransactionController->sumTransportFifoSizes();
00043    transactionFifoSize = mStack.mTransactionController->getTransactionFifoSize();
00044    activeTimers = mStack.mTransactionController->getTimerQueueSize();
00045    activeClientTransactions = mStack.mTransactionController->getNumClientTransactions();
00046    activeServerTransactions = mStack.mTransactionController->getNumServerTransactions();
00047 
00048    // .kw. At last check payload was > 146kB, which seems too large
00049    // to alloc on stack. Also, the post'd message has reference
00050    // to the appStats, so not safe queue as ref to stack element.
00051    // Converted to dynamic memory allocation.
00052    if ( mPublicPayload==NULL )
00053    {
00054        mPublicPayload = new StatisticsMessage::AtomicPayload;
00055        // re-used each time, free'd in destructor
00056    }
00057    mPublicPayload->loadIn(*this);
00058 
00059    bool postToStack = true;
00060    StatisticsMessage msg(*mPublicPayload);
00061    // WATCHOUT: msg contains reference to the payload, and this reference
00062    // is preserved thru clone().
00063 
00064    if( mExternalHandler )
00065    {
00066       postToStack = (*mExternalHandler)(msg);
00067    }
00068 
00069    if( postToStack )
00070    {
00071       // let the app do what it wants with it
00072       mStack.post(msg);
00073    }
00074    
00075    // !bwc! TODO maybe change this? Or is a flexible implementation of 
00076    // CongestionManager::logCurrentState() enough?
00077    if(mStack.mCongestionManager)
00078    {
00079       mStack.mCongestionManager->logCurrentState();
00080    }
00081 }
00082 
00083 void 
00084 StatisticsManager::process()
00085 {
00086    if (Timer::getTimeMs() >= mNextPoll)
00087    {
00088       poll();
00089       mNextPoll += mInterval;
00090    }
00091 }
00092 
00093 bool
00094 StatisticsManager::sent(SipMessage* msg)
00095 {
00096    MethodTypes met = msg->method();
00097 
00098    if (msg->isRequest())
00099    {
00100       ++requestsSent;
00101       ++requestsSentByMethod[met];
00102    }
00103    else if (msg->isResponse())
00104    {
00105       int code = msg->const_header(h_StatusLine).statusCode();
00106       if (code < 0 || code >= MaxCode)
00107       {
00108          code = 0;
00109       }
00110 
00111       ++responsesSent;
00112       ++responsesSentByMethod[met];
00113       ++responsesSentByMethodByCode[met][code];
00114    }
00115    
00116    return false;
00117 }
00118 
00119 bool 
00120 StatisticsManager::retransmitted(MethodTypes met, 
00121                                  bool request, 
00122                                  unsigned int code)
00123 {
00124    if(request)
00125    {
00126       ++requestsRetransmitted;
00127       ++requestsRetransmittedByMethod[met];
00128    }
00129    else
00130    {
00131       ++responsesRetransmitted;
00132       ++responsesRetransmittedByMethod[met];
00133       ++responsesRetransmittedByMethodByCode[met][code];
00134    }
00135    return false;
00136 }
00137 
00138 bool
00139 StatisticsManager::received(SipMessage* msg)
00140 {
00141    MethodTypes met = msg->header(h_CSeq).method();
00142 
00143    if (msg->isRequest())
00144    {
00145       ++requestsReceived;
00146       ++requestsReceivedByMethod[met];
00147    }
00148    else if (msg->isResponse())
00149    {
00150       ++responsesReceived;
00151       ++responsesReceivedByMethod[met];
00152       int code = msg->const_header(h_StatusLine).statusCode();
00153       if (code < 0 || code >= MaxCode)
00154       {
00155          code = 0;
00156       }
00157       ++responsesReceivedByMethodByCode[met][code];
00158    }
00159 
00160    return false;
00161 }
00162 
00163 /* ====================================================================
00164  * The Vovida Software License, Version 1.0 
00165  * 
00166  * Copyright (c) 2000-2005 Vovida Networks, Inc.  All rights reserved.
00167  * 
00168  * Redistribution and use in source and binary forms, with or without
00169  * modification, are permitted provided that the following conditions
00170  * are met:
00171  * 
00172  * 1. Redistributions of source code must retain the above copyright
00173  *    notice, this list of conditions and the following disclaimer.
00174  * 
00175  * 2. Redistributions in binary form must reproduce the above copyright
00176  *    notice, this list of conditions and the following disclaimer in
00177  *    the documentation and/or other materials provided with the
00178  *    distribution.
00179  * 
00180  * 3. The names "VOCAL", "Vovida Open Communication Application Library",
00181  *    and "Vovida Open Communication Application Library (VOCAL)" must
00182  *    not be used to endorse or promote products derived from this
00183  *    software without prior written permission. For written
00184  *    permission, please contact vocal@vovida.org.
00185  *
00186  * 4. Products derived from this software may not be called "VOCAL", nor
00187  *    may "VOCAL" appear in their name, without prior written
00188  *    permission of Vovida Networks, Inc.
00189  * 
00190  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
00191  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00192  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
00193  * NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL VOVIDA
00194  * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
00195  * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
00196  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00197  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00198  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
00199  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00200  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
00201  * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
00202  * DAMAGE.
00203  * 
00204  * ====================================================================
00205  * 
00206  * This software consists of voluntary contributions made by Vovida
00207  * Networks, Inc. and many individuals on behalf of Vovida Networks,
00208  * Inc.  For more information on Vovida Networks, Inc., please see
00209  * <http://www.vovida.org/>.
00210  *
00211  */