/*! * @project XRootD SSI/Protocol Buffer Interface Project * @brief Provides an interface to the XrdSsi log * @copyright Copyright 2018 CERN * @license This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #pragma once #include #include #include #include #include #include #include #include namespace XrdSsi { extern XrdSysError Log; //!< XRootD Log object } namespace XrdSsiPb { /*! * Interface to the XRootD logging object */ class Log { public: /*! * XRootD SSI log level bit values */ enum LogLevel { // Low-order bits are defined by the XRootD framework NONE = 0, XRD_LOGIN = SYS_LOG_01, //!< login and authentication XRD_DISC = SYS_LOG_02, //!< disconnect and unbind RESERVED_03 = SYS_LOG_03, RESERVED_04 = SYS_LOG_04, RESERVED_05 = SYS_LOG_05, RESERVED_06 = SYS_LOG_06, RESERVED_07 = SYS_LOG_07, RESERVED_08 = SYS_LOG_08, // High-order bits are used for our messages ERROR = 1 << 16, //!< Non-fatal error (fatal errors throw an exception) WARNING = 1 << 17, //!< Warning INFO = 1 << 18, //!< Information DEBUG = 1 << 19, //!< Debug information PROTOBUF = 1 << 20, //!< Show Protocol buffer contents PROTORAW = 1 << 21 //!< Show raw Protocol buffer contents }; /*! * The Log class has no instances; it is used for namespacing only. */ Log() = delete; /*! * Set log level from an option list */ static void SetLogLevel(const std::vector &levels) { const std::map option = { { "none", NONE }, { "error", ERROR }, { "warning", ERROR | WARNING }, { "info", ERROR | WARNING | INFO }, { "debug", ERROR | WARNING | INFO | DEBUG }, { "protobuf", PROTOBUF }, { "protoraw", PROTORAW }, { "all", ERROR | WARNING | INFO | DEBUG | PROTOBUF | PROTORAW } }; uint32_t loglevel = XrdSsi::Log.getMsgMask() & 0xFFFF; for(auto it = levels.begin(); it != levels.end(); ++it) { auto level = option.find(*it); if(level == option.end()) { Say("Ignoring unknown option ", *it); } else { loglevel |= level->second; } } XrdSsi::Log.setMsgMask(loglevel); } /*! * Set log level from a single string */ static void SetLogLevel(const std::string &level) { std::vector levels; levels.push_back(level); SetLogLevel(levels); } /*! * Enable microsecond resolution in timestamps */ static void SetHiRes() { XrdSsi::Log.logger()->setHiRes(); } /*! * Add a simple message to the XRootD log (no timestamp, identifiers or log level) */ template static void Say(Args... args) { // Bail out if the XRootD logging subsystem has not been initialised if(XrdSsi::Log.logger() == nullptr) return; std::stringstream logstream; BuildMessage(logstream, args...); XrdSsi::Log.Say(logstream.str().c_str()); } /*! * Add a timestamped message to the XRootD log. * * Log messages take the form: * *