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
27using Poco::AutoPtr;
28using Poco::Formatter;
29using Poco::PatternFormatter;
30using Poco::Channel;
31using Poco::FormattingChannel;
32using Poco::Logger;
33using Poco::LoggingRegistry;
34using Poco::LoggingFactory;
35
36
37namespace Poco {
38namespace Util {
39
40
41LoggingConfigurator::LoggingConfigurator()
42{
43}
44
45
46LoggingConfigurator::~LoggingConfigurator()
47{
48}
49
50
51void 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
66void 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
79void 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
98void 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
118Formatter::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
132Channel::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
166void 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
180void 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