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/25 06:37:33 UTC
cvs commit: logging-log4cxx/include/log4cxx stream.h
carnold 2004/10/24 21:37:33
Modified: include/log4cxx stream.h
Log:
LOGCXX-18: Reworked as std::ios_base to reduce overhead when disabled
Revision Changes Path
1.3 +119 -202 logging-log4cxx/include/log4cxx/stream.h
Index: stream.h
===================================================================
RCS file: /home/cvs/logging-log4cxx/include/log4cxx/stream.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- stream.h 8 Oct 2004 04:10:59 -0000 1.2
+++ stream.h 25 Oct 2004 04:37:33 -0000 1.3
@@ -23,171 +23,111 @@
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) {
- enabled = logger->isEnabledFor(level);
- }
-
- /**
- * Gets whether logger is currently enabled for the specified level.
- * @returns true if enabled
- */
- inline bool isEnabled() const {
- return enabled;
- }
-
- /**
- * 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) {
- bool newState = logger->isEnabledFor(level);
- //
- // if not previously enabled but soon to be enabled then
- // reset the buffer to clear any previously inserted content
- if (newState && !enabled) {
- //
- // reset the stream buffer
- seekoff(0, ::std::ios_base::beg, ::std::ios_base::out);
- }
- this->level = level;
- enabled = newState;
- }
-
- protected:
- /**
- * Synchronizes the stream and logger.
- *
- */
- int sync() {
- //
- // if previously enabled
- if (enabled) {
- // check (and cache) whether it is still enabled
- enabled = logger->isEnabledFor(level);
- // log message if still enabled
- if (enabled) {
- logger->forcedLog(level,
- str(),
- location.getFileName(),
- location.getLineNumber());
- }
- }
- // clear call site information
- location.clear();
- //
- // reset the stream buffer
- seekoff(0, ::std::ios_base::beg, ::std::ios_base::out);
- return 0;
- }
-
- bool isEnabledFor(const ::log4cxx::LevelPtr& level) const {
- return logger.isEnabledFor(level);
- }
-
- 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 enabled;
-
- };
-
- /**
- * 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);
- }
-
- inline bool isEnabled() const {
- return buffer.isEnabled();
- }
-
- bool isEnabledFor(const ::log4cxx::LevelPtr& level) const {
- return buffer.isEnabledFor(level);
- }
-
-
- private:
- basic_logstreambuf<Elem, Tr> buffer;
- };
+ /**
+ * This template acts as a proxy for base_logstreamimpl
+ * and defers the potentially expensive construction
+ * of basic_stream until needed.
+ */
+ template <class Elem, class Tr = ::std::char_traits<Elem> >
+ class basic_logstream : public ::std::ios_base {
+ public:
+ /**
+ * Constructor.
+ */
+ basic_logstream(const ::log4cxx::LoggerPtr& loggr,
+ const ::log4cxx::LevelPtr& level) :
+ logger(loggr),
+ currentLevel(level),
+ impl(0),
+ enabled(loggr->isEnabledFor(level)) {
+ }
+
+ /**
+ * Constructor.
+ */
+ basic_logstream(const char* logName,
+ ::log4cxx::LevelPtr& level) :
+ logger(::log4cxx::Logger::getLogger(logName)),
+ currentLevel(level),
+ impl(0),
+ enabled(logger->isEnabledFor(level)) {
+ }
+
+ ~basic_logstream() {
+ delete impl;
+ }
+
+
+
+ /**
+ * Set the level.
+ * @param level level
+ */
+ void setLevel(const ::log4cxx::LevelPtr& level) {
+ currentLevel = level;
+ enabled = logger->isEnabledFor(currentLevel);
+ }
+
+ inline bool isEnabled() const {
+ return enabled;
+ }
+
+ bool isEnabledFor(const ::log4cxx::LevelPtr& level) const {
+ return logger.isEnabledFor(level);
+ }
+
+
+ void setLocation(const ::log4cxx::spi::location::LocationInfo& location) {
+ if (LOG4CXX_UNLIKELY(enabled)) {
+ currentLocation = location;
+ }
+ }
+
+
+
+ void flush(const ::log4cxx::spi::location::LocationInfo& location) {
+ if (LOG4CXX_UNLIKELY(enabled && 0 != impl)) {
+ ::std::basic_string<Elem, Tr> msg(impl->str());
+ logger->log(currentLevel,
+ msg,
+ location.getFileName(),
+ location.getLineNumber());
+ msg.clear();
+ impl->str(msg);
+ }
+ }
+
+ inline void flush() {
+ flush(currentLocation);
+ }
+
+
+ ::std::basic_ostream<Elem, Tr>& getStream() {
+ if (0 == impl) {
+ impl = new ::std::basic_ostringstream<Elem, Tr>();
+ }
+ impl->precision(precision());
+ impl->width(width());
+ impl->flags(flags());
+ return *impl;
+ }
+
+ private:
+ LevelPtr currentLevel;
+ LoggerPtr logger;
+ ::log4cxx::spi::location::LocationInfo currentLocation;
+ bool enabled;
+ ::std::basic_ostringstream<Elem, Tr>* impl;
+
+ };
typedef basic_logstream<char> logstream;
typedef basic_logstream<wchar_t> wlogstream;
} // namespace log4cxx
+
+
+
/**
* Insertion operator for LocationInfo.
*
@@ -196,9 +136,7 @@
::log4cxx::basic_logstream<Elem, Tr>& operator<<(
::log4cxx::basic_logstream<Elem, Tr>& lhs,
const ::log4cxx::spi::location::LocationInfo& rhs) {
- if (LOG4CXX_UNLIKELY(lhs.isEnabled())) {
- lhs.setLocation(rhs);
- }
+ lhs.setLocation(rhs);
return lhs;
}
@@ -210,16 +148,13 @@
::log4cxx::basic_logstream<Elem, Tr>& operator<<(
::log4cxx::basic_logstream<Elem, Tr>& lhs,
const ::log4cxx::spi::location::LocationFlush& rhs) {
- if (LOG4CXX_UNLIKELY(lhs.isEnabled())) {
- lhs.setLocation(rhs);
- lhs.flush();
- }
+ lhs.flush(rhs);
return lhs;
}
/**
-* Insertion operator for LocationInfo.
+* Insertion operator for Level.
*
*/
template<class Elem, class Tr>
@@ -231,50 +166,32 @@
}
-#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 (LOG4CXX_UNLIKELY(lhs.isEnabled())) { \
- ((::std::basic_ostream<Elem, Tr>&) lhs) << rhs; \
- } \
- return lhs; \
+//
+//
+// template for manipulators (std::scientific et al)
+//
+template<class Elem, class Tr>
+::log4cxx::basic_logstream<Elem, Tr>& operator<<(
+ ::log4cxx::basic_logstream<Elem, Tr>& lhs,
+ ::std::ios_base& (*manip)(::std::ios_base&)) {
+ (*manip)(lhs);
+ 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>
+//
+// template for all other insertion operators
+//
+template<class Elem, class Tr, class ArbitraryType>
::log4cxx::basic_logstream<Elem, Tr>& operator<<(
::log4cxx::basic_logstream<Elem, Tr>& lhs,
- const ::std::basic_string<Elem, Tr>& rhs) {
+ const ArbitraryType& rhs) {
if (LOG4CXX_UNLIKELY(lhs.isEnabled())) {
- ((::std::basic_ostream<Elem, Tr>&) lhs) << rhs;
+ lhs.getStream() << rhs;
}
return lhs;
}
-
#if !defined(LOG4CXX_ENDMSG)
#define LOG4CXX_ENDMSG LOG4CXX_LOCATION_FLUSH