Back to home page

EIC code displayed by LXR

 
 

    


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__