XRootD
Loading...
Searching...
No Matches
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"
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{
59public:
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);}
70private:
71XrdScheduler *Sched;
72XrdStats *Stats;
73int 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
108void 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
175const 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
265int 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
283int 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
friend class XrdScheduler
Definition XrdJob.hh:44
XrdJob(const char *desc="")
Definition XrdJob.hh:51
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)
int Stats(char *buff, int blen, int do_sync=0)
void DoIt()
Definition XrdStats.cc:61
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
unsigned long Report(double &)