|
||||
File indexing completed on 2025-01-30 10:27:53
0001 //------------------------------------------------------------------------------ 0002 // Copyright (c) 2011-2014 by European Organization for Nuclear Research (CERN) 0003 // Author: Lukasz Janyst <ljanyst@cern.ch> 0004 //------------------------------------------------------------------------------ 0005 // This file is part of the XRootD software suite. 0006 // 0007 // XRootD is free software: you can redistribute it and/or modify 0008 // it under the terms of the GNU Lesser General Public License as published by 0009 // the Free Software Foundation, either version 3 of the License, or 0010 // (at your option) any later version. 0011 // 0012 // XRootD is distributed in the hope that it will be useful, 0013 // but WITHOUT ANY WARRANTY; without even the implied warranty of 0014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0015 // GNU General Public License for more details. 0016 // 0017 // You should have received a copy of the GNU Lesser General Public License 0018 // along with XRootD. If not, see <http://www.gnu.org/licenses/>. 0019 // 0020 // In applying this licence, CERN does not waive the privileges and immunities 0021 // granted to it by virtue of its status as an Intergovernmental Organization 0022 // or submit itself to any jurisdiction. 0023 //------------------------------------------------------------------------------ 0024 0025 #ifndef __XRD_CL_LOG_HH__ 0026 #define __XRD_CL_LOG_HH__ 0027 0028 #include <cstdarg> 0029 #include <string> 0030 #include <map> 0031 #include <cstdint> 0032 #include "XrdSys/XrdSysPthread.hh" 0033 0034 //------------------------------------------------------------------------------ 0035 // C++11 atomics are used to avoid illegal behavior when setting/getting the 0036 // log level. To minimize costs across all platforms, we use 0037 // std::memory_order_relaxed; this means threads may reorder SetLogLevel writes 0038 // and the visibility is relatively undefined. However, we know the stores are 0039 // at least atomic. 0040 //------------------------------------------------------------------------------ 0041 #include <atomic> 0042 0043 namespace XrdCl 0044 { 0045 //---------------------------------------------------------------------------- 0046 //! Interface for logger outputs 0047 //---------------------------------------------------------------------------- 0048 class LogOut 0049 { 0050 public: 0051 virtual ~LogOut() {} 0052 0053 //------------------------------------------------------------------------ 0054 //! Write a message to the destination 0055 //! 0056 //! @param message message to be written 0057 //------------------------------------------------------------------------ 0058 virtual void Write( const std::string &message ) = 0; 0059 }; 0060 0061 //---------------------------------------------------------------------------- 0062 //! Write log messages to a file 0063 //---------------------------------------------------------------------------- 0064 class LogOutFile: public LogOut 0065 { 0066 public: 0067 LogOutFile(): pFileDes(-1) {}; 0068 virtual ~LogOutFile() { Close(); }; 0069 0070 //------------------------------------------------------------------------ 0071 //! Open the log file 0072 //------------------------------------------------------------------------ 0073 bool Open( const std::string &fileName ); 0074 0075 //------------------------------------------------------------------------ 0076 //! Close the log file 0077 //------------------------------------------------------------------------ 0078 void Close(); 0079 virtual void Write( const std::string &message ); 0080 0081 private: 0082 int pFileDes; 0083 }; 0084 0085 //---------------------------------------------------------------------------- 0086 //! Write log messages to stderr 0087 //---------------------------------------------------------------------------- 0088 class LogOutCerr: public LogOut 0089 { 0090 public: 0091 virtual void Write( const std::string &message ); 0092 virtual ~LogOutCerr() {} 0093 private: 0094 XrdSysMutex pMutex; 0095 }; 0096 0097 //---------------------------------------------------------------------------- 0098 //! Handle diagnostics 0099 //---------------------------------------------------------------------------- 0100 class Log 0101 { 0102 public: 0103 //------------------------------------------------------------------------ 0104 //! Log levels 0105 //------------------------------------------------------------------------ 0106 enum LogLevel 0107 { 0108 NoMsg = 0, //!< report nothing 0109 ErrorMsg = 1, //!< report errors 0110 WarningMsg = 2, //!< report warnings 0111 InfoMsg = 3, //!< print info 0112 DebugMsg = 4, //!< print debug info 0113 DumpMsg = 5 //!< print details of the request and responses 0114 }; 0115 0116 //------------------------------------------------------------------------ 0117 //! Constructor 0118 //------------------------------------------------------------------------ 0119 Log(): pLevel( NoMsg ), pTopicMaxLength( 18 ), pPid(0) 0120 { 0121 pOutput = new LogOutCerr(); 0122 int maxMask = (int)DumpMsg+1; 0123 for( int i = 0; i < maxMask; ++i ) 0124 pMask[i] = 0xffffffffffffffffULL; 0125 } 0126 0127 //------------------------------------------------------------------------ 0128 // Destructor 0129 //------------------------------------------------------------------------ 0130 ~Log() 0131 { 0132 delete pOutput; 0133 } 0134 0135 //------------------------------------------------------------------------ 0136 //! Report an error 0137 //------------------------------------------------------------------------ 0138 void Error( uint64_t topic, const char *format, ... ); 0139 0140 //------------------------------------------------------------------------ 0141 //! Report a warning 0142 //------------------------------------------------------------------------ 0143 void Warning( uint64_t topic, const char *format, ... ); 0144 0145 //------------------------------------------------------------------------ 0146 //! Print an info 0147 //------------------------------------------------------------------------ 0148 void Info( uint64_t topic, const char *format, ... ); 0149 0150 //------------------------------------------------------------------------ 0151 //! Print a debug message 0152 //------------------------------------------------------------------------ 0153 void Debug( uint64_t topic, const char *format, ... ); 0154 0155 //------------------------------------------------------------------------ 0156 //! Print a dump message 0157 //------------------------------------------------------------------------ 0158 void Dump( uint64_t topic, const char *format, ... ); 0159 0160 //------------------------------------------------------------------------ 0161 //! Always print the message 0162 //! 0163 //! @param level log level 0164 //! @param topic topic of the message 0165 //! @param format format string - the same as in printf 0166 //! @param list list of arguments 0167 //------------------------------------------------------------------------ 0168 void Say( LogLevel level, uint64_t topic, const char *format, va_list list ); 0169 0170 //------------------------------------------------------------------------ 0171 //! Set the level of the messages that should be sent to the destination 0172 //------------------------------------------------------------------------ 0173 void SetLevel( LogLevel level ) 0174 { 0175 #if __cplusplus >= 201103L 0176 pLevel.store(level, std::memory_order_relaxed); 0177 #else 0178 pLevel = level; 0179 #endif 0180 } 0181 0182 //------------------------------------------------------------------------ 0183 //! Set the level of the messages that should be sent to the destination 0184 //------------------------------------------------------------------------ 0185 void SetLevel( const std::string &level ) 0186 { 0187 LogLevel lvl; 0188 if( StringToLogLevel( level, lvl ) ) 0189 SetLevel( lvl ); 0190 } 0191 0192 //------------------------------------------------------------------------ 0193 //! Set the output that should be used. 0194 //------------------------------------------------------------------------ 0195 void SetOutput( LogOut *output ) 0196 { 0197 delete pOutput; 0198 pOutput = output; 0199 } 0200 0201 //------------------------------------------------------------------------ 0202 //! Sets the mask for the topics of messages that should be printed 0203 //------------------------------------------------------------------------ 0204 void SetMask( LogLevel level, uint64_t mask ) 0205 { 0206 pMask[level] = mask; 0207 } 0208 0209 //------------------------------------------------------------------------ 0210 //! Sets the mask for the topics of messages that should be printed 0211 //------------------------------------------------------------------------ 0212 void SetMask( const std::string &level, uint64_t mask ) 0213 { 0214 LogLevel lvl; 0215 if( StringToLogLevel( level, lvl ) ) 0216 pMask[lvl] = mask; 0217 } 0218 0219 //------------------------------------------------------------------------ 0220 //! Map a topic number to a string 0221 //------------------------------------------------------------------------ 0222 void SetTopicName( uint64_t topic, std::string name ); 0223 0224 0225 //------------------------------------------------------------------------ 0226 //! Register new topic 0227 //------------------------------------------------------------------------ 0228 inline uint64_t RegisterTopic( const std::string &topic ) 0229 { 0230 uint64_t tpcnb = pTopicMap.rbegin()->first << 1; 0231 SetTopicName( tpcnb, topic ); 0232 return tpcnb; 0233 } 0234 0235 //------------------------------------------------------------------------ 0236 //! Get the log level 0237 //------------------------------------------------------------------------ 0238 LogLevel GetLevel() const 0239 { 0240 LogLevel lvl = pLevel.load(std::memory_order_relaxed); 0241 return lvl; 0242 } 0243 0244 //------------------------------------------------------------------------ 0245 //! Set pid 0246 //------------------------------------------------------------------------ 0247 void SetPid(pid_t pid) 0248 { 0249 pPid = pid; 0250 } 0251 0252 private: 0253 typedef std::map<uint64_t, std::string> TopicMap; 0254 std::string LogLevelToString( LogLevel level ); 0255 bool StringToLogLevel( const std::string &strLevel, LogLevel &level ); 0256 std::string TopicToString( uint64_t topic ); 0257 0258 std::atomic<LogLevel> pLevel; 0259 0260 uint64_t pMask[DumpMsg+1]; 0261 LogOut *pOutput; 0262 TopicMap pTopicMap; 0263 uint32_t pTopicMaxLength; 0264 pid_t pPid; 0265 }; 0266 } 0267 0268 #endif // __XRD_CL_LOG_HH__
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |