/******************************************************************************/ /* */ /* 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 . */ /* */ /* 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 #include "XrdSys/XrdSysFD.hh" #include "XrdSys/XrdSysLogger.hh" #include "XrdSys/XrdSysTrace.hh" /******************************************************************************/ /* G l o b a l T r a c i n g O b j e c t s */ /******************************************************************************/ // The following objects are defined centrally for all components of the stack. // The naming convention is: XrdSysTrace // XrdSysTrace XrdSysTraceXrd("xrd_"); /******************************************************************************/ /* 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) { // Make sure and 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 {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 char hv[] = "0123456789abcdef"; // If we have enough space then format the value // if (vPnt < iovMax && dFree > 1) {if (doHex) {ioVec[vPnt] .iov_base = (char *)(&dBuff[dPnt]); ioVec[vPnt++].iov_len = 2; dBuff[dPnt++] = hv[(val >> 4) & 0x0f]; dBuff[dPnt++] = hv[ val & 0xf0]; dFree -= 2; } 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 = (doHex ? "%hx" : "%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; } } 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 = (doHex ? "%x" : "%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; } } 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<(val); else return *this<(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 = (doHex ? "%llx" : "%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; } } 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 = (doHex ? "%hx" : "%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; } } 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 = (doHex ? "%x" : "%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; } } 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<(val); else return *this<(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 = (doHex ? "%llx" : "%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; } } 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; }