logging.cc 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. // Copyright (C) 2014, 2015 Internet Systems Consortium, Inc. ("ISC")
  2. //
  3. // Permission to use, copy, modify, and/or distribute this software for any
  4. // purpose with or without fee is hereby granted, provided that the above
  5. // copyright notice and this permission notice appear in all copies.
  6. //
  7. // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
  8. // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  9. // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
  10. // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  11. // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  12. // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  13. // PERFORMANCE OF THIS SOFTWARE.
  14. #include <config.h>
  15. #include <cc/data.h>
  16. #include <dhcpsrv/logging.h>
  17. #include <boost/foreach.hpp>
  18. #include <boost/lexical_cast.hpp>
  19. #include <log/logger_specification.h>
  20. #include <log/logger_support.h>
  21. #include <log/logger_manager.h>
  22. #include <log/logger_name.h>
  23. using namespace isc::data;
  24. using namespace isc::log;
  25. namespace isc {
  26. namespace dhcp {
  27. LogConfigParser::LogConfigParser(const SrvConfigPtr& storage)
  28. :config_(storage), verbose_(false) {
  29. if (!storage) {
  30. isc_throw(BadValue, "LogConfigParser needs a pointer to the "
  31. "configuration, so parsed data can be stored there");
  32. }
  33. }
  34. void LogConfigParser::parseConfiguration(const isc::data::ConstElementPtr& loggers,
  35. bool verbose) {
  36. verbose_ = verbose;
  37. // Iterate over all entries in "Logging/loggers" list
  38. BOOST_FOREACH(ConstElementPtr logger, loggers->listValue()) {
  39. parseConfigEntry(logger);
  40. }
  41. }
  42. void LogConfigParser::parseConfigEntry(isc::data::ConstElementPtr entry) {
  43. if (!entry) {
  44. // This should not happen, but let's be on the safe side and check
  45. return;
  46. }
  47. if (!config_) {
  48. isc_throw(BadValue, "configuration storage not set, can't parse logger config.");
  49. }
  50. LoggingInfo info;
  51. // Remove default destinations as we are going to replace them.
  52. info.clearDestinations();
  53. // Get a name
  54. isc::data::ConstElementPtr name_ptr = entry->get("name");
  55. if (!name_ptr) {
  56. isc_throw(BadValue, "loggers entry does not have a mandatory 'name' "
  57. "element (" << entry->getPosition() << ")");
  58. }
  59. info.name_ = name_ptr->stringValue();
  60. // Get severity
  61. isc::data::ConstElementPtr severity_ptr = entry->get("severity");
  62. if (!name_ptr) {
  63. isc_throw(BadValue, "loggers entry does not have a mandatory "
  64. "'severity' element (" << entry->getPosition() << ")");
  65. }
  66. try {
  67. info.severity_ = isc::log::getSeverity(severity_ptr->stringValue().c_str());
  68. } catch (const std::exception&) {
  69. isc_throw(BadValue, "Unsupported severity value '"
  70. << severity_ptr->stringValue() << "' ("
  71. << severity_ptr->getPosition() << ")");
  72. }
  73. // Get debug logging level
  74. info.debuglevel_ = 0;
  75. isc::data::ConstElementPtr debuglevel_ptr = entry->get("debuglevel");
  76. // It's ok to not have debuglevel, we'll just assume its least verbose
  77. // (0) level.
  78. if (debuglevel_ptr) {
  79. try {
  80. info.debuglevel_ = boost::lexical_cast<int>(debuglevel_ptr->str());
  81. if ( (info.debuglevel_ < 0) || (info.debuglevel_ > 99) ) {
  82. // Comment doesn't matter, it is caught several lines below
  83. isc_throw(BadValue, "");
  84. }
  85. } catch (...) {
  86. isc_throw(BadValue, "Unsupported debuglevel value '"
  87. << debuglevel_ptr->stringValue()
  88. << "', expected 0-99 ("
  89. << debuglevel_ptr->getPosition() << ")");
  90. }
  91. }
  92. // We want to follow the normal path, so it could catch parsing errors even
  93. // when verbose mode is enabled. If it is, just override whatever was parsed
  94. // in the config file.
  95. if (verbose_) {
  96. info.severity_ = isc::log::DEBUG;
  97. info.debuglevel_ = 99;
  98. }
  99. isc::data::ConstElementPtr output_options = entry->get("output_options");
  100. if (output_options) {
  101. parseOutputOptions(info.destinations_, output_options);
  102. }
  103. config_->addLoggingInfo(info);
  104. }
  105. void LogConfigParser::parseOutputOptions(std::vector<LoggingDestination>& destination,
  106. isc::data::ConstElementPtr output_options) {
  107. if (!output_options) {
  108. isc_throw(BadValue, "Missing 'output_options' structure in 'loggers'");
  109. }
  110. BOOST_FOREACH(ConstElementPtr output_option, output_options->listValue()) {
  111. LoggingDestination dest;
  112. isc::data::ConstElementPtr output = output_option->get("output");
  113. if (!output) {
  114. isc_throw(BadValue, "output_options entry does not have a mandatory 'output' "
  115. "element (" << output_option->getPosition() << ")");
  116. }
  117. dest.output_ = output->stringValue();
  118. isc::data::ConstElementPtr maxver_ptr = output_option->get("maxver");
  119. if (maxver_ptr) {
  120. dest.maxver_ = boost::lexical_cast<int>(maxver_ptr->str());
  121. }
  122. isc::data::ConstElementPtr maxsize_ptr = output_option->get("maxsize");
  123. if (maxsize_ptr) {
  124. dest.maxsize_ = boost::lexical_cast<uint64_t>(maxsize_ptr->str());
  125. }
  126. isc::data::ConstElementPtr flush_ptr = output_option->get("flush");
  127. if (flush_ptr) {
  128. dest.flush_ = flush_ptr->boolValue();
  129. }
  130. destination.push_back(dest);
  131. }
  132. }
  133. } // namespace isc::dhcp
  134. } // namespace isc