Loading...
Searching...
No Matches
XrdSysTrace.cc
Go to the documentation of this file.
/******************************************************************************/
/* */
/* X r d S y s T r a c e . h h */
/* */
/* (c) 2016 by the Board of Trustees of the Leland Stanford, Jr., University */
/* All Rights Reserved */
/* Produced by Andrew Hanushevsky for Stanford University under contract */
/* DE-AC02-76-SFO0515 with the Department of Energy */
/* */
/* This file is part of the XRootD software suite. */
/* */
/* XRootD is free software: you can redistribute it and/or modify it under */
/* the terms of the GNU Lesser General Public License as published by the */
/* Free Software Foundation, either version 3 of the License, or (at your */
/* option) any later version. */
/* */
/* XRootD is distributed in the hope that it will be useful, but WITHOUT */
/* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
/* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */
/* License for more details. */
/* */
/* You should have received a copy of the GNU Lesser General Public License */
/* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */
/* COPYING (GPL license). If not, see <http://www.gnu.org/licenses/>. */
/* */
/* The copyright holder's institutional names and contributor's names may not */
/* be used to endorse or promote products derived from this software without */
/* specific prior written permission of the institution or contributor. */
/******************************************************************************/
#include <cstdio>
#include "XrdSys/XrdSysFD.hh"
#include "XrdSys/XrdSysLogger.hh"
#include "XrdSys/XrdSysTrace.hh"
/******************************************************************************/
/* C o n v e r s i o n F u n c t i o n s */
/******************************************************************************/
namespace
{
XrdSysTrace::msgCB_t msgCB = 0;
void ToMsgCB(int iovcnt, struct iovec *iov)
{
std::string msg;
int n = 0;
for (int i = 2; i < iovcnt; i++) n += iov[i].iov_len;
msg.reserve(n+1);
for (int i = 2; i < iovcnt; i++)
msg.append((const char *)iov[i].iov_base, iov[i].iov_len);
msgCB((const char *)iov[1].iov_base, msg.c_str(), true);
}
}
/******************************************************************************/
/* S e t L o g g e r */
/******************************************************************************/
void XrdSysTrace::SetLogger(XrdSysLogger *logp) {logP = logp;}
void XrdSysTrace::SetLogger(msgCB_t cbP) {msgCB = cbP;}
/******************************************************************************/
/* B e g */
/******************************************************************************/
XrdSysTrace& XrdSysTrace::Beg(const char *usr,
const char *epn,
const char *txt)
{
char fmt[16];
const char *fmt1, *fmt2, *fmt3;
int n;
// Generate prefix format (way too complicated)
//
if (usr) fmt1 = "%s ";
else {usr = "", fmt1 = "%s";}
if (epn) fmt2 = "%s_%s: ";
else {epn = ""; fmt2 = "%s%s: ";}
if (txt) fmt3 = "%s";
else {txt = ""; fmt3 = "";}
sprintf(fmt, "%s%s%s", fmt1, fmt2, fmt3);
// Format the header
//
myMutex.Lock();
n = snprintf(pBuff, sizeof(pBuff), fmt, usr, iName, epn, txt);
if (n >= (int)sizeof(pBuff)) n = sizeof(pBuff)-1;
// Start the trace procedure
//
ioVec[0].iov_base = 0; ioVec[0].iov_len = 0;
ioVec[1].iov_base = pBuff; ioVec[1].iov_len = n;
// Reset ourselves
//
dPnt = 0;
dFree = txtMax;
vPnt = 2;
// All done
//
return *this;
}
/******************************************************************************/
/* E n d */
/******************************************************************************/
XrdSysTrace& XrdSysTrace::operator<<(XrdSysTrace *val)
{
(void)val;
// Make sure an endline character appears
//
if (vPnt >= iovMax) vPnt = iovMax-1;
ioVec[vPnt] .iov_base = (char *)"\n";
ioVec[vPnt++].iov_len = 1;
// Output the line
//
if (logP) logP->Put(vPnt, ioVec);
else if (msgCB) ToMsgCB(vPnt, ioVec);
else {static XrdSysLogger tLog(XrdSysFD_Dup(STDERR_FILENO), 0);
tLog.Put(vPnt, ioVec);
}
// All done
//
myMutex.UnLock();
return *this;
}
/******************************************************************************/
/* < < b o o l */
/******************************************************************************/
XrdSysTrace& XrdSysTrace::operator<<(bool val)
{
// If we have enough space then format the value
//
if (vPnt < iovMax)
{if (val)
{ioVec[vPnt] .iov_base = (char *)"True";
ioVec[vPnt++].iov_len = 4;
} else {
ioVec[vPnt] .iov_base = (char *)"False";
ioVec[vPnt++].iov_len = 5;
}
}
return *this;
}
/******************************************************************************/
/* < < c h a r */
/******************************************************************************/
XrdSysTrace& XrdSysTrace::operator<<(char val)
{
static const char hv[] = "0123456789abcdef";
// If we have enough space then format the value
//
if (vPnt < iovMax && dFree > 1)
{if (doFmt)
{if (doFmt & Xrd::hex)
{ioVec[vPnt].iov_base = (char *)(&dBuff[dPnt]);
if (doFmt & Xrd::hex)
{ioVec[vPnt++].iov_len = 2;
dBuff[dPnt++] = hv[(val >> 4) & 0x0f];
dBuff[dPnt++] = hv[ val & 0xf0];
dFree -= 2;
} else if (doFmt & Xrd::oct && dFree > 2) {
ioVec[vPnt++].iov_len = 3;
dBuff[dPnt+2] = hv[val & 0x07]; val >>= 3;
dBuff[dPnt+1] = hv[val & 0x07]; val >>= 3;
dBuff[dPnt+1] = hv[val & 0x03];
dPnt += 3;
dFree -= 3;
}
}
if (doFmt & doOne) doFmt = Xrd::dec;
} else {
ioVec[vPnt] .iov_base = (char *)(&dBuff[dPnt]);
ioVec[vPnt++].iov_len = 1;
dBuff[dPnt++] = val; dFree--;
}
}
return *this;
}
/******************************************************************************/
/* < < c o n s t c h a r * */
/******************************************************************************/
XrdSysTrace& XrdSysTrace::operator<<(const char *val)
{
// If we have enough space then format the value
//
if (vPnt < iovMax)
{ioVec[vPnt] .iov_base = (char *)val;
ioVec[vPnt++].iov_len = strlen(val);
}
return *this;
}
/******************************************************************************/
/* < < std::string */
/******************************************************************************/
XrdSysTrace& XrdSysTrace::operator<<(const std::string& val)
{
return (*this << val.c_str());
}
/******************************************************************************/
/* < < s h o r t */
/******************************************************************************/
XrdSysTrace& XrdSysTrace::operator<<(short val)
{
static const int xSz = sizeof("-32768");
// If we have enough space then format the value
//
if (dFree >= xSz && vPnt < iovMax)
{const char *fmt = (doFmt ? (doFmt & Xrd::hex ? "%hx" : "%ho") : "%hd");
int n = snprintf(&dBuff[dPnt], dFree, fmt, val);
if (n > dFree) dFree = 0;
else {ioVec[vPnt] .iov_base = &dBuff[dPnt];
ioVec[vPnt++].iov_len = n;
dPnt += n; dFree -= n;
}
}
if (doFmt & doOne) doFmt = Xrd::dec;
return *this;
}
/******************************************************************************/
/* < < i n t */
/******************************************************************************/
XrdSysTrace& XrdSysTrace::operator<<(int val)
{
static const int xSz = sizeof("-2147483648");
// If we have enough space then format the value
//
if (dFree >= xSz && vPnt < iovMax)
{const char *fmt = (doFmt ? (doFmt & Xrd::hex ? "%x" : "%o") : "%d");
int n = snprintf(&dBuff[dPnt], dFree, fmt, val);
if (n > dFree) dFree = 0;
else {ioVec[vPnt] .iov_base = &dBuff[dPnt];
ioVec[vPnt++].iov_len = n;
dPnt += n; dFree -= n;
}
}
if (doFmt & doOne) doFmt = Xrd::dec;
return *this;
}
/******************************************************************************/
/* < < l o n g */
/******************************************************************************/
XrdSysTrace& XrdSysTrace::operator<<(long val)
{
// Fan out based on length of a long
//
if (sizeof(long) > 4) return *this<<static_cast<long long>(val);
else return *this<<static_cast<int>(val);
}
/******************************************************************************/
/* < < l o n g l o n g */
/******************************************************************************/
XrdSysTrace& XrdSysTrace::operator<<(long long val)
{
static const int xSz = sizeof("-9223372036854775808");
// If we have enough space then format the value
//
if (dFree >= xSz && vPnt < iovMax)
{const char *fmt = (doFmt ? (doFmt & Xrd::hex ? "%llx" : "%llo") : "%lld");
int n = snprintf(&dBuff[dPnt], dFree, fmt, val);
if (n > dFree) dFree = 0;
else {ioVec[vPnt] .iov_base = &dBuff[dPnt];
ioVec[vPnt++].iov_len = n;
dPnt += n; dFree -= n;
}
}
if (doFmt & doOne) doFmt = Xrd::dec;
return *this;
}
/******************************************************************************/
/* < < u n s i g n e d s h o r t */
/******************************************************************************/
XrdSysTrace& XrdSysTrace::operator<<(unsigned short val)
{
static const int xSz = sizeof("65535");
// If we have enough space then format the value
//
if (dFree >= xSz && vPnt < iovMax)
{const char *fmt = (doFmt ? (doFmt & Xrd::hex ? "%hx" : "%ho") : "%hu");
int n = snprintf(&dBuff[dPnt], dFree, fmt, val);
if (n > dFree) dFree = 0;
else {ioVec[vPnt] .iov_base = &dBuff[dPnt];
ioVec[vPnt++].iov_len = n;
dPnt += n; dFree -= n;
}
}
if (doFmt & doOne) doFmt = Xrd::dec;
return *this;
}
/******************************************************************************/
/* < < u n s i g n e d i n t */
/******************************************************************************/
XrdSysTrace& XrdSysTrace::operator<<(unsigned int val)
{
static const int xSz = sizeof("4294967295");
// If we have enough space then format the value
//
if (dFree >= xSz && vPnt < iovMax)
{const char *fmt = (doFmt ? (doFmt & Xrd::hex ? "%x" : "%o") : "%u");
int n = snprintf(&dBuff[dPnt], dFree, fmt, val);
if (n > dFree) dFree = 0;
else {ioVec[vPnt] .iov_base = &dBuff[dPnt];
ioVec[vPnt++].iov_len = n;
dPnt += n; dFree -= n;
}
}
if (doFmt & doOne) doFmt = Xrd::dec;
return *this;
}
/******************************************************************************/
/* < < u n s i g n e d l o n g */
/******************************************************************************/
XrdSysTrace& XrdSysTrace::operator<<(unsigned long val)
{
// Fan out based on length of a long
//
if (sizeof(long) > 4) return *this<<static_cast<unsigned long long>(val);
else return *this<<static_cast<unsigned int>(val);
}
/******************************************************************************/
/* < < u n s i g n e d l o n g l o n g */
/******************************************************************************/
XrdSysTrace& XrdSysTrace::operator<<(unsigned long long val)
{
static const int xSz = sizeof("18446744073709551615");
// If we have enough space then format the value
//
if (dFree >= xSz && vPnt < iovMax)
{const char *fmt = (doFmt ? (doFmt & Xrd::hex ? "%llx" : "%llo") : "%llu");
int n = snprintf(&dBuff[dPnt], dFree, fmt, val);
if (n > dFree) dFree = 0;
else {ioVec[vPnt] .iov_base = &dBuff[dPnt];
ioVec[vPnt++].iov_len = n;
dPnt += n; dFree -= n;
}
}
if (doFmt & doOne) doFmt = Xrd::dec;
return *this;
}
/******************************************************************************/
/* < < v o i d * */
/******************************************************************************/
XrdSysTrace& XrdSysTrace::operator<<(void *val)
{
static const int xSz = sizeof(void *)*2+1;
// If we have enough space then format the value
//
if (dFree >= xSz && vPnt < iovMax)
{int n = snprintf(&dBuff[dPnt], dFree, "%p", val);
if (n > dFree) dFree = 0;
else {ioVec[vPnt] .iov_base = &dBuff[dPnt];
ioVec[vPnt++].iov_len = n;
dPnt += n; dFree -= n;
}
}
return *this;
}
/******************************************************************************/
/* < < l o n g d o u b l e */
/******************************************************************************/
XrdSysTrace& XrdSysTrace::Insert(long double val)
{
char tmp[32];
int n;
// Gaurd against iovec overflows
//
if (vPnt < iovMax)
{
// Convert the value into the temporary buffer
//
n = snprintf(tmp, sizeof(tmp), "%Lg", val);
// If we have enough space then format the value
//
if (dFree > n && n < (int)sizeof(tmp))
{ioVec[vPnt] .iov_base = &dBuff[dPnt];
ioVec[vPnt++].iov_len = n;
strcpy(&dBuff[dPnt], tmp);
dPnt += n; dFree -= n;
}
}
return *this;
}
XrdSysFD.hh
XrdSysLogger.hh
XrdSysTrace.hh
XrdSysLogger
Definition XrdSysLogger.hh:53
XrdSysLogger::Put
void Put(int iovcnt, struct iovec *iov)
Definition XrdSysLogger.cc:330
XrdSysTrace
Definition XrdSysTrace.hh:49
XrdSysTrace::XrdSysTrace
XrdSysTrace(const char *pfx, XrdSysLogger *logp=0, int tf=0)
Definition XrdSysTrace.hh:95
XrdSysTrace::Beg
XrdSysTrace & Beg(const char *usr=0, const char *epn=0, const char *txt=0)
Definition XrdSysTrace.cc:73
XrdSysTrace::msgCB_t
void(* msgCB_t)(const char *tid, const char *msg, bool dbgmsg)
Definition XrdSysTrace.hh:58
XrdSysTrace::operator<<
XrdSysTrace & operator<<(bool val)
Definition XrdSysTrace.cc:145
XrdSysTrace::SetLogger
void SetLogger(XrdSysLogger *logp)
Definition XrdSysTrace.cc:65
XrdSsi::msgCB
XrdSsiLogger::MCB_t * msgCB
Definition XrdSsiLogger.cc:59
Xrd::oct
@ oct
Definition XrdSysTrace.hh:42
Xrd::dec
@ dec
Definition XrdSysTrace.hh:42
Xrd::hex
@ hex
Definition XrdSysTrace.hh:42
iov
Definition XrdOucIOVec.hh:65