XRootD
Loading...
Searching...
No Matches
XrdSysTrace.cc
Go to the documentation of this file.
1/******************************************************************************/
2/* */
3/* X r d S y s T r a c e . h h */
4/* */
5/* (c) 2016 by the Board of Trustees of the Leland Stanford, Jr., University */
6/* All Rights Reserved */
7/* Produced by Andrew Hanushevsky for Stanford University under contract */
8/* DE-AC02-76-SFO0515 with the Department of Energy */
9/* */
10/* This file is part of the XRootD software suite. */
11/* */
12/* XRootD is free software: you can redistribute it and/or modify it under */
13/* the terms of the GNU Lesser General Public License as published by the */
14/* Free Software Foundation, either version 3 of the License, or (at your */
15/* option) any later version. */
16/* */
17/* XRootD is distributed in the hope that it will be useful, but WITHOUT */
18/* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
19/* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */
20/* License for more details. */
21/* */
22/* You should have received a copy of the GNU Lesser General Public License */
23/* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */
24/* COPYING (GPL license). If not, see <http://www.gnu.org/licenses/>. */
25/* */
26/* The copyright holder's institutional names and contributor's names may not */
27/* be used to endorse or promote products derived from this software without */
28/* specific prior written permission of the institution or contributor. */
29/******************************************************************************/
30
31#include <cstdio>
32
33#include "XrdSys/XrdSysFD.hh"
35#include "XrdSys/XrdSysTrace.hh"
36
37/******************************************************************************/
38/* C o n v e r s i o n F u n c t i o n s */
39/******************************************************************************/
40
41namespace
42{
44
45void ToMsgCB(int iovcnt, struct iovec *iov)
46{
47 std::string msg;
48 int n = 0;
49
50 for (int i = 2; i < iovcnt; i++) n += iov[i].iov_len;
51
52 msg.reserve(n+1);
53
54 for (int i = 2; i < iovcnt; i++)
55 msg.append((const char *)iov[i].iov_base, iov[i].iov_len);
56
57 msgCB((const char *)iov[1].iov_base, msg.c_str(), true);
58}
59}
60
61/******************************************************************************/
62/* S e t L o g g e r */
63/******************************************************************************/
64
65void XrdSysTrace::SetLogger(XrdSysLogger *logp) {logP = logp;}
66
67void XrdSysTrace::SetLogger(msgCB_t cbP) {msgCB = cbP;}
68
69/******************************************************************************/
70/* B e g */
71/******************************************************************************/
72
74 const char *epn,
75 const char *txt)
76{
77 char fmt[16];
78 const char *fmt1, *fmt2, *fmt3;
79 int n;
80
81// Generate prefix format (way too complicated)
82//
83 if (usr) fmt1 = "%s ";
84 else {usr = "", fmt1 = "%s";}
85 if (epn) fmt2 = "%s_%s: ";
86 else {epn = ""; fmt2 = "%s%s: ";}
87 if (txt) fmt3 = "%s";
88 else {txt = ""; fmt3 = "";}
89 sprintf(fmt, "%s%s%s", fmt1, fmt2, fmt3);
90
91// Format the header
92//
93 myMutex.Lock();
94 n = snprintf(pBuff, sizeof(pBuff), fmt, usr, iName, epn, txt);
95 if (n >= (int)sizeof(pBuff)) n = sizeof(pBuff)-1;
96
97// Start the trace procedure
98//
99 ioVec[0].iov_base = 0; ioVec[0].iov_len = 0;
100 ioVec[1].iov_base = pBuff; ioVec[1].iov_len = n;
101
102// Reset ourselves
103//
104 dPnt = 0;
105 dFree = txtMax;
106 vPnt = 2;
107
108// All done
109//
110 return *this;
111}
112
113/******************************************************************************/
114/* E n d */
115/******************************************************************************/
116
118{
119 (void)val;
120
121// Make sure an endline character appears
122//
123 if (vPnt >= iovMax) vPnt = iovMax-1;
124 ioVec[vPnt] .iov_base = (char *)"\n";
125 ioVec[vPnt++].iov_len = 1;
126
127// Output the line
128//
129 if (logP) logP->Put(vPnt, ioVec);
130 else if (msgCB) ToMsgCB(vPnt, ioVec);
131 else {static XrdSysLogger tLog(XrdSysFD_Dup(STDERR_FILENO), 0);
132 tLog.Put(vPnt, ioVec);
133 }
134
135// All done
136//
137 myMutex.UnLock();
138 return *this;
139}
140
141/******************************************************************************/
142/* < < b o o l */
143/******************************************************************************/
144
146{
147
148// If we have enough space then format the value
149//
150 if (vPnt < iovMax)
151 {if (val)
152 {ioVec[vPnt] .iov_base = (char *)"True";
153 ioVec[vPnt++].iov_len = 4;
154 } else {
155 ioVec[vPnt] .iov_base = (char *)"False";
156 ioVec[vPnt++].iov_len = 5;
157 }
158 }
159 return *this;
160}
161
162/******************************************************************************/
163/* < < c h a r */
164/******************************************************************************/
165
167{
168 static char hv[] = "0123456789abcdef";
169
170// If we have enough space then format the value
171//
172 if (vPnt < iovMax && dFree > 1)
173 {if (doFmt)
174 {if (doFmt & Xrd::hex)
175 {ioVec[vPnt].iov_base = (char *)(&dBuff[dPnt]);
176 if (doFmt & Xrd::hex)
177 {ioVec[vPnt++].iov_len = 2;
178 dBuff[dPnt++] = hv[(val >> 4) & 0x0f];
179 dBuff[dPnt++] = hv[ val & 0xf0];
180 dFree -= 2;
181 } else if (doFmt & Xrd::oct && dFree > 2) {
182 ioVec[vPnt++].iov_len = 3;
183 dBuff[dPnt+2] = hv[val & 0x07]; val >>= 3;
184 dBuff[dPnt+1] = hv[val & 0x07]; val >>= 3;
185 dBuff[dPnt+1] = hv[val & 0x03];
186 dPnt += 3;
187 dFree -= 3;
188 }
189 }
190 if (doFmt & doOne) doFmt = Xrd::dec;
191 } else {
192 ioVec[vPnt] .iov_base = (char *)(&dBuff[dPnt]);
193 ioVec[vPnt++].iov_len = 1;
194 dBuff[dPnt++] = val; dFree--;
195 }
196 }
197 return *this;
198}
199
200/******************************************************************************/
201/* < < c o n s t c h a r * */
202/******************************************************************************/
203
205{
206
207// If we have enough space then format the value
208//
209 if (vPnt < iovMax)
210 {ioVec[vPnt] .iov_base = (char *)val;
211 ioVec[vPnt++].iov_len = strlen(val);
212 }
213 return *this;
214}
215
216
217/******************************************************************************/
218/* < < std::string */
219/******************************************************************************/
220XrdSysTrace& XrdSysTrace::operator<<(const std::string& val)
221{
222 return (*this << val.c_str());
223}
224
225/******************************************************************************/
226/* < < s h o r t */
227/******************************************************************************/
228
230{
231 static const int xSz = sizeof("-32768");
232
233// If we have enough space then format the value
234//
235 if (dFree >= xSz && vPnt < iovMax)
236 {const char *fmt = (doFmt ? (doFmt & Xrd::hex ? "%hx" : "%ho") : "%hd");
237 int n = snprintf(&dBuff[dPnt], dFree, fmt, val);
238 if (n > dFree) dFree = 0;
239 else {ioVec[vPnt] .iov_base = &dBuff[dPnt];
240 ioVec[vPnt++].iov_len = n;
241 dPnt += n; dFree -= n;
242 }
243 }
244 if (doFmt & doOne) doFmt = Xrd::dec;
245 return *this;
246}
247
248/******************************************************************************/
249/* < < i n t */
250/******************************************************************************/
251
253{
254 static const int xSz = sizeof("-2147483648");
255
256// If we have enough space then format the value
257//
258 if (dFree >= xSz && vPnt < iovMax)
259 {const char *fmt = (doFmt ? (doFmt & Xrd::hex ? "%x" : "%o") : "%d");
260 int n = snprintf(&dBuff[dPnt], dFree, fmt, val);
261 if (n > dFree) dFree = 0;
262 else {ioVec[vPnt] .iov_base = &dBuff[dPnt];
263 ioVec[vPnt++].iov_len = n;
264 dPnt += n; dFree -= n;
265 }
266 }
267 if (doFmt & doOne) doFmt = Xrd::dec;
268 return *this;
269}
270
271/******************************************************************************/
272/* < < l o n g */
273/******************************************************************************/
274
276{
277
278// Fan out based on length of a long
279//
280 if (sizeof(long) > 4) return *this<<static_cast<long long>(val);
281 else return *this<<static_cast<int>(val);
282}
283
284/******************************************************************************/
285/* < < l o n g l o n g */
286/******************************************************************************/
287
289{
290 static const int xSz = sizeof("-9223372036854775808");
291
292// If we have enough space then format the value
293//
294 if (dFree >= xSz && vPnt < iovMax)
295 {const char *fmt = (doFmt ? (doFmt & Xrd::hex ? "%llx" : "%llo") : "%lld");
296 int n = snprintf(&dBuff[dPnt], dFree, fmt, val);
297 if (n > dFree) dFree = 0;
298 else {ioVec[vPnt] .iov_base = &dBuff[dPnt];
299 ioVec[vPnt++].iov_len = n;
300 dPnt += n; dFree -= n;
301 }
302 }
303 if (doFmt & doOne) doFmt = Xrd::dec;
304 return *this;
305}
306
307/******************************************************************************/
308/* < < u n s i g n e d s h o r t */
309/******************************************************************************/
310
312{
313 static const int xSz = sizeof("65535");
314
315// If we have enough space then format the value
316//
317 if (dFree >= xSz && vPnt < iovMax)
318 {const char *fmt = (doFmt ? (doFmt & Xrd::hex ? "%hx" : "%ho") : "%hu");
319 int n = snprintf(&dBuff[dPnt], dFree, fmt, val);
320 if (n > dFree) dFree = 0;
321 else {ioVec[vPnt] .iov_base = &dBuff[dPnt];
322 ioVec[vPnt++].iov_len = n;
323 dPnt += n; dFree -= n;
324 }
325 }
326 if (doFmt & doOne) doFmt = Xrd::dec;
327 return *this;
328}
329
330/******************************************************************************/
331/* < < u n s i g n e d i n t */
332/******************************************************************************/
333
335{
336 static const int xSz = sizeof("4294967295");
337
338// If we have enough space then format the value
339//
340 if (dFree >= xSz && vPnt < iovMax)
341 {const char *fmt = (doFmt ? (doFmt & Xrd::hex ? "%x" : "%o") : "%u");
342 int n = snprintf(&dBuff[dPnt], dFree, fmt, val);
343 if (n > dFree) dFree = 0;
344 else {ioVec[vPnt] .iov_base = &dBuff[dPnt];
345 ioVec[vPnt++].iov_len = n;
346 dPnt += n; dFree -= n;
347 }
348 }
349 if (doFmt & doOne) doFmt = Xrd::dec;
350 return *this;
351}
352
353/******************************************************************************/
354/* < < u n s i g n e d l o n g */
355/******************************************************************************/
356
358{
359
360// Fan out based on length of a long
361//
362 if (sizeof(long) > 4) return *this<<static_cast<unsigned long long>(val);
363 else return *this<<static_cast<unsigned int>(val);
364}
365
366/******************************************************************************/
367/* < < u n s i g n e d l o n g l o n g */
368/******************************************************************************/
369
370XrdSysTrace& XrdSysTrace::operator<<(unsigned long long val)
371{
372 static const int xSz = sizeof("18446744073709551615");
373
374// If we have enough space then format the value
375//
376 if (dFree >= xSz && vPnt < iovMax)
377 {const char *fmt = (doFmt ? (doFmt & Xrd::hex ? "%llx" : "%llo") : "%llu");
378 int n = snprintf(&dBuff[dPnt], dFree, fmt, val);
379 if (n > dFree) dFree = 0;
380 else {ioVec[vPnt] .iov_base = &dBuff[dPnt];
381 ioVec[vPnt++].iov_len = n;
382 dPnt += n; dFree -= n;
383 }
384 }
385 if (doFmt & doOne) doFmt = Xrd::dec;
386 return *this;
387}
388
389/******************************************************************************/
390/* < < v o i d * */
391/******************************************************************************/
392
394{
395 static const int xSz = sizeof(void *)*2+1;
396
397// If we have enough space then format the value
398//
399 if (dFree >= xSz && vPnt < iovMax)
400 {int n = snprintf(&dBuff[dPnt], dFree, "%p", val);
401 if (n > dFree) dFree = 0;
402 else {ioVec[vPnt] .iov_base = &dBuff[dPnt];
403 ioVec[vPnt++].iov_len = n;
404 dPnt += n; dFree -= n;
405 }
406 }
407 return *this;
408}
409
410/******************************************************************************/
411/* < < l o n g d o u b l e */
412/******************************************************************************/
413
414XrdSysTrace& XrdSysTrace::Insert(long double val)
415{
416 char tmp[32];
417 int n;
418
419// Gaurd against iovec overflows
420//
421if (vPnt < iovMax)
422 {
423
424// Convert the value into the temporary buffer
425//
426 n = snprintf(tmp, sizeof(tmp), "%Lg", val);
427
428// If we have enough space then format the value
429//
430 if (dFree > n && n < (int)sizeof(tmp))
431 {ioVec[vPnt] .iov_base = &dBuff[dPnt];
432 ioVec[vPnt++].iov_len = n;
433 strcpy(&dBuff[dPnt], tmp);
434 dPnt += n; dFree -= n;
435 }
436 }
437 return *this;
438}
void Put(int iovcnt, struct iovec *iov)
XrdSysTrace & Beg(const char *usr=0, const char *epn=0, const char *txt=0)
void(* msgCB_t)(const char *tid, const char *msg, bool dbgmsg)
XrdSysTrace & operator<<(bool val)
void SetLogger(XrdSysLogger *logp)
XrdSsiLogger::MCB_t * msgCB