XrdStats.cc

Go to the documentation of this file.
00001 /******************************************************************************/
00002 /*                                                                            */
00003 /*                           X r d S t a t s . c c                            */
00004 /*                                                                            */
00005 /* (c) 2004 by the Board of Trustees of the Leland Stanford, Jr., University  */
00006 /*       All Rights Reserved. See XrdInfo.cc for complete License Terms       */
00007 /*   Produced by Andrew Hanushevsky for Stanford University under contract    */
00008 /*              DE-AC03-76-SFO0515 with the Department of Energy              */
00009 /******************************************************************************/
00010 
00011 //         $Id: XrdStats.cc 34000 2010-06-21 06:49:56Z ganis $ 
00012 
00013 const char *XrdStatsCVSID = "$Id: XrdStats.cc 34000 2010-06-21 06:49:56Z ganis $";
00014 
00015 #if !defined(__macos__) && !defined(__FreeBSD__)
00016 #include <malloc.h>
00017 #endif
00018 #include <stdio.h>
00019 #include <sys/time.h>
00020 #include <sys/resource.h>
00021   
00022 #include "XrdVersion.hh"
00023 #include "Xrd/XrdBuffer.hh"
00024 #include "Xrd/XrdJob.hh"
00025 #include "Xrd/XrdLink.hh"
00026 #include "Xrd/XrdPoll.hh"
00027 #include "Xrd/XrdProtLoad.hh"
00028 #include "Xrd/XrdScheduler.hh"
00029 #include "Xrd/XrdStats.hh"
00030 #include "XrdNet/XrdNetMsg.hh"
00031 #include "XrdSys/XrdSysPlatform.hh"
00032 #include "XrdSys/XrdSysTimer.hh"
00033 
00034 /******************************************************************************/
00035 /*           G l o b a l   C o n f i g u r a t i o n   O b j e c t            */
00036 /******************************************************************************/
00037 
00038 extern XrdBuffManager    XrdBuffPool;
00039 
00040 extern XrdScheduler      XrdSched;
00041 
00042        long              XrdStats::tBoot = static_cast<long>(time(0));
00043 
00044 /******************************************************************************/
00045 /*               L o c a l   C l a s s   X r d S t a t s J o b                */
00046 /******************************************************************************/
00047   
00048 class XrdStatsJob : XrdJob
00049 {
00050 public:
00051 
00052      void DoIt() {Stats->Report();
00053                   XrdSched.Schedule((XrdJob *)this, time(0)+iVal);
00054                  }
00055 
00056           XrdStatsJob(XrdStats *sP, int iV) : XrdJob("stats reporter"),
00057                                               Stats(sP), iVal(iV)
00058                      {XrdSched.Schedule((XrdJob *)this, time(0)+iVal);}
00059          ~XrdStatsJob() {}
00060 private:
00061 XrdStats *Stats;
00062 int       iVal;
00063 };
00064 
00065 /******************************************************************************/
00066 /*                           C o n s t r c u t o r                            */
00067 /******************************************************************************/
00068   
00069 XrdStats::XrdStats(const char *hname, int port,
00070                    const char *iname, const char *pname)
00071 {
00072    static const char *head =
00073           "<statistics tod=\"%%ld\" ver=\"" XrdVSTRING "\" src=\"%s:%d\" "
00074                       "tos=\"%ld\" pgm=\"%s\" ins=\"%s\" pid=\"%d\">";
00075    char myBuff[1024];
00076 
00077    Hlen = sprintf(myBuff, head, hname, port, tBoot, pname, iname,
00078                           static_cast<int>(getpid()));
00079    Head = strdup(myBuff);
00080    buff = 0;
00081    blen = 0;
00082    myHost = hname;
00083    myName = iname;
00084    myPort = port;
00085 }
00086  
00087 /******************************************************************************/
00088 /*                                R e p o r t                                 */
00089 /******************************************************************************/
00090   
00091 void XrdStats::Report(char **Dest, int iVal, int Opts)
00092 {
00093    extern XrdSysError XrdLog;
00094    static XrdNetMsg *netDest[2] = {0,0};
00095    static int autoSync, repOpts = Opts;
00096    XrdJob *jP;
00097    const char *Data;
00098           int theOpts, Dlen;
00099 
00100 // If we have dest then this is for initialization
00101 //
00102    if (Dest)
00103    // Establish up to two destinations
00104    //
00105       {if (Dest[0]) netDest[0] = new XrdNetMsg(&XrdLog, Dest[0]);
00106        if (Dest[1]) netDest[1] = new XrdNetMsg(&XrdLog, Dest[1]);
00107        if (!(repOpts & XRD_STATS_ALL)) repOpts |= XRD_STATS_ALL;
00108        autoSync = repOpts & XRD_STATS_SYNCA;
00109 
00110    // Get and schedule a new job to report (ignore the jP pointer afterwards)
00111    //
00112       if (netDest[0]) jP = (XrdJob *)new XrdStatsJob(this, iVal);
00113        return;
00114       }
00115 
00116 // This is a re-entry for reporting purposes, establish the sync flag
00117 //
00118    if (!autoSync || XrdSched.Active() <= 30) theOpts = repOpts;
00119       else theOpts = repOpts & ~XRD_STATS_SYNC;
00120 
00121 // Now get the statistics
00122 //
00123    Lock();
00124    if ((Data = Stats(theOpts)))
00125       {Dlen = strlen(Data);
00126        netDest[0]->Send(Data, Dlen);
00127        if (netDest[1]) netDest[1]->Send(Data, Dlen);
00128       }
00129    UnLock();
00130 }
00131 
00132 /******************************************************************************/
00133 /*                                 S t a t s                                  */
00134 /******************************************************************************/
00135   
00136 const char *XrdStats::Stats(int opts)   // statsMutex must be locked!
00137 {
00138    static const char *sgen = "<stats id=\"sgen\">"
00139                              "<as>%d</as><et>%lu</et><toe>%ld</toe></stats>";
00140    static const char *tail = "</statistics>";
00141    static const char *snul = "<statistics tod=\"0\" ver=\"" XrdVSTRING "\">"
00142                             "</statistics>";
00143 
00144    static XrdProtLoad Protocols;
00145    static const int  ovrhed = 256+strlen(sgen)+strlen(tail);
00146    XrdSysTimer myTimer;
00147    char *bp;
00148    int   bl, sz, do_sync = (opts & XRD_STATS_SYNC ? 1 : 0);
00149 
00150 // If buffer is not allocated, do it now. We must defer buffer allocation
00151 // until all components that can provide statistics have been loaded
00152 //
00153    if (!(bp = buff))
00154       {blen = InfoStats(0,0) + XrdBuffPool.Stats(0,0) + XrdLink::Stats(0,0)
00155             + ProcStats(0,0) + XrdSched.Stats(0,0)    + XrdPoll::Stats(0,0)
00156             + Protocols.Stats(0,0) + ovrhed + Hlen;
00157        buff = (char *)memalign(getpagesize(), blen+256);
00158        if (!(bp = buff)) return snul;
00159       }
00160    bl = blen;
00161 
00162 // Start the time if need be
00163 //
00164    if (opts & XRD_STATS_SGEN) myTimer.Reset();
00165 
00166 // Insert the heading
00167 //
00168    sz = sprintf(buff, Head, static_cast<long>(time(0)));
00169    bl -= sz; bp += sz;
00170 
00171 // Extract out the statistics, as needed
00172 //
00173    if (opts & XRD_STATS_INFO)
00174       {sz = InfoStats(bp, bl, do_sync);
00175        bp += sz; bl -= sz;
00176       }
00177 
00178    if (opts & XRD_STATS_BUFF)
00179       {sz = XrdBuffPool.Stats(bp, bl, do_sync);
00180        bp += sz; bl -= sz;
00181       }
00182 
00183    if (opts & XRD_STATS_LINK)
00184       {sz = XrdLink::Stats(bp, bl, do_sync);
00185        bp += sz; bl -= sz;
00186       }
00187 
00188    if (opts & XRD_STATS_POLL)
00189       {sz = XrdPoll::Stats(bp, bl, do_sync);
00190        bp += sz; bl -= sz;
00191       }
00192 
00193    if (opts & XRD_STATS_PROC)
00194       {sz = ProcStats(bp, bl, do_sync);
00195        bp += sz; bl -= sz;
00196       }
00197 
00198    if (opts & XRD_STATS_PROT)
00199       {sz = Protocols.Stats(bp, bl, do_sync);
00200        bp += sz; bl -= sz;
00201       }
00202 
00203    if (opts & XRD_STATS_SCHD)
00204       {sz = XrdSched.Stats(bp, bl, do_sync);
00205        bp += sz; bl -= sz;
00206       }
00207 
00208    if (opts & XRD_STATS_SGEN)
00209       {unsigned long totTime = 0;
00210        myTimer.Report(totTime);
00211        sz = snprintf(bp,bl,sgen,do_sync==0,totTime,static_cast<long>(time(0)));
00212        bp += sz; bl -= sz;
00213       }
00214 
00215    strlcpy(bp, tail, bl);
00216    return buff;
00217 }
00218  
00219 /******************************************************************************/
00220 /*                       P r i v a t e   M e t h o d s                        */
00221 /******************************************************************************/
00222 /******************************************************************************/
00223 /*                             I n f o S t a t s                              */
00224 /******************************************************************************/
00225   
00226 int XrdStats::InfoStats(char *bfr, int bln, int do_sync)
00227 {
00228    static const char statfmt[] = "<stats id=\"info\"><host>%s</host>"
00229                      "<port>%d</port><name>%s</name></stats>";
00230 
00231 // Check if actual length wanted
00232 //
00233    if (!bfr) return sizeof(statfmt)+24 + strlen(myHost);
00234 
00235 // Format the statistics
00236 //
00237    return snprintf(bfr, bln, statfmt, myHost, myPort, myName);
00238 }
00239  
00240 /******************************************************************************/
00241 /*                             P r o c S t a t s                              */
00242 /******************************************************************************/
00243   
00244 int XrdStats::ProcStats(char *bfr, int bln, int do_sync)
00245 {
00246    static const char statfmt[] = "<stats id=\"proc\">"
00247           "<usr><s>%lld</s><u>%lld</u></usr>"
00248           "<sys><s>%lld</s><u>%lld</u></sys>"
00249           "</stats>";
00250    struct rusage r_usage;
00251    long long utime_sec, utime_usec, stime_sec, stime_usec;
00252 // long long ru_maxrss, ru_majflt, ru_nswap, ru_inblock, ru_oublock;
00253 // long long ru_msgsnd, ru_msgrcv, ru_nsignals;
00254 
00255 // Check if actual length wanted
00256 //
00257    if (!bfr) return sizeof(statfmt)+16*13;
00258 
00259 // Get the statistics
00260 //
00261    if (getrusage(RUSAGE_SELF, &r_usage)) return 0;
00262 
00263 // Convert fields to correspond to the format we are using. Commented out fields
00264 // are either not uniformaly reported or are incorrectly reported making them
00265 // useless across multiple platforms.
00266 //
00267 //
00268    utime_sec   = static_cast<long long>(r_usage.ru_utime.tv_sec);
00269    utime_usec  = static_cast<long long>(r_usage.ru_utime.tv_usec);
00270    stime_sec   = static_cast<long long>(r_usage.ru_stime.tv_sec);
00271    stime_usec  = static_cast<long long>(r_usage.ru_stime.tv_usec);
00272 // ru_maxrss   = static_cast<long long>(r_usage.ru_maxrss);
00273 // ru_majflt   = static_cast<long long>(r_usage.ru_majflt);
00274 // ru_nswap    = static_cast<long long>(r_usage.ru_nswap);
00275 // ru_inblock  = static_cast<long long>(r_usage.ru_inblock);
00276 // ru_oublock  = static_cast<long long>(r_usage.ru_oublock);
00277 // ru_msgsnd   = static_cast<long long>(r_usage.ru_msgsnd);
00278 // ru_msgrcv   = static_cast<long long>(r_usage.ru_msgrcv);
00279 // ru_nsignals = static_cast<long long>(r_usage.ru_nsignals);
00280 
00281 // Format the statistics
00282 //
00283    return snprintf(bfr, bln, statfmt,
00284           utime_sec, utime_usec, stime_sec, stime_usec
00285 //        ru_maxrss, ru_majflt, ru_nswap, ru_inblock, ru_oublock,
00286 //        ru_msgsnd, ru_msgrcv, ru_nsignals
00287          );
00288 }

Generated on Tue Jul 5 14:46:15 2011 for ROOT_528-00b_version by  doxygen 1.5.1