buffer_appender_impl.cc 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. // Copyright (C) 2012-2016 Internet Systems Consortium, Inc. ("ISC")
  2. //
  3. // This Source Code Form is subject to the terms of the Mozilla Public
  4. // License, v. 2.0. If a copy of the MPL was not distributed with this
  5. // file, You can obtain one at http://mozilla.org/MPL/2.0/.
  6. #include <log/buffer_appender_impl.h>
  7. #include <log4cplus/loglevel.h>
  8. #include <log4cplus/version.h>
  9. #include <boost/scoped_ptr.hpp>
  10. #include <cstdio>
  11. namespace isc {
  12. namespace log {
  13. namespace internal {
  14. BufferAppender::~BufferAppender() {
  15. // If there is anything left in the buffer,
  16. // it means no reconfig has been done, and
  17. // we can assume the logging system was either
  18. // never setup, or broke while doing so.
  19. // So dump all that is left to stdout
  20. try {
  21. flushStdout();
  22. destructorImpl();
  23. } catch (...) {
  24. // Ok if we can't even seem to dump to stdout, never mind.
  25. }
  26. }
  27. void
  28. BufferAppender::flushStdout() {
  29. // This does not show a bit of information normal log messages
  30. // do, so perhaps we should try and setup a new logger here
  31. // However, as this is called from a destructor, it may not
  32. // be a good idea; as we can't reliably know whether in what
  33. // state the logger instance is now (or what the specific logger's
  34. // settings were).
  35. LogEventList::const_iterator it;
  36. for (it = stored_.begin(); it != stored_.end(); ++it) {
  37. const std::string level(it->first);
  38. LogEventPtr event(it->second);
  39. std::printf("%s [%s]: %s\n", level.c_str(),
  40. event->getLoggerName().c_str(),
  41. event->getMessage().c_str());
  42. }
  43. stored_.clear();
  44. }
  45. void
  46. BufferAppender::flush() {
  47. LogEventList stored_copy;
  48. stored_.swap(stored_copy);
  49. LogEventList::const_iterator it;
  50. for (it = stored_copy.begin(); it != stored_copy.end(); ++it) {
  51. LogEventPtr event(it->second);
  52. log4cplus::Logger logger =
  53. log4cplus::Logger::getInstance(event->getLoggerName());
  54. logger.log(event->getLogLevel(), event->getMessage());
  55. }
  56. flushed_ = true;
  57. }
  58. size_t
  59. BufferAppender::getBufferSize() const {
  60. return (stored_.size());
  61. }
  62. void
  63. BufferAppender::append(const log4cplus::spi::InternalLoggingEvent& event) {
  64. if (flushed_) {
  65. isc_throw(LogBufferAddAfterFlush,
  66. "Internal log buffer has been flushed already");
  67. }
  68. // get a clone, and put the pointer in a shared_ptr in the list
  69. #if LOG4CPLUS_VERSION < LOG4CPLUS_MAKE_VERSION(2, 0, 0)
  70. std::auto_ptr<log4cplus::spi::InternalLoggingEvent>
  71. #else
  72. std::unique_ptr<log4cplus::spi::InternalLoggingEvent>
  73. #endif
  74. event_aptr = event.clone();
  75. // Also store the string representation of the log level, to be
  76. // used in flushStdout if necessary
  77. stored_.push_back(LevelAndEvent(
  78. log4cplus::LogLevelManager().toString(event.getLogLevel()),
  79. LogEventPtr(event_aptr.release())));
  80. }
  81. } // end namespace internal
  82. } // end namespace log
  83. } // end namespace isc