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