You are viewing a plain text version of this content. The canonical link for it is here.
Posted to log4cxx-dev@logging.apache.org by ca...@apache.org on 2004/10/07 20:52:12 UTC

cvs commit: logging-log4cxx/src locationinfo.cpp Makefile.am

carnold     2004/10/07 11:52:12

  Modified:    examples Makefile.am
               src      Makefile.am
  Added:       examples stream.cpp
               include/log4cxx stream.h
               include/log4cxx/spi/location locationinfo.h
               src      locationinfo.cpp
  Log:
  LOGCXX-18: Another stab at stream logging
  
  Revision  Changes    Path
  1.4       +4 -1      logging-log4cxx/examples/Makefile.am
  
  Index: Makefile.am
  ===================================================================
  RCS file: /home/cvs/logging-log4cxx/examples/Makefile.am,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- Makefile.am	13 Aug 2004 12:27:45 -0000	1.3
  +++ Makefile.am	7 Oct 2004 18:52:12 -0000	1.4
  @@ -1,4 +1,4 @@
  -noinst_PROGRAMS = trivial delayedloop
  +noinst_PROGRAMS = trivial delayedloop stream
   
   INCLUDES = -I$(top_srcdir)/include -I$(top_builddir)/include
   
  @@ -7,6 +7,9 @@
   
   delayedloop_SOURCES = delayedloop.cpp
   delayedloop_LDADD = $(top_builddir)/src/liblog4cxx.la
  +
  +stream_SOURCES = stream.cpp
  +stream_LDADD = $(top_builddir)/src/liblog4cxx.la
   
   
   
  
  
  
  1.1                  logging-log4cxx/examples/stream.cpp
  
  Index: stream.cpp
  ===================================================================
  /*
   * Copyright 2003,2004 The Apache Software Foundation.
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *      http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  #include <stdlib.h>
  #include <log4cxx/stream.h>
  #include <log4cxx/basicconfigurator.h>
  #include <log4cxx/helpers/exception.h>
  #include <log4cxx/ndc.h>
  
  using namespace log4cxx;
  using namespace log4cxx::helpers;
  
  int main()
  {
      int result = EXIT_SUCCESS;
      try
      {
  		BasicConfigurator::configure();
   		LoggerPtr rootLogger = Logger::getRootLogger();
  
  		NDC::push(_T("trivial context"));
  
                  log4cxx::logstream logstream(rootLogger, Level::DEBUG);
                  logstream << "debug message" << LOG4CXX_ENDMSG;
                  logstream.setLevel(Level::INFO);
                  logstream << "info message" << LOG4CXX_ENDMSG;
                  logstream << Level::WARN << "warn message" << LOG4CXX_ENDMSG;
                  logstream << Level::ERROR << "error message" << LOG4CXX_ENDMSG;
                  logstream << Level::FATAL << "fatal message" << LOG4CXX_ENDMSG;
  
  
  		NDC::pop();
  	}
  	catch(Exception&)
  	{
  		result = EXIT_FAILURE;
  	}
  
      return result;
  }
  
  
  
  1.1                  logging-log4cxx/include/log4cxx/stream.h
  
  Index: stream.h
  ===================================================================
  /*
   * Copyright 2004 The Apache Software Foundation.
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *      http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  #ifndef _LOG4CXX_STREAM_H
  #define _LOG4CXX_STREAM_H
  
  #include <log4cxx/logger.h>
  #include <sstream>
  #include <log4cxx/spi/location/locationinfo.h>
  
  namespace log4cxx
  {
  	/**
  	 * Implements an STL streambuf for use by logging streams.
  	 */
  	template <class Elem, class Tr = ::std::char_traits<Elem> >
  	   class basic_logstreambuf : public ::std::basic_stringbuf<Elem, Tr> {
  	   public:
  	   /**
  	    * Constructor.
  	    *
  	    */
  	   basic_logstreambuf(const ::log4cxx::LoggerPtr& logger,
  	                   const ::log4cxx::LevelPtr& level) :
  	                   ::std::basic_stringbuf<Elem, Tr>(::std::ios_base::out),
  	                   logger(logger),
  	                   level(level)  {
  	        isLoggerEnabled = logger->isEnabledFor(level);
  	   }
  
         /**
          * Gets whether logger is currently enabled for the specified level.
          * @returns true if enabled
          */
  	   bool isEnabled() const {
  	   	  return isLoggerEnabled;
  	   }
  
  	   /**
  	    * Sets the call site location.
  	    * @param location call site location
  	    */
  	   void setLocation(const ::log4cxx::spi::location::LocationInfo& location) {
  	   	   this->location = location;
  	   }
  
  	   /**
  	    * Sets the level.
  	    * @param level level
  	    */
  	   void setLevel(const ::log4cxx::LevelPtr& level) {
  	   	  this->level = level;
  	   	  isLoggerEnabled = logger->isEnabledFor(level);
  	   }
  
         protected:
         /**
          * Synchronizes the stream and logger.
          *
          */
  	   int sync() {
  	   	  isLoggerEnabled = logger->isEnabledFor(level);
  	   	  if (isLoggerEnabled) {
  	   	  	 ::std::basic_string<Elem, Tr> msg(str());
  	   	  	 if (msg.length() > 0) {
  	   	             logger->forcedLog(level,
  	   	                 msg,
  	   	                 location.getFileName(),
  	   	                 location.getLineNumber());
  	   	  	 }
  	   	  }
                    location.clear();
  	   	  //
  	   	  //   reset the stream buffer
  	   	  seekoff(0, ::std::ios_base::beg, ::std::ios_base::out);
  	   	  return 0;
  	   }
  
  	   private:
  	   /**
  	    * logger.
  	    */
  	   ::log4cxx::LoggerPtr logger;
  	   /**
  	    * level.
  	    */
  	   ::log4cxx::LevelPtr level;
  	   /**
  	    * location.
  	    */
  	   ::log4cxx::spi::location::LocationInfo location;
  
             /**
             * State of logger at last sync or level changes.
             */
             bool isLoggerEnabled;
  
  	};
  
  	/**
  	 * This template provides an stream interface layer to
  	 * log4cxx.
  	 */
  	template <class Elem, class Tr = ::std::char_traits<Elem> >
  	   class basic_logstream : public ::std::basic_ostream<Elem, Tr> {
  
  	   public:
  	   /**
  	    * Constructor.
  	    */
  	   basic_logstream(const ::log4cxx::LoggerPtr& logger,
  	                const ::log4cxx::LevelPtr& level) :
  	                ::std::basic_ostream<Elem, Tr>(&buffer),
  	                buffer(logger, level) {
  	   }
  
            /**
             * Constructor.
             */
             basic_logstream(const char* logName,
               ::log4cxx::LevelPtr& level) :
               ::std::basic_ostream<Elem, Tr>(&buffer),
               buffer(::log4cxx::Logger::getLogger(logName), level) {
              }
  
  
            /**
             * Sets the call site location.
             * @param location call site location
             */
  	   void setLocation(const ::log4cxx::spi::location::LocationInfo& location) {
  	   	   buffer.setLocation(location);
  	   }
  
  
  	   /**
  	    * Set the level.
  	    * @param level level
  	    */
  	   void setLevel(const ::log4cxx::LevelPtr& level) {
  	   	  buffer.setLevel(level);
  	   }
  
             bool isEnabled() const {
               return buffer.isEnabled();
             }
  
  
  	   private:
  	   basic_logstreambuf<Elem, Tr> buffer;
  	};
  
  	typedef basic_logstream<char> logstream;
  	typedef basic_logstream<wchar_t> wlogstream;
  }  // namespace log4cxx
  
  /**
  * Insertion operator for LocationInfo.
  *
  */
  template<class Elem, class Tr>
  ::log4cxx::basic_logstream<Elem, Tr>& operator<<(
     ::log4cxx::basic_logstream<Elem, Tr>& lhs,
     const ::log4cxx::spi::location::LocationInfo& rhs) {
     lhs.setLocation(rhs);
     return lhs;
  }
  
  /**
  * Insertion operator for LocationInfo.
  *
  */
  template<class Elem, class Tr>
  ::log4cxx::basic_logstream<Elem, Tr>& operator<<(
     ::log4cxx::basic_logstream<Elem, Tr>& lhs,
     const ::log4cxx::LevelPtr& rhs) {
     lhs.setLevel(rhs);
     return lhs;
  }
  
  
  #define LOG4CXX_STREAM_DEFINE_INSERTION(InsType)           \
  template<class Elem, class Tr>                             \
  ::log4cxx::basic_logstream<Elem, Tr>& operator<<(          \
     ::log4cxx::basic_logstream<Elem, Tr>& lhs,              \
     InsType rhs) {                                          \
     if (lhs.isEnabled()) {                                  \
        ((::std::basic_ostream<Elem, Tr>&) lhs) << rhs;      \
     }                                                       \
     return lhs;                                             \
  }
  
  /*
  * Insertion operators for common types.
  * Can't use template or would get ambiguities.
  * If attempting to insert a type without a matching
  * logstream specific insertion operator, the type
  * will be formatted, but may get discarded.
  *
  */
  LOG4CXX_STREAM_DEFINE_INSERTION(bool)
  LOG4CXX_STREAM_DEFINE_INSERTION(signed char)
  LOG4CXX_STREAM_DEFINE_INSERTION(unsigned char)
  LOG4CXX_STREAM_DEFINE_INSERTION(signed short)
  LOG4CXX_STREAM_DEFINE_INSERTION(unsigned short)
  LOG4CXX_STREAM_DEFINE_INSERTION(signed int)
  LOG4CXX_STREAM_DEFINE_INSERTION(unsigned int)
  LOG4CXX_STREAM_DEFINE_INSERTION(signed long)
  LOG4CXX_STREAM_DEFINE_INSERTION(unsigned long)
  LOG4CXX_STREAM_DEFINE_INSERTION(float)
  LOG4CXX_STREAM_DEFINE_INSERTION(double)
  LOG4CXX_STREAM_DEFINE_INSERTION(const Elem*)
  
  template<class Elem, class Tr>
  ::log4cxx::basic_logstream<Elem, Tr>& operator<<(
     ::log4cxx::basic_logstream<Elem, Tr>& lhs,
     const ::std::basic_string<Elem, Tr>& rhs) {
     if (lhs.isEnabled()) {
        ((::std::basic_ostream<Elem, Tr>&) lhs) << rhs;
     }
     return lhs;
  }
  
  
  #if !defined(LOG4CXX_ENDL)
  #define LOG4CXX_ENDMSG LOG4CXX_LOCATION << ::std::flush
  #endif
  
  
  #endif //_LOG4CXX_STREAM_H
  
  
  
  1.1                  logging-log4cxx/include/log4cxx/spi/location/locationinfo.h
  
  Index: locationinfo.h
  ===================================================================
  /*
   * Copyright 2004 The Apache Software Foundation.
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *      http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  #ifndef _LOG4CXX_SPI_LOCATION_LOCATIONINFO_H
    #define _LOG4CXX_SPI_LOCATION_LOCATIONINFO_H
  
    #include <string>
  
  namespace log4cxx
  {
    namespace spi
    {
      namespace location
      {
        /**
         * This class represents the location of a logging statement.
         *
         * @remarks This class currently only used by the experimental (and optional) log4cxx::stream class.
         */
        class LocationInfo
        {
        public:
  
  
  
        /**
          *   When location information is not available the constant
          * <code>NA</code> is returned. Current value of this string constant is <b>?</b>.
          */
          static const char * const NA;
  
  
          /**
           * NA_LOCATION_INFO when  real location info is not available.
           */
          static LocationInfo NA_LOCATION_INFO;
  
  
         /**
          *   Constructor.
          *   @remarks Used by LOG4CXX_LOCATION to generate
          *       location info for current code site
          */
          LocationInfo( const char * const fileName,
                        const char * const className,
                        const char * const methodName,
                        int lineNumber )
               : fileName( fileName ),
                 className( className ),
                 methodName( methodName ),
                 lineNumber( lineNumber )
               {
          }
  
         /**
          *   Default constructor.
          */
          LocationInfo()
             : fileName(LocationInfo::NA),
               className(LocationInfo::NA),
               methodName(LocationInfo::NA),
               lineNumber(-1) {
          }
  
         /**
          *   Copy constructor.
          *   @param src source location
          */
          LocationInfo( const LocationInfo & src )
               : fileName( src.fileName ),
                 className( src.className ),
                 methodName( src.methodName ),
                 lineNumber( src.lineNumber )
               {
          }
  
         /**
          *  Assignment operator.
          * @param src source location
          */
          LocationInfo & operator = ( const LocationInfo & src )
          {
            fileName = src.fileName;
            className = src.className;
            methodName = src.methodName;
            lineNumber = src.lineNumber;
            return * this;
          }
  
          /**
           *   Resets location info to default state.
           */
          void clear() {
            fileName = NA;
            className = NA;
            methodName = NA;
            lineNumber = -1;
          }
  
  
          /** Return the class name of the call site. */
          const std::string getClassName() const;
  
          /**
           *   Return the file name of the caller.
           *   @returns file name, may be null.
           */
          const char * getFileName() const
          {
            return fileName;
          }
  
          /**
            *   Returns the line number of the caller.
            * @returns line number, -1 if not available.
            */
          int getLineNumber() const
          {
            return lineNumber;
          }
  
          /** Returns the method name of the caller. */
          const char * getMethodName() const
          {
            return methodName;
          }
  
          /** Formatted representation of location */
          const std::string getFullInfo() const;
  
          private:
          /** Caller's line number. */
          int lineNumber;
  
          /** Caller's file name. */
          const char * fileName;
  
          /** Caller's fully qualified class name. */
          const char * className;
  
          /** Caller's method name. */
          const char * methodName;
  
  
        };
      }
    }
  }
  
    #if !defined(LOG4CXX_LOCATION)
      #if defined(_GCC_VER)
        #define LOG4CXX_LOCATION ::log4cxx::spi::location::LocationInfo(__FILE__, \
             __PRETTY_FUNCTION__,                                              \
             __func__,                                                         \
             __LINE__)
      #else
        #if defined(_MSC_VER)
          #define LOG4CXX_LOCATION ::log4cxx::spi::location::LocationInfo(__FILE__, \
               __FUNCSIG__,                                                      \
               __FUNCTION__,                                                     \
               __LINE__)
        #else
          #define LOG4CXX_LOCATION ::log4cxx::spi::location::LocationInfo(__FILE__, \
               ::log4cxx::spi::location::LocationInfo::NA,                       \
               __func__,                                                         \
               __LINE__)
        #endif
      #endif
    #endif
  
  #endif //_LOG4CXX_SPI_LOCATION_LOCATIONINFO_H
  
  
  
  1.18      +1 -0      logging-log4cxx/src/Makefile.am
  
  Index: Makefile.am
  ===================================================================
  RCS file: /home/cvs/logging-log4cxx/src/Makefile.am,v
  retrieving revision 1.17
  retrieving revision 1.18
  diff -u -r1.17 -r1.18
  --- Makefile.am	13 Aug 2004 12:27:47 -0000	1.17
  +++ Makefile.am	7 Oct 2004 18:52:12 -0000	1.18
  @@ -36,6 +36,7 @@
   	levelrangefilter.cpp \
   	loader.cpp\
   	locale.cpp\
  +        locationinfo.cpp\
   	logger.cpp \
   	loggingevent.cpp \
   	loglog.cpp \
  
  
  
  1.1                  logging-log4cxx/src/locationinfo.cpp
  
  Index: locationinfo.cpp
  ===================================================================
  /*
   * Copyright 2004 The Apache Software Foundation.
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *      http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
   #include <log4cxx/spi/location/locationinfo.h>
   #include <sstream>
  
   using namespace ::log4cxx::spi::location;
     /**
       When location information is not available the constant
       <code>NA</code> is returned. Current value of this string
       constant is <b>?</b>.  */
   const char* const LocationInfo::NA = "?";
  
  
    /**
     * NA_LOCATION_INFO is used in conjunction with deserialized LoggingEvents
     * without real location info available.
     */
  LocationInfo LocationInfo::NA_LOCATION_INFO;
  
  const std::string LocationInfo::getClassName() const {
  	if (className == NULL) {
  		return NA;
  	}
  	if (strchr(className, ':') == NULL) {
  		return className;
  	}
  	std::string tmp(className);
  	size_t colonPos = tmp.find("::");
  	if (colonPos != std::string::npos) {
  		size_t spacePos = tmp.find_last_of(' ', colonPos);
  		if (spacePos != std::string::npos) {
  			tmp.erase(colonPos);
  			tmp.erase(0, spacePos + 1);
  		}
  	}
  	return tmp;
  }
  
  const std::string LocationInfo::getFullInfo() const {
  	std::ostringstream os;
  	os << getClassName()
  	   << '.'
  	   << getMethodName()
  	   << '('
  	   << getFileName()
  	   << ':'
  	   << getLineNumber()
  	   << ')';
  	return os.str();
  }