XRootD
XrdStats.cc
Go to the documentation of this file.
1 /******************************************************************************/
2 /* */
3 /* X r d S t a t s . c c */
4 /* */
5 /* (c) 2004 by the Board of Trustees of the Leland Stanford, Jr., University */
6 /* Produced by Andrew Hanushevsky for Stanford University under contract */
7 /* DE-AC02-76-SFO0515 with the Department of Energy */
8 /* */
9 /* This file is part of the XRootD software suite. */
10 /* */
11 /* XRootD is free software: you can redistribute it and/or modify it under */
12 /* the terms of the GNU Lesser General Public License as published by the */
13 /* Free Software Foundation, either version 3 of the License, or (at your */
14 /* option) any later version. */
15 /* */
16 /* XRootD is distributed in the hope that it will be useful, but WITHOUT */
17 /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
18 /* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */
19 /* License for more details. */
20 /* */
21 /* You should have received a copy of the GNU Lesser General Public License */
22 /* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */
23 /* COPYING (GPL license). If not, see <http://www.gnu.org/licenses/>. */
24 /* */
25 /* The copyright holder's institutional names and contributor's names may not */
26 /* be used to endorse or promote products derived from this software without */
27 /* specific prior written permission of the institution or contributor. */
28 /******************************************************************************/
29 
30 #include <cstdio>
31 #include <cstdlib>
32 #include <sys/time.h>
33 #include <sys/resource.h>
34 
35 #include "XrdVersion.hh"
36 #include "Xrd/XrdBuffer.hh"
37 #include "Xrd/XrdJob.hh"
38 #include "Xrd/XrdLink.hh"
39 #include "Xrd/XrdPoll.hh"
40 #include "Xrd/XrdProtLoad.hh"
41 #include "Xrd/XrdScheduler.hh"
42 #include "Xrd/XrdStats.hh"
43 #include "XrdNet/XrdNetMsg.hh"
44 #include "XrdSys/XrdSysPlatform.hh"
45 #include "XrdSys/XrdSysTimer.hh"
46 
47 /******************************************************************************/
48 /* S t a t i c O b j e c t s */
49 /******************************************************************************/
50 
51  long XrdStats::tBoot = static_cast<long>(time(0));
52 
53 /******************************************************************************/
54 /* L o c a l C l a s s X r d S t a t s J o b */
55 /******************************************************************************/
56 
58 {
59 public:
60 
61  void DoIt() {Stats->Report();
62  Sched->Schedule((XrdJob *)this, time(0)+iVal);
63  }
64 
65  XrdStatsJob(XrdScheduler *schP, XrdStats *sP, int iV)
66  : XrdJob("stats reporter"),
67  Sched(schP), Stats(sP), iVal(iV)
68  {Sched->Schedule((XrdJob *)this, time(0)+iVal);}
70 private:
71 XrdScheduler *Sched;
72 XrdStats *Stats;
73 int iVal;
74 };
75 
76 /******************************************************************************/
77 /* C o n s t r c u t o r */
78 /******************************************************************************/
79 
81  const char *hname, int port,
82  const char *iname, const char *pname, const char *site)
83 {
84  static const char *head =
85  "<statistics tod=\"%%ld\" ver=\"" XrdVERSION "\" src=\"%s:%d\" "
86  "tos=\"%ld\" pgm=\"%s\" ins=\"%s\" pid=\"%d\" "
87  "site=\"%s\">";
88  char myBuff[1024];
89 
90  XrdLog = eP;
91  XrdSched = sP;
92  BuffPool = bP;
93 
94  Hlen = sprintf(myBuff, head, hname, port, tBoot, pname, iname,
95  static_cast<int>(getpid()), (site ? site : ""));
96  Head = strdup(myBuff);
97  buff = 0;
98  blen = 0;
99  myHost = hname;
100  myName = iname;
101  myPort = port;
102 }
103 
104 /******************************************************************************/
105 /* R e p o r t */
106 /******************************************************************************/
107 
108 void XrdStats::Report(char **Dest, int iVal, int Opts)
109 {
110  static XrdNetMsg *netDest[2] = {0,0};
111  static int autoSync, repOpts = Opts;
112  const char *Data;
113  int theOpts, Dlen;
114 
115 // If we have dest then this is for initialization
116 //
117  if (Dest)
118  // Establish up to two destinations
119  //
120  {if (Dest[0]) netDest[0] = new XrdNetMsg(XrdLog, Dest[0]);
121  if (Dest[1]) netDest[1] = new XrdNetMsg(XrdLog, Dest[1]);
122  if (!(repOpts & XRD_STATS_ALL)) repOpts |= XRD_STATS_ALL;
123  autoSync = repOpts & XRD_STATS_SYNCA;
124 
125  // Get and schedule a new job to report
126  //
127  if (netDest[0]) new XrdStatsJob(XrdSched, this, iVal);
128  return;
129  }
130 
131 // This is a re-entry for reporting purposes, establish the sync flag
132 //
133  if (!autoSync || XrdSched->Active() <= 30) theOpts = repOpts;
134  else theOpts = repOpts & ~XRD_STATS_SYNC;
135 
136 // Now get the statistics
137 //
138  statsMutex.Lock();
139  if ((Data = GenStats(Dlen, theOpts)))
140  {netDest[0]->Send(Data, Dlen);
141  if (netDest[1]) netDest[1]->Send(Data, Dlen);
142  }
143  statsMutex.UnLock();
144 }
145 
146 /******************************************************************************/
147 /* S t a t s */
148 /******************************************************************************/
149 
151 {
152  const char *info;
153  int sz;
154 
155 // Lock the buffer,
156 //
157  statsMutex.Lock();
158 
159 // Obtain the stats, if we have some, do the callback
160 //
161  if ((info = GenStats(sz, opts))) cbP->Info(info, sz);
162 
163 // Unlock the buffer
164 //
165  statsMutex.UnLock();
166 }
167 
168 /******************************************************************************/
169 /* P r i v a t e M e t h o d s */
170 /******************************************************************************/
171 /******************************************************************************/
172 /* G e n S t a t s */
173 /******************************************************************************/
174 
175 const char *XrdStats::GenStats(int &rsz, int opts) // statsMutex must be locked!
176 {
177  static const char *sgen = "<stats id=\"sgen\">"
178  "<as>%d</as><et>%lu</et><toe>%ld</toe></stats>";
179  static const char *tail = "</statistics>";
180  static const char *snul = "<statistics tod=\"0\" ver=\"" XrdVSTRING "\">"
181  "</statistics>";
182 
183  static const int snulsz = strlen(snul);
184  static const int ovrhed = 256+strlen(sgen)+strlen(tail);
185  XrdSysTimer myTimer;
186  char *bp;
187  int n, bl, sz, do_sync = (opts & XRD_STATS_SYNC ? 1 : 0);
188 
189 // If buffer is not allocated, do it now. We must defer buffer allocation
190 // until all components that can provide statistics have been loaded
191 //
192  if (!(bp = buff))
193  {blen = InfoStats(0,0) + BuffPool->Stats(0,0) + XrdLink::Stats(0,0)
194  + ProcStats(0,0) + XrdSched->Stats(0,0) + XrdPoll::Stats(0,0)
195  + XrdProtLoad::Statistics(0,0) + ovrhed + Hlen;
196  if (posix_memalign((void **)&buff, getpagesize(), blen+256)) buff = 0;
197  if (!(bp = buff)) {rsz = snulsz; return snul;}
198  }
199  bl = blen;
200 
201 // Start the time if need be
202 //
203  if (opts & XRD_STATS_SGEN) myTimer.Reset();
204 
205 // Insert the heading
206 //
207  sz = sprintf(buff, Head, static_cast<long>(time(0)));
208  bl -= sz; bp += sz;
209 
210 // Extract out the statistics, as needed
211 //
212  if (opts & XRD_STATS_INFO)
213  {sz = InfoStats(bp, bl, do_sync);
214  bp += sz; bl -= sz;
215  }
216 
217  if (opts & XRD_STATS_BUFF)
218  {sz = BuffPool->Stats(bp, bl, do_sync);
219  bp += sz; bl -= sz;
220  }
221 
222  if (opts & XRD_STATS_LINK)
223  {sz = XrdLink::Stats(bp, bl, do_sync);
224  bp += sz; bl -= sz;
225  }
226 
227  if (opts & XRD_STATS_POLL)
228  {sz = XrdPoll::Stats(bp, bl, do_sync);
229  bp += sz; bl -= sz;
230  }
231 
232  if (opts & XRD_STATS_PROC)
233  {sz = ProcStats(bp, bl, do_sync);
234  bp += sz; bl -= sz;
235  }
236 
237  if (opts & XRD_STATS_PROT)
238  {sz = XrdProtLoad::Statistics(bp, bl, do_sync);
239  bp += sz; bl -= sz;
240  }
241 
242  if (opts & XRD_STATS_SCHD)
243  {sz = XrdSched->Stats(bp, bl, do_sync);
244  bp += sz; bl -= sz;
245  }
246 
247  if (opts & XRD_STATS_SGEN)
248  {unsigned long totTime = 0;
249  myTimer.Report(totTime);
250  sz = snprintf(bp,bl,sgen,do_sync==0,totTime,static_cast<long>(time(0)));
251  bp += sz; bl -= sz;
252  }
253 
254  sz = bp - buff;
255  if (bl > 0) n = strlcpy(bp, tail, bl);
256  else n = 0;
257  rsz = sz + (n >= bl ? bl : n);
258  return buff;
259 }
260 
261 /******************************************************************************/
262 /* I n f o S t a t s */
263 /******************************************************************************/
264 
265 int XrdStats::InfoStats(char *bfr, int bln, int do_sync)
266 {
267  static const char statfmt[] = "<stats id=\"info\"><host>%s</host>"
268  "<port>%d</port><name>%s</name></stats>";
269 
270 // Check if actual length wanted
271 //
272  if (!bfr) return sizeof(statfmt)+24 + strlen(myHost);
273 
274 // Format the statistics
275 //
276  return snprintf(bfr, bln, statfmt, myHost, myPort, myName);
277 }
278 
279 /******************************************************************************/
280 /* P r o c S t a t s */
281 /******************************************************************************/
282 
283 int XrdStats::ProcStats(char *bfr, int bln, int do_sync)
284 {
285  static const char statfmt[] = "<stats id=\"proc\">"
286  "<usr><s>%lld</s><u>%lld</u></usr>"
287  "<sys><s>%lld</s><u>%lld</u></sys>"
288  "</stats>";
289  struct rusage r_usage;
290  long long utime_sec, utime_usec, stime_sec, stime_usec;
291 // long long ru_maxrss, ru_majflt, ru_nswap, ru_inblock, ru_oublock;
292 // long long ru_msgsnd, ru_msgrcv, ru_nsignals;
293 
294 // Check if actual length wanted
295 //
296  if (!bfr) return sizeof(statfmt)+16*13;
297 
298 // Get the statistics
299 //
300  if (getrusage(RUSAGE_SELF, &r_usage)) return 0;
301 
302 // Convert fields to correspond to the format we are using. Commented out fields
303 // are either not uniformaly reported or are incorrectly reported making them
304 // useless across multiple platforms.
305 //
306 //
307  utime_sec = static_cast<long long>(r_usage.ru_utime.tv_sec);
308  utime_usec = static_cast<long long>(r_usage.ru_utime.tv_usec);
309  stime_sec = static_cast<long long>(r_usage.ru_stime.tv_sec);
310  stime_usec = static_cast<long long>(r_usage.ru_stime.tv_usec);
311 // ru_maxrss = static_cast<long long>(r_usage.ru_maxrss);
312 // ru_majflt = static_cast<long long>(r_usage.ru_majflt);
313 // ru_nswap = static_cast<long long>(r_usage.ru_nswap);
314 // ru_inblock = static_cast<long long>(r_usage.ru_inblock);
315 // ru_oublock = static_cast<long long>(r_usage.ru_oublock);
316 // ru_msgsnd = static_cast<long long>(r_usage.ru_msgsnd);
317 // ru_msgrcv = static_cast<long long>(r_usage.ru_msgrcv);
318 // ru_nsignals = static_cast<long long>(r_usage.ru_nsignals);
319 
320 // Format the statistics
321 //
322  return snprintf(bfr, bln, statfmt,
323  utime_sec, utime_usec, stime_sec, stime_usec
324 // ru_maxrss, ru_majflt, ru_nswap, ru_inblock, ru_oublock,
325 // ru_msgsnd, ru_msgrcv, ru_nsignals
326  );
327 }
struct myOpts opts
#define XRD_STATS_POLL
Definition: XrdStats.hh:40
#define XRD_STATS_SYNC
Definition: XrdStats.hh:45
#define XRD_STATS_INFO
Definition: XrdStats.hh:37
#define XRD_STATS_LINK
Definition: XrdStats.hh:39
#define XRD_STATS_BUFF
Definition: XrdStats.hh:38
#define XRD_STATS_SYNCA
Definition: XrdStats.hh:46
#define XRD_STATS_SCHD
Definition: XrdStats.hh:43
#define XRD_STATS_ALL
Definition: XrdStats.hh:36
#define XRD_STATS_PROT
Definition: XrdStats.hh:42
#define XRD_STATS_PROC
Definition: XrdStats.hh:41
#define XRD_STATS_SGEN
Definition: XrdStats.hh:44
size_t strlcpy(char *dst, const char *src, size_t sz)
int Stats(char *buff, int blen, int do_sync=0)
Definition: XrdBuffer.cc:323
Definition: XrdJob.hh:43
int Send(const char *buff, int blen=0, const char *dest=0, int tmo=-1)
Definition: XrdNetMsg.cc:70
static int Stats(char *buff, int blen, int do_sync=0)
Definition: XrdPoll.cc:332
static int Statistics(char *buff, int blen, int do_sync=0)
Definition: XrdProtLoad.cc:256
int Stats(char *buff, int blen, int do_sync=0)
void Schedule(XrdJob *jp)
void DoIt()
Definition: XrdStats.cc:61
~XrdStatsJob()
Definition: XrdStats.cc:69
XrdStatsJob(XrdScheduler *schP, XrdStats *sP, int iV)
Definition: XrdStats.cc:65
virtual void Info(const char *data, int dlen)=0
XrdStats(XrdSysError *eP, XrdScheduler *sP, XrdBuffManager *bP, const char *hn, int port, const char *in, const char *pn, const char *sn)
Definition: XrdStats.cc:80
void Report(char **Dest=0, int iVal=600, int Opts=0)
Definition: XrdStats.cc:108
virtual void Stats(CallBack *InfoBack, int opts)
Definition: XrdStats.cc:150
void Reset()
Definition: XrdSysTimer.hh:61
unsigned long Report(double &)
Definition: XrdSysTimer.cc:100
int Opts
Definition: XrdMpxStats.cc:58