Logo Search packages:      
Sourcecode: poco version File versions  Download package

Logger.h
//
// Logger.h
//
// $Id: //poco/1.3/Foundation/include/Poco/Logger.h#3 $
//
// Library: Foundation
// Package: Logging
// Module:  Logger
//
// Definition of the Logger class.
//
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// Permission is hereby granted, free of charge, to any person or organization
// obtaining a copy of the software and accompanying documentation covered by
// this license (the "Software") to use, reproduce, display, distribute,
// execute, and transmit the Software, and to prepare derivative works of the
// Software, and to permit third-parties to whom the Software is furnished to
// do so, all subject to the following:
// 
// The copyright notices in the Software and this entire statement, including
// the above license grant, this restriction and the following disclaimer,
// must be included in all copies of the Software, in whole or in part, and
// all derivative works of the Software, unless such copies or derivative
// works are solely in the form of machine-executable object code generated by
// a source language processor.
// 
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//


#ifndef Foundation_Logger_INCLUDED
#define Foundation_Logger_INCLUDED


#include "Poco/Foundation.h"
#include "Poco/Channel.h"
#include "Poco/Message.h"
#include <map>
#include <vector>
#include <cstddef>


namespace Poco {


class Exception;


00057 class Foundation_API Logger: public Channel
      /// Logger is a special Channel that acts as the main
      /// entry point into the logging framework.
      ///
      /// An application uses instances of the Logger class to generate its log messages
      /// and send them on their way to their final destination. Logger instances
      /// are organized in a hierarchical, tree-like manner and are maintained by
      /// the framework. Every Logger object has exactly one direct ancestor, with
      /// the exception of the root logger. A newly created logger inherits its properties -
      /// channel and level - from its direct ancestor. Every logger is connected
      /// to a channel, to which it passes on its messages. Furthermore, every logger
      /// has a log level, which is used for filtering messages based on their priority.
      /// Only messages with a priority equal to or higher than the specified level
      /// are passed on. For example, if the level of a logger is set to three (PRIO_ERROR),
      /// only messages with priority PRIO_ERROR, PRIO_CRITICAL and PRIO_FATAL will
      /// propagate. If the level is set to zero, the logger is effectively disabled.
      ///
      /// The name of a logger determines the logger's place within the logger hierarchy.
      /// The name of the root logger is always "", the empty string. For all other
      /// loggers, the name is made up of one or more components, separated by a period.
      /// For example, the loggers with the name HTTPServer.RequestHandler and HTTPServer.Listener
      /// are descendants of the logger HTTPServer, which itself is a descendant of
      /// the root logger. There is not limit as to how deep
      /// the logger hierarchy can become. Once a logger has been created and it has
      /// inherited the channel and level from its ancestor, it loses the connection
      /// to it. So changes to the level or channel of a logger do not affect its
      /// descendants. This greatly simplifies the implementation of the framework
      /// and is no real restriction, because almost always levels and channels are
      /// set up at application startup and never changed afterwards. Nevertheless,
      /// there are methods to simultaneously change the level and channel of all
      /// loggers in a certain hierarchy.
{
public:
      const std::string& name() const;
            /// Returns the name of the logger, which is set as the
            /// message source on all messages created by the logger.

      void setChannel(Channel* pChannel);
            /// Attaches the given Channel to the Logger.
            
      Channel* getChannel() const;
            /// Returns the Channel attached to the logger.
            
      void setLevel(int level);
            /// Sets the Logger's log level.
            
      int getLevel() const;
            /// Returns the Logger's log level.
            
      void setLevel(const std::string& level);
            /// Sets the Logger's log level using a symbolic value.
            ///
            /// Valid values are:
            ///   - fatal
            ///   - critical
            ///   - error
            ///   - warning
            ///   - notice
            ///   - information
            ///   - debug
            ///   - trace

      void setProperty(const std::string& name, const std::string& value);
            /// Sets or changes a configuration property.
            ///
            /// Only the "channel" and "level" properties are supported, which allow
            /// setting the target channel and log level, respectively, via the LoggingRegistry.
            /// The "channel" and "level" properties are set-only.

      void log(const Message& msg);
            /// Logs the given message if its priority is
            /// greater than or equal to the Logger's log level.
            
      void log(const Exception& exc);
            /// Logs the given exception with priority PRIO_ERROR.      
            
      void fatal(const std::string& msg);
            /// If the Logger's log level is at least PRIO_FATAL,
            /// creates a Message with priority PRIO_FATAL
            /// and the given message text and sends it
            /// to the attached channel.

      void critical(const std::string& msg);
            /// If the Logger's log level is at least PRIO_CRITICAL,
            /// creates a Message with priority PRIO_CRITICAL
            /// and the given message text and sends it
            /// to the attached channel.

      void error(const std::string& msg);
            /// If the Logger's log level is at least PRIO_ERROR,
            /// creates a Message with priority PRIO_ERROR
            /// and the given message text and sends it
            /// to the attached channel.

      void warning(const std::string& msg);
            /// If the Logger's log level is at least PRIO_WARNING,
            /// creates a Message with priority PRIO_WARNING
            /// and the given message text and sends it
            /// to the attached channel.

      void notice(const std::string& msg);
            /// If the Logger's log level is at least PRIO_NOTICE,
            /// creates a Message with priority PRIO_NOTICE
            /// and the given message text and sends it
            /// to the attached channel.

      void information(const std::string& msg);
            /// If the Logger's log level is at least PRIO_INFORMATION,
            /// creates a Message with priority PRIO_INFORMATION
            /// and the given message text and sends it
            /// to the attached channel.

      void debug(const std::string& msg);
            /// If the Logger's log level is at least PRIO_DEBUG,
            /// creates a Message with priority PRIO_DEBUG
            /// and the given message text and sends it
            /// to the attached channel.

      void trace(const std::string& msg);
            /// If the Logger's log level is at least PRIO_TRACE,
            /// creates a Message with priority PRIO_TRACE
            /// and the given message text and sends it
            /// to the attached channel.
            
      void dump(const std::string& msg, const void* buffer, std::size_t length, Message::Priority prio = Message::PRIO_DEBUG);
            /// Logs the given message, followed by the data in buffer.
            ///
            /// The data in buffer is written in canonical hex+ASCII form:
            /// Offset (4 bytes) in hexadecimal, followed by sixteen 
            /// space-separated, two column, hexadecimal bytes,
            /// followed by the same sixteen bytes as ASCII characters.
            /// For bytes outside the range 32 .. 127, a dot is printed.

      bool is(int level) const;
            /// Returns true if at least the given log level is set.
            
      bool fatal() const;
            /// Returns true if the log level is at least PRIO_FATAL.
            
      bool critical() const;
            /// Returns true if the log level is at least PRIO_CRITICAL.

      bool error() const;
            /// Returns true if the log level is at least PRIO_ERROR.

      bool warning() const;
            /// Returns true if the log level is at least PRIO_WARNING.

      bool notice() const;
            /// Returns true if the log level is at least PRIO_NOTICE.

      bool information() const;
            /// Returns true if the log level is at least PRIO_INFORMATION.

      bool debug() const;
            /// Returns true if the log level is at least PRIO_DEBUG.

      bool trace() const;
            /// Returns true if the log level is at least PRIO_TRACE.

      static std::string format(const std::string& fmt, const std::string& arg);
            /// Replaces all occurences of $0 in fmt with the string given in arg and
            /// returns the result. To include a dollar sign in the result string,
            /// specify two dollar signs ($$) in the format string.
            
      static std::string format(const std::string& fmt, const std::string& arg0, const std::string& arg1);
            /// Replaces all occurences of $<n> in fmt with the string given in arg<n> and
            /// returns the result. To include a dollar sign in the result string,
            /// specify two dollar signs ($$) in the format string.

      static std::string format(const std::string& fmt, const std::string& arg0, const std::string& arg1, const std::string& arg2); 
            /// Replaces all occurences of $<n> in fmt with the string given in arg<n> and
            /// returns the result. To include a dollar sign in the result string,
            /// specify two dollar signs ($$) in the format string.

      static std::string format(const std::string& fmt, const std::string& arg0, const std::string& arg1, const std::string& arg2, const std::string& arg3);      
            /// Replaces all occurences of $<n> in fmt with the string given in arg<n> and
            /// returns the result. To include a dollar sign in the result string,
            /// specify two dollar signs ($$) in the format string.

      static void setLevel(const std::string& name, int level);
            /// Sets the given log level on all loggers that are
            /// descendants of the Logger with the given name.
            
      static void setChannel(const std::string& name, Channel* pChannel);
            /// Attaches the given Channel to all loggers that are
            /// descendants of the Logger with the given name.

      static void setProperty(const std::string& loggerName, const std::string& propertyName, const std::string& value);
            /// Sets or changes a configuration property for all loggers
            /// that are descendants of the Logger with the given name.

      static Logger& get(const std::string& name);
            /// Returns a reference to the Logger with the given name.
            /// If the Logger does not yet exist, it is created, based
            /// on its parent logger.

      static Logger& unsafeGet(const std::string& name);
            /// Returns a reference to the Logger with the given name.
            /// If the Logger does not yet exist, it is created, based
            /// on its parent logger.
            ///
            /// WARNING: This method is not thread safe. You should
            /// probably use get() instead.
            /// The only time this method should be used is during
            /// program initialization, when only one thread is running.
            
      static Logger& create(const std::string& name, Channel* pChannel, int level = Message::PRIO_INFORMATION);
            /// Creates and returns a reference to a Logger with the
            /// given name. The Logger's Channel and log level as set as
            /// specified.
            
      static Logger& root();
            /// Returns a reference to the root logger, which is the ultimate
            /// ancestor of all Loggers.
            
      static Logger* has(const std::string& name);
            /// Returns a pointer to the Logger with the given name if it
            /// exists, or a null pointer otherwse.
            
      static void destroy(const std::string& name);
            /// Destroys the logger with the specified name. Does nothing
            /// if the logger is not found.
            ///
            /// After a logger has been destroyed, all references to it
            /// become invalid.     
            
      static void shutdown();
            /// Shuts down the logging framework and releases all
            /// Loggers.
            
      static void names(std::vector<std::string>& names);
            /// Fills the given vector with the names
            /// of all currently defined loggers.
            
00292       static const std::string ROOT; /// The name of the root logger ("").    
            
protected:
00295       typedef std::map<std::string, Logger*> LoggerMap;

      Logger(const std::string& name, Channel* pChannel, int level);
      ~Logger();
      
      void log(const std::string& text, Message::Priority prio);

      static std::string format(const std::string& fmt, int argc, std::string argv[]);
      static void formatDump(std::string& message, const void* buffer, std::size_t length);
      static Logger& parent(const std::string& name);
      static void add(Logger* pLogger);
      static Logger* find(const std::string& name);

private:
      Logger();
      Logger(const Logger&);
      Logger& operator = (const Logger&);
      
      std::string _name;
      Channel*    _pChannel;
      int         _level;

      static LoggerMap* _pLoggerMap;
      static Mutex      _mapMtx;
};


//
// convenience macros
//
#define poco_fatal(logger, msg) \
      if ((logger).fatal()) (logger).fatal(msg); else (void) 0

#define poco_critical(logger, msg) \
      if ((logger).critical()) (logger).critical(msg); else (void) 0

#define poco_error(logger, msg) \
      if ((logger).error()) (logger).error(msg); else (void) 0

#define poco_warning(logger, msg) \
      if ((logger).warning()) (logger).warning(msg); else (void) 0
      
#define poco_notice(logger, msg) \
      if ((logger).notice()) (logger).notice(msg); else (void) 0

#define poco_information(logger, msg) \
      if ((logger).information()) (logger).information(msg); else (void) 0

#if defined(_DEBUG)
      #define poco_debug(logger, msg) \
            if ((logger).debug()) (logger).debug(msg); else (void) 0

      #define poco_trace(logger, msg) \
            if ((logger).trace()) (logger).trace(msg); else (void) 0
#else
      #define poco_debug(logger, msg)
      #define poco_trace(logger, msg)
#endif


//
// inlines
//
inline const std::string& Logger::name() const
{
      return _name;
}


00364 inline int Logger::getLevel() const
{
      return _level;
}


inline void Logger::log(const std::string& text, Message::Priority prio)
{
      if (_level >= prio && _pChannel)
      {
            _pChannel->log(Message(_name, text, prio));
      }
}


00379 inline void Logger::fatal(const std::string& msg)
{
      log(msg, Message::PRIO_FATAL);
}


00385 inline void Logger::critical(const std::string& msg)
{
      log(msg, Message::PRIO_CRITICAL);
}


00391 inline void Logger::error(const std::string& msg)
{
      log(msg, Message::PRIO_ERROR);
}


00397 inline void Logger::warning(const std::string& msg)
{
      log(msg, Message::PRIO_WARNING);
}


00403 inline void Logger::notice(const std::string& msg)
{
      log(msg, Message::PRIO_NOTICE);
}


00409 inline void Logger::information(const std::string& msg)
{
      log(msg, Message::PRIO_INFORMATION);
}


00415 inline void Logger::debug(const std::string& msg)
{
      log(msg, Message::PRIO_DEBUG);
}


00421 inline void Logger::trace(const std::string& msg)
{
      log(msg, Message::PRIO_TRACE);
}


00427 inline bool Logger::is(int level) const
{
      return _level >= level;
}


00433 inline bool Logger::fatal() const
{
      return _level >= Message::PRIO_FATAL;
}


00439 inline bool Logger::critical() const
{
      return _level >= Message::PRIO_CRITICAL;
}


00445 inline bool Logger::error() const
{
      return _level >= Message::PRIO_ERROR;
}


00451 inline bool Logger::warning() const
{
      return _level >= Message::PRIO_WARNING;
}


00457 inline bool Logger::notice() const
{
      return _level >= Message::PRIO_NOTICE;
}


00463 inline bool Logger::information() const
{
      return _level >= Message::PRIO_INFORMATION;
}


00469 inline bool Logger::debug() const
{
      return _level >= Message::PRIO_DEBUG;
}


00475 inline bool Logger::trace() const
{
      return _level >= Message::PRIO_TRACE;
}


} // namespace Poco


#endif // Foundation_Logger_INCLUDED

Generated by  Doxygen 1.6.0   Back to index