1 | // |
2 | // LoggingConfigurator.cpp |
3 | // |
4 | // Library: Util |
5 | // Package: Configuration |
6 | // Module: LoggingConfigurator |
7 | // |
8 | // Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. |
9 | // and Contributors. |
10 | // |
11 | // SPDX-License-Identifier: BSL-1.0 |
12 | // |
13 | |
14 | |
15 | #include "Poco/Util/LoggingConfigurator.h" |
16 | #include "Poco/AutoPtr.h" |
17 | #include "Poco/Channel.h" |
18 | #include "Poco/FormattingChannel.h" |
19 | #include "Poco/Formatter.h" |
20 | #include "Poco/PatternFormatter.h" |
21 | #include "Poco/Logger.h" |
22 | #include "Poco/LoggingRegistry.h" |
23 | #include "Poco/LoggingFactory.h" |
24 | #include <map> |
25 | |
26 | |
27 | using Poco::AutoPtr; |
28 | using Poco::Formatter; |
29 | using Poco::PatternFormatter; |
30 | using Poco::Channel; |
31 | using Poco::FormattingChannel; |
32 | using Poco::Logger; |
33 | using Poco::LoggingRegistry; |
34 | using Poco::LoggingFactory; |
35 | |
36 | |
37 | namespace Poco { |
38 | namespace Util { |
39 | |
40 | |
41 | LoggingConfigurator::LoggingConfigurator() |
42 | { |
43 | } |
44 | |
45 | |
46 | LoggingConfigurator::~LoggingConfigurator() |
47 | { |
48 | } |
49 | |
50 | |
51 | void LoggingConfigurator::configure(AbstractConfiguration::Ptr pConfig) |
52 | { |
53 | poco_check_ptr (pConfig); |
54 | |
55 | AbstractConfiguration::Ptr pFormattersConfig(pConfig->createView("logging.formatters" )); |
56 | configureFormatters(pFormattersConfig); |
57 | |
58 | AbstractConfiguration::Ptr pChannelsConfig(pConfig->createView("logging.channels" )); |
59 | configureChannels(pChannelsConfig); |
60 | |
61 | AbstractConfiguration::Ptr pLoggersConfig(pConfig->createView("logging.loggers" )); |
62 | configureLoggers(pLoggersConfig); |
63 | } |
64 | |
65 | |
66 | void LoggingConfigurator::configureFormatters(AbstractConfiguration::Ptr pConfig) |
67 | { |
68 | AbstractConfiguration::Keys formatters; |
69 | pConfig->keys(formatters); |
70 | for (AbstractConfiguration::Keys::const_iterator it = formatters.begin(); it != formatters.end(); ++it) |
71 | { |
72 | AutoPtr<AbstractConfiguration> pFormatterConfig(pConfig->createView(*it)); |
73 | AutoPtr<Formatter> pFormatter(createFormatter(pFormatterConfig)); |
74 | LoggingRegistry::defaultRegistry().registerFormatter(*it, pFormatter); |
75 | } |
76 | } |
77 | |
78 | |
79 | void LoggingConfigurator::configureChannels(AbstractConfiguration::Ptr pConfig) |
80 | { |
81 | AbstractConfiguration::Keys channels; |
82 | pConfig->keys(channels); |
83 | for (AbstractConfiguration::Keys::const_iterator it = channels.begin(); it != channels.end(); ++it) |
84 | { |
85 | AutoPtr<AbstractConfiguration> pChannelConfig(pConfig->createView(*it)); |
86 | AutoPtr<Channel> pChannel = createChannel(pChannelConfig); |
87 | LoggingRegistry::defaultRegistry().registerChannel(*it, pChannel); |
88 | } |
89 | for (AbstractConfiguration::Keys::const_iterator it = channels.begin(); it != channels.end(); ++it) |
90 | { |
91 | AutoPtr<AbstractConfiguration> pChannelConfig(pConfig->createView(*it)); |
92 | Channel::Ptr pChannel = LoggingRegistry::defaultRegistry().channelForName(*it); |
93 | configureChannel(pChannel, pChannelConfig); |
94 | } |
95 | } |
96 | |
97 | |
98 | void LoggingConfigurator::configureLoggers(AbstractConfiguration::Ptr pConfig) |
99 | { |
100 | typedef std::map<std::string, AutoPtr<AbstractConfiguration> > LoggerMap; |
101 | |
102 | AbstractConfiguration::Keys loggers; |
103 | pConfig->keys(loggers); |
104 | // use a map to sort loggers by their name, ensuring initialization in correct order (parents before children) |
105 | LoggerMap loggerMap; |
106 | for (AbstractConfiguration::Keys::const_iterator it = loggers.begin(); it != loggers.end(); ++it) |
107 | { |
108 | AutoPtr<AbstractConfiguration> pLoggerConfig(pConfig->createView(*it)); |
109 | loggerMap[pLoggerConfig->getString("name" , "" )] = pLoggerConfig; |
110 | } |
111 | for (LoggerMap::iterator it = loggerMap.begin(); it != loggerMap.end(); ++it) |
112 | { |
113 | configureLogger(it->second); |
114 | } |
115 | } |
116 | |
117 | |
118 | Formatter::Ptr LoggingConfigurator::createFormatter(AbstractConfiguration::Ptr pConfig) |
119 | { |
120 | Formatter::Ptr pFormatter(LoggingFactory::defaultFactory().createFormatter(pConfig->getString("class" ))); |
121 | AbstractConfiguration::Keys props; |
122 | pConfig->keys(props); |
123 | for (AbstractConfiguration::Keys::const_iterator it = props.begin(); it != props.end(); ++it) |
124 | { |
125 | if (*it != "class" ) |
126 | pFormatter->setProperty(*it, pConfig->getString(*it)); |
127 | } |
128 | return pFormatter; |
129 | } |
130 | |
131 | |
132 | Channel::Ptr LoggingConfigurator::createChannel(AbstractConfiguration::Ptr pConfig) |
133 | { |
134 | Channel::Ptr pChannel(LoggingFactory::defaultFactory().createChannel(pConfig->getString("class" ))); |
135 | Channel::Ptr pWrapper(pChannel); |
136 | AbstractConfiguration::Keys props; |
137 | pConfig->keys(props); |
138 | for (AbstractConfiguration::Keys::const_iterator it = props.begin(); it != props.end(); ++it) |
139 | { |
140 | if (*it == "pattern" ) |
141 | { |
142 | AutoPtr<Formatter> pPatternFormatter(new PatternFormatter(pConfig->getString(*it))); |
143 | pWrapper = new FormattingChannel(pPatternFormatter, pChannel); |
144 | } |
145 | else if (*it == "formatter" ) |
146 | { |
147 | AutoPtr<FormattingChannel> pFormattingChannel(new FormattingChannel(0, pChannel)); |
148 | if (pConfig->hasProperty("formatter.class" )) |
149 | { |
150 | AutoPtr<AbstractConfiguration> pFormatterConfig(pConfig->createView(*it)); |
151 | AutoPtr<Formatter> pFormatter(createFormatter(pFormatterConfig)); |
152 | pFormattingChannel->setFormatter(pFormatter); |
153 | } |
154 | else pFormattingChannel->setProperty(*it, pConfig->getString(*it)); |
155 | #if defined(__GNUC__) && __GNUC__ < 3 |
156 | pWrapper = pFormattingChannel.duplicate(); |
157 | #else |
158 | pWrapper = pFormattingChannel; |
159 | #endif |
160 | } |
161 | } |
162 | return pWrapper; |
163 | } |
164 | |
165 | |
166 | void LoggingConfigurator::configureChannel(Channel::Ptr pChannel, AbstractConfiguration::Ptr pConfig) |
167 | { |
168 | AbstractConfiguration::Keys props; |
169 | pConfig->keys(props); |
170 | for (AbstractConfiguration::Keys::const_iterator it = props.begin(); it != props.end(); ++it) |
171 | { |
172 | if (*it != "pattern" && *it != "formatter" && *it != "class" ) |
173 | { |
174 | pChannel->setProperty(*it, pConfig->getString(*it)); |
175 | } |
176 | } |
177 | } |
178 | |
179 | |
180 | void LoggingConfigurator::configureLogger(AbstractConfiguration::Ptr pConfig) |
181 | { |
182 | Logger& logger = Logger::get(pConfig->getString("name" , "" )); |
183 | AbstractConfiguration::Keys props; |
184 | pConfig->keys(props); |
185 | for (AbstractConfiguration::Keys::const_iterator it = props.begin(); it != props.end(); ++it) |
186 | { |
187 | if (*it == "channel" && pConfig->hasProperty("channel.class" )) |
188 | { |
189 | AutoPtr<AbstractConfiguration> pChannelConfig(pConfig->createView(*it)); |
190 | AutoPtr<Channel> pChannel(createChannel(pChannelConfig)); |
191 | configureChannel(pChannel, pChannelConfig); |
192 | Logger::setChannel(logger.name(), pChannel); |
193 | } |
194 | else if (*it != "name" ) |
195 | { |
196 | Logger::setProperty(logger.name(), *it, pConfig->getString(*it)); |
197 | } |
198 | } |
199 | } |
200 | |
201 | |
202 | } } // namespace Poco::Util |
203 | |