Kea 2.2.0
log_parser.cc
Go to the documentation of this file.
1// Copyright (C) 2014-2019 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
7#include <config.h>
8#include <cc/data.h>
10#include <boost/foreach.hpp>
11#include <boost/lexical_cast.hpp>
13#include <log/logger_support.h>
14#include <log/logger_manager.h>
15#include <log/logger_name.h>
16
17using namespace isc::data;
18using namespace isc::log;
19
20namespace isc {
21namespace process {
22
24 :config_(storage), verbose_(false) {
25 if (!storage) {
26 isc_throw(BadValue, "LogConfigParser needs a pointer to the "
27 "configuration, so parsed data can be stored there");
28 }
29}
30
32 bool verbose) {
33 verbose_ = verbose;
34
35 // Iterate over all entries in "Server/loggers" list
36 BOOST_FOREACH(ConstElementPtr logger, loggers->listValue()) {
37 parseConfigEntry(logger);
38 }
39}
40
41void LogConfigParser::parseConfigEntry(isc::data::ConstElementPtr entry) {
42 if (!entry) {
43 // This should not happen, but let's be on the safe side and check
44 return;
45 }
46
47 if (!config_) {
48 isc_throw(BadValue, "configuration storage not set, can't parse logger config.");
49 }
50
51 LoggingInfo info;
52 // Remove default destinations as we are going to replace them.
53 info.clearDestinations();
54
55 // Get user context
56 isc::data::ConstElementPtr user_context = entry->get("user-context");
57 if (user_context) {
58 info.setContext(user_context);
59 }
60
61 // Get a name
62 isc::data::ConstElementPtr name_ptr = entry->get("name");
63 if (!name_ptr) {
64 isc_throw(BadValue, "loggers entry does not have a mandatory 'name' "
65 "element (" << entry->getPosition() << ")");
66 }
67 info.name_ = name_ptr->stringValue();
68
69 // Get severity
70 isc::data::ConstElementPtr severity_ptr = entry->get("severity");
71 if (!severity_ptr) {
72 isc_throw(BadValue, "loggers entry does not have a mandatory "
73 "'severity' element (" << entry->getPosition() << ")");
74 }
75 try {
76 info.severity_ = isc::log::getSeverity(severity_ptr->stringValue().c_str());
77 } catch (const std::exception&) {
78 isc_throw(BadValue, "Unsupported severity value '"
79 << severity_ptr->stringValue() << "' ("
80 << severity_ptr->getPosition() << ")");
81 }
82
83 // Get debug logging level
84 info.debuglevel_ = 0;
85 isc::data::ConstElementPtr debuglevel_ptr = entry->get("debuglevel");
86
87 // It's ok to not have debuglevel, we'll just assume its least verbose
88 // (0) level.
89 if (debuglevel_ptr) {
90 try {
91 info.debuglevel_ = boost::lexical_cast<int>(debuglevel_ptr->str());
92 if ( (info.debuglevel_ < 0) || (info.debuglevel_ > 99) ) {
93 // Comment doesn't matter, it is caught several lines below
94 isc_throw(BadValue, "");
95 }
96 } catch (...) {
97 isc_throw(BadValue, "Unsupported debuglevel value '"
98 << debuglevel_ptr->stringValue()
99 << "', expected 0-99 ("
100 << debuglevel_ptr->getPosition() << ")");
101 }
102 }
103
104 // We want to follow the normal path, so it could catch parsing errors even
105 // when verbose mode is enabled. If it is, just override whatever was parsed
106 // in the config file.
107 if (verbose_) {
108 info.severity_ = isc::log::DEBUG;
109 info.debuglevel_ = 99;
110 }
111
112 isc::data::ConstElementPtr output_options = entry->get("output_options");
113
114 if (output_options) {
115 parseOutputOptions(info.destinations_, output_options);
116 }
117
118 config_->addLoggingInfo(info);
119}
120
121void LogConfigParser::parseOutputOptions(std::vector<LoggingDestination>& destination,
122 isc::data::ConstElementPtr output_options) {
123 if (!output_options) {
124 isc_throw(BadValue, "Missing 'output_options' structure in 'loggers'");
125 }
126
127 BOOST_FOREACH(ConstElementPtr output_option, output_options->listValue()) {
128
129 LoggingDestination dest;
130
131 isc::data::ConstElementPtr output = output_option->get("output");
132 if (!output) {
133 isc_throw(BadValue, "output_options entry does not have a mandatory 'output' "
134 "element (" << output_option->getPosition() << ")");
135 }
136 dest.output_ = output->stringValue();
137
138 isc::data::ConstElementPtr maxver_ptr = output_option->get("maxver");
139 if (maxver_ptr) {
140 dest.maxver_ = boost::lexical_cast<int>(maxver_ptr->str());
141 }
142
143 isc::data::ConstElementPtr maxsize_ptr = output_option->get("maxsize");
144 if (maxsize_ptr) {
145 dest.maxsize_ = boost::lexical_cast<uint64_t>(maxsize_ptr->str());
146 }
147
148 isc::data::ConstElementPtr flush_ptr = output_option->get("flush");
149 if (flush_ptr) {
150 dest.flush_ = flush_ptr->boolValue();
151 }
152
153 isc::data::ConstElementPtr pattern = output_option->get("pattern");
154 if (pattern) {
155 dest.pattern_ = pattern->stringValue();
156 }
157
158 destination.push_back(dest);
159 }
160}
161
162} // namespace isc::dhcp
163} // namespace isc
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
LogConfigParser(const ConfigPtr &storage)
Constructor.
Definition: log_parser.cc:23
void parseConfiguration(const isc::data::ConstElementPtr &log_config, bool verbose=false)
Parses specified configuration.
Definition: log_parser.cc:31
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
Logging initialization functions.
isc::log::Logger logger("asiodns")
Use the ASIO logger.
boost::shared_ptr< const Element > ConstElementPtr
Definition: data.h:27
@ info
Definition: db_log.h:117
isc::log::Severity getSeverity(const std::string &sev_str)
Returns the isc::log::Severity value represented by the given string.
Definition: logger_level.cc:20
boost::shared_ptr< ConfigBase > ConfigPtr
Non-const pointer to the ConfigBase.
Definition: config_base.h:176
Defines the logger used by the top-level component of kea-lfc.