[2] | 1 | /*
|
---|
| 2 | * Licensed to the Apache Software Foundation (ASF) under one or more
|
---|
| 3 | * contributor license agreements. See the NOTICE file distributed with
|
---|
| 4 | * this work for additional information regarding copyright ownership.
|
---|
| 5 | * The ASF licenses this file to You under the Apache License, Version 2.0
|
---|
| 6 | * (the "License"); you may not use this file except in compliance with
|
---|
| 7 | * the License. You may obtain a copy of the License at
|
---|
| 8 | *
|
---|
| 9 | * http://www.apache.org/licenses/LICENSE-2.0
|
---|
| 10 | *
|
---|
| 11 | * Unless required by applicable law or agreed to in writing, software
|
---|
| 12 | * distributed under the License is distributed on an "AS IS" BASIS,
|
---|
| 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
---|
| 14 | * See the License for the specific language governing permissions and
|
---|
| 15 | * limitations under the License.
|
---|
| 16 | */
|
---|
| 17 |
|
---|
| 18 | #ifndef _LOG4CXX_PROPERTY_CONFIGURATOR_H
|
---|
| 19 | #define _LOG4CXX_PROPERTY_CONFIGURATOR_H
|
---|
| 20 |
|
---|
| 21 | #if defined(_MSC_VER)
|
---|
| 22 | #pragma warning (push)
|
---|
| 23 | #pragma warning ( disable: 4231 4251 4275 4786 )
|
---|
| 24 | #endif
|
---|
| 25 |
|
---|
| 26 |
|
---|
| 27 | #include <log4cxx/helpers/objectptr.h>
|
---|
| 28 | #include <log4cxx/helpers/objectimpl.h>
|
---|
| 29 | #include <log4cxx/logstring.h>
|
---|
| 30 | #include <log4cxx/spi/configurator.h>
|
---|
| 31 | #include <map>
|
---|
| 32 |
|
---|
| 33 | #include <log4cxx/file.h>
|
---|
| 34 |
|
---|
| 35 | namespace log4cxx
|
---|
| 36 | {
|
---|
| 37 | class Logger;
|
---|
| 38 | typedef helpers::ObjectPtrT<Logger> LoggerPtr;
|
---|
| 39 |
|
---|
| 40 | class Appender;
|
---|
| 41 | typedef helpers::ObjectPtrT<Appender> AppenderPtr;
|
---|
| 42 |
|
---|
| 43 | namespace helpers
|
---|
| 44 | {
|
---|
| 45 | class Properties;
|
---|
| 46 | }
|
---|
| 47 |
|
---|
| 48 |
|
---|
| 49 | namespace spi {
|
---|
| 50 | class LoggerFactory;
|
---|
| 51 | }
|
---|
| 52 |
|
---|
| 53 | /**
|
---|
| 54 | Allows the configuration of log4cxx from an external file. See
|
---|
| 55 | <b>{@link #doConfigure(const File&, log4cxx::spi::LoggerRepositoryPtr&)}</b>
|
---|
| 56 | for the expected format.
|
---|
| 57 |
|
---|
| 58 | <p>It is sometimes useful to see how log4cxx is reading configuration
|
---|
| 59 | files. You can enable log4cxx internal logging by defining the
|
---|
| 60 | <b>log4j.debug</b> variable.
|
---|
| 61 |
|
---|
| 62 | <P>At class initialization time class,
|
---|
| 63 | the file <b>log4j.properties</b> will be searched in the current directory.
|
---|
| 64 | If the file can be found, then it will
|
---|
| 65 | be fed to the
|
---|
| 66 | {@link PropertyConfigurator#configure(const File& configFilename)}
|
---|
| 67 | method.
|
---|
| 68 |
|
---|
| 69 | <p>The <code>PropertyConfigurator</code> does not handle the
|
---|
| 70 | advanced configuration features supported by the {@link
|
---|
| 71 | xml::DOMConfigurator DOMConfigurator} such as
|
---|
| 72 | support for {@link spi::Filter Filters}, custom
|
---|
| 73 | {@link spi::ErrorHandler ErrorHandlers}, nested
|
---|
| 74 | appenders such as the {@link AsyncAppender
|
---|
| 75 | AsyncAppender}, etc.
|
---|
| 76 |
|
---|
| 77 | <p>All option <em>values</em> admit variable substitution. The
|
---|
| 78 | syntax of variable substitution is similar to that of Unix
|
---|
| 79 | shells. The string between an opening <b>"${"</b> and
|
---|
| 80 | closing <b>"}"</b> is interpreted as a key. The value of
|
---|
| 81 | the substituted variable can be defined as a system property or in
|
---|
| 82 | the configuration file itself. The value of the key is first
|
---|
| 83 | searched in the system properties, and if not found there, it is
|
---|
| 84 | then searched in the configuration file being parsed. The
|
---|
| 85 | corresponding value replaces the ${variableName} sequence. For
|
---|
| 86 | example, if <code>java.home</code> system property is set to
|
---|
| 87 | <code>/home/xyz</code>, then every occurrence of the sequence
|
---|
| 88 | <code>${java.home}</code> will be interpreted as
|
---|
| 89 | <code>/home/xyz</code>.
|
---|
| 90 | */
|
---|
| 91 | class LOG4CXX_EXPORT PropertyConfigurator :
|
---|
| 92 | virtual public spi::Configurator,
|
---|
| 93 | virtual public helpers::ObjectImpl
|
---|
| 94 | {
|
---|
| 95 | protected:
|
---|
| 96 |
|
---|
| 97 | /**
|
---|
| 98 | Used internally to keep track of configured appenders.
|
---|
| 99 | */
|
---|
| 100 | std::map<LogString, AppenderPtr>* registry;
|
---|
| 101 |
|
---|
| 102 | /**
|
---|
| 103 | Used to create new instances of logger
|
---|
| 104 | */
|
---|
| 105 | helpers::ObjectPtrT<spi::LoggerFactory> loggerFactory;
|
---|
| 106 |
|
---|
| 107 | public:
|
---|
| 108 | DECLARE_LOG4CXX_OBJECT(PropertyConfigurator)
|
---|
| 109 | BEGIN_LOG4CXX_CAST_MAP()
|
---|
| 110 | LOG4CXX_CAST_ENTRY(spi::Configurator)
|
---|
| 111 | END_LOG4CXX_CAST_MAP()
|
---|
| 112 |
|
---|
| 113 | PropertyConfigurator();
|
---|
| 114 | virtual ~PropertyConfigurator();
|
---|
| 115 | void addRef() const;
|
---|
| 116 | void releaseRef() const;
|
---|
| 117 |
|
---|
| 118 | /**
|
---|
| 119 | Read configuration from a file. <b>The existing configuration is
|
---|
| 120 | not cleared nor reset.</b> If you require a different behavior,
|
---|
| 121 | then call {@link LogManager#resetConfiguration
|
---|
| 122 | resetConfiguration} method before calling
|
---|
| 123 | <code>doConfigure</code>.
|
---|
| 124 |
|
---|
| 125 | <p>The configuration file consists of statements in the format
|
---|
| 126 | <code>key=value</code>. The syntax of different configuration
|
---|
| 127 | elements are discussed below.
|
---|
| 128 |
|
---|
| 129 | <h3>Repository-wide threshold</h3>
|
---|
| 130 |
|
---|
| 131 | <p>The repository-wide threshold filters logging requests by level
|
---|
| 132 | regardless of logger. The syntax is:
|
---|
| 133 |
|
---|
| 134 | <pre>
|
---|
| 135 | log4j.threshold=[level]
|
---|
| 136 | </pre>
|
---|
| 137 |
|
---|
| 138 | <p>The level value can consist of the string values OFF, FATAL,
|
---|
| 139 | ERROR, WARN, INFO, DEBUG, ALL or a <em>custom level</em> value. A
|
---|
| 140 | custom level value can be specified in the form
|
---|
| 141 | level#classname. By default the repository-wide threshold is set
|
---|
| 142 | to the lowest possible value, namely the level <code>ALL</code>.
|
---|
| 143 | </p>
|
---|
| 144 |
|
---|
| 145 |
|
---|
| 146 | <h3>Appender configuration</h3>
|
---|
| 147 |
|
---|
| 148 | <p>Appender configuration syntax is:
|
---|
| 149 | <pre>
|
---|
| 150 | # For appender named <i>appenderName</i>, set its class.
|
---|
| 151 | # Note: The appender name can contain dots.
|
---|
| 152 | log4j.appender.appenderName=fully.qualified.name.of.appender.class
|
---|
| 153 |
|
---|
| 154 | # Set appender specific options.
|
---|
| 155 | log4j.appender.appenderName.option1=value1
|
---|
| 156 | ...
|
---|
| 157 | log4j.appender.appenderName.optionN=valueN
|
---|
| 158 | </pre>
|
---|
| 159 |
|
---|
| 160 | For each named appender you can configure its {@link Layout Layout}. The
|
---|
| 161 | syntax for configuring an appender's layout is:
|
---|
| 162 | <pre>
|
---|
| 163 | log4j.appender.appenderName.layout=fully.qualified.name.of.layout.class
|
---|
| 164 | log4j.appender.appenderName.layout.option1=value1
|
---|
| 165 | ....
|
---|
| 166 | log4j.appender.appenderName.layout.optionN=valueN
|
---|
| 167 | </pre>
|
---|
| 168 |
|
---|
| 169 | <h3>Configuring loggers</h3>
|
---|
| 170 |
|
---|
| 171 | <p>The syntax for configuring the root logger is:
|
---|
| 172 | <pre>
|
---|
| 173 | log4j.rootLogger=[level], appenderName, appenderName, ...
|
---|
| 174 | </pre>
|
---|
| 175 |
|
---|
| 176 | <p>This syntax means that an optional <em>level</em> can be
|
---|
| 177 | supplied followed by appender names separated by commas.
|
---|
| 178 |
|
---|
| 179 | <p>The level value can consist of the string values OFF, FATAL,
|
---|
| 180 | ERROR, WARN, INFO, DEBUG, ALL or a <em>custom level</em> value. A
|
---|
| 181 | custom level value can be specified in the form
|
---|
| 182 | <code>level#classname</code>.
|
---|
| 183 |
|
---|
| 184 | <p>If a level value is specified, then the root level is set
|
---|
| 185 | to the corresponding level. If no level value is specified,
|
---|
| 186 | then the root level remains untouched.
|
---|
| 187 |
|
---|
| 188 | <p>The root logger can be assigned multiple appenders.
|
---|
| 189 |
|
---|
| 190 | <p>Each <i>appenderName</i> (separated by commas) will be added to
|
---|
| 191 | the root logger. The named appender is defined using the
|
---|
| 192 | appender syntax defined above.
|
---|
| 193 |
|
---|
| 194 | <p>For non-root categories the syntax is almost the same:
|
---|
| 195 | <pre>
|
---|
| 196 | log4j.logger.logger_name=[level|INHERITED|NULL], appenderName, appenderName,
|
---|
| 197 | ...
|
---|
| 198 | </pre>
|
---|
| 199 |
|
---|
| 200 | <p>The meaning of the optional level value is discussed above
|
---|
| 201 | in relation to the root logger. In addition however, the value
|
---|
| 202 | INHERITED can be specified meaning that the named logger should
|
---|
| 203 | inherit its level from the logger hierarchy.
|
---|
| 204 |
|
---|
| 205 | <p>If no level value is supplied, then the level of the
|
---|
| 206 | named logger remains untouched.
|
---|
| 207 |
|
---|
| 208 | <p>By default categories inherit their level from the
|
---|
| 209 | hierarchy. However, if you set the level of a logger and later
|
---|
| 210 | decide that that logger should inherit its level, then you should
|
---|
| 211 | specify INHERITED as the value for the level value. NULL is a
|
---|
| 212 | synonym for INHERITED.
|
---|
| 213 |
|
---|
| 214 | <p>Similar to the root logger syntax, each <i>appenderName</i>
|
---|
| 215 | (separated by commas) will be attached to the named logger.
|
---|
| 216 |
|
---|
| 217 | <p>See the <a href="Introduction.html#additivity">appender
|
---|
| 218 | additivity rule</a> in the user manual for the meaning of the
|
---|
| 219 | <code>additivity</code> flag.
|
---|
| 220 |
|
---|
| 221 | <h3>Logger Factories</h3>
|
---|
| 222 |
|
---|
| 223 | The usage of custom logger factories is discouraged and no longer
|
---|
| 224 | documented.
|
---|
| 225 |
|
---|
| 226 | <h3>Example</h3>
|
---|
| 227 |
|
---|
| 228 | <p>An example configuration is given below. Other configuration
|
---|
| 229 | file examples are given in the <code>examples</code> folder.
|
---|
| 230 |
|
---|
| 231 | <pre>
|
---|
| 232 |
|
---|
| 233 | # Set options for appender named "A1".
|
---|
| 234 | # Appender "A1" will be a SyslogAppender
|
---|
| 235 | log4j.appender.A1=SyslogAppender
|
---|
| 236 |
|
---|
| 237 | # The syslog daemon resides on www.abc.net
|
---|
| 238 | log4j.appender.A1.SyslogHost=www.abc.net
|
---|
| 239 |
|
---|
| 240 | # A1's layout is a PatternLayout, using the conversion pattern
|
---|
| 241 | # <b>%r %-5p %c{2} %M.%L %x - %m\n</b>. Thus, the log output will
|
---|
| 242 | # include # the relative time since the start of the application in
|
---|
| 243 | # milliseconds, followed by the level of the log request,
|
---|
| 244 | # followed by the two rightmost components of the logger name,
|
---|
| 245 | # followed by the callers method name, followed by the line number,
|
---|
| 246 | # the nested disgnostic context and finally the message itself.
|
---|
| 247 | # Refer to the documentation of PatternLayout for further information
|
---|
| 248 | # on the syntax of the ConversionPattern key.
|
---|
| 249 | log4j.appender.A1.layout=PatternLayout
|
---|
| 250 | log4j.appender.A1.layout.ConversionPattern=%-4r %-5p %c{2} %M.%L %x - %m\n
|
---|
| 251 |
|
---|
| 252 | # Set options for appender named "A2"
|
---|
| 253 | # A2 should be a RollingFileAppender, with maximum file size of 10 MB
|
---|
| 254 | # using at most one backup file. A2's layout is TTCC, using the
|
---|
| 255 | # ISO8061 date format with context printing enabled.
|
---|
| 256 | log4j.appender.A2=RollingFileAppender
|
---|
| 257 | log4j.appender.A2.MaxFileSize=10MB
|
---|
| 258 | log4j.appender.A2.MaxBackupIndex=1
|
---|
| 259 | log4j.appender.A2.layout=TTCCLayout
|
---|
| 260 | log4j.appender.A2.layout.ContextPrinting=enabled
|
---|
| 261 | log4j.appender.A2.layout.DateFormat=ISO8601
|
---|
| 262 |
|
---|
| 263 | # Root logger set to DEBUG using the A2 appender defined above.
|
---|
| 264 | log4j.rootLogger=DEBUG, A2
|
---|
| 265 |
|
---|
| 266 | # Logger definitions:
|
---|
| 267 | # The SECURITY logger inherits is level from root. However, it's output
|
---|
| 268 | # will go to A1 appender defined above. It's additivity is non-cumulative.
|
---|
| 269 | log4j.logger.SECURITY=INHERIT, A1
|
---|
| 270 | log4j.additivity.SECURITY=false
|
---|
| 271 |
|
---|
| 272 | # Only warnings or above will be logged for the logger "SECURITY.access".
|
---|
| 273 | # Output will go to A1.
|
---|
| 274 | log4j.logger.SECURITY.access=WARN
|
---|
| 275 |
|
---|
| 276 |
|
---|
| 277 | # The logger "class.of.the.day" inherits its level from the
|
---|
| 278 | # logger hierarchy. Output will go to the appender's of the root
|
---|
| 279 | # logger, A2 in this case.
|
---|
| 280 | log4j.logger.class.of.the.day=INHERIT
|
---|
| 281 | </pre>
|
---|
| 282 |
|
---|
| 283 | <p>Refer to the <b>setOption</b> method in each Appender and
|
---|
| 284 | Layout for class specific options.
|
---|
| 285 |
|
---|
| 286 | <p>Use the <code>#</code> or <code>!</code> characters at the
|
---|
| 287 | beginning of a line for comments.
|
---|
| 288 |
|
---|
| 289 | <p>
|
---|
| 290 | @param configFileName The name of the configuration file where the
|
---|
| 291 | configuration information is stored.
|
---|
| 292 | @param hierarchy The hierarchy to operation upon.
|
---|
| 293 | */
|
---|
| 294 | void doConfigure(const File& configFileName,
|
---|
| 295 | spi::LoggerRepositoryPtr& hierarchy);
|
---|
| 296 |
|
---|
| 297 | /**
|
---|
| 298 | Read configuration options from file <code>configFilename</code>.
|
---|
| 299 | */
|
---|
| 300 | static void configure(const File& configFilename);
|
---|
| 301 |
|
---|
| 302 | /**
|
---|
| 303 | Like {@link #configureAndWatch(const File& configFilename, long delay)}
|
---|
| 304 | except that the
|
---|
| 305 | default delay as defined by helpers::FileWatchdog#DEFAULT_DELAY
|
---|
| 306 | is used.
|
---|
| 307 | @param configFilename A file in key=value format.
|
---|
| 308 | */
|
---|
| 309 | static void configureAndWatch(const File& configFilename);
|
---|
| 310 |
|
---|
| 311 | /**
|
---|
| 312 | Read the configuration file <code>configFilename</code> if it
|
---|
| 313 | exists. Moreover, a thread will be created that will periodically
|
---|
| 314 | check if <code>configFilename</code> has been created or
|
---|
| 315 | modified. The period is determined by the <code>delay</code>
|
---|
| 316 | argument. If a change or file creation is detected, then
|
---|
| 317 | <code>configFilename</code> is read to configure log4j.
|
---|
| 318 |
|
---|
| 319 | @param configFilename A file in key=value format.
|
---|
| 320 | @param delay The delay in milliseconds to wait between each check.
|
---|
| 321 | */
|
---|
| 322 | static void configureAndWatch(const File& configFilename,
|
---|
| 323 | long delay);
|
---|
| 324 |
|
---|
| 325 | /**
|
---|
| 326 | Read configuration options from <code>properties</code>.
|
---|
| 327 | See #doConfigure(const File&, log4cxx::spi::LoggerRepositoryPtr&)
|
---|
| 328 | for the expected format.
|
---|
| 329 | */
|
---|
| 330 | static void configure(helpers::Properties& properties);
|
---|
| 331 |
|
---|
| 332 | /**
|
---|
| 333 | Read configuration options from <code>properties</code>.
|
---|
| 334 | See #doConfigure(const File&, log4cxx::spi::LoggerRepositoryPtr&)
|
---|
| 335 | for the expected format.
|
---|
| 336 | */
|
---|
| 337 | void doConfigure(helpers::Properties& properties,
|
---|
| 338 | spi::LoggerRepositoryPtr& hierarchy);
|
---|
| 339 |
|
---|
| 340 | // --------------------------------------------------------------------------
|
---|
| 341 | // Internal stuff
|
---|
| 342 | // --------------------------------------------------------------------------
|
---|
| 343 | protected:
|
---|
| 344 | /**
|
---|
| 345 | Check the provided <code>Properties</code> object for a
|
---|
| 346 | #loggerFactory
|
---|
| 347 | entry specified by LOGGER_FACTORY_KEY. If such an entry
|
---|
| 348 | exists, an attempt is made to create an instance using the default
|
---|
| 349 | constructor. This instance is used for subsequent Logger creations
|
---|
| 350 | within this configurator.
|
---|
| 351 | @see #parseCatsAndRenderers
|
---|
| 352 | */
|
---|
| 353 | void configureLoggerFactory(helpers::Properties& props);
|
---|
| 354 |
|
---|
| 355 | void configureRootLogger(helpers::Properties& props,
|
---|
| 356 | spi::LoggerRepositoryPtr& hierarchy);
|
---|
| 357 |
|
---|
| 358 | /**
|
---|
| 359 | Parse non-root elements, such non-root categories and renderers.
|
---|
| 360 | */
|
---|
| 361 | void parseCatsAndRenderers(helpers::Properties& props,
|
---|
| 362 | spi::LoggerRepositoryPtr& hierarchy);
|
---|
| 363 |
|
---|
| 364 | /**
|
---|
| 365 | Parse the additivity option for a non-root logger.
|
---|
| 366 | */
|
---|
| 367 | void parseAdditivityForLogger(helpers::Properties& props,
|
---|
| 368 | LoggerPtr& cat, const LogString& loggerName);
|
---|
| 369 |
|
---|
| 370 | /**
|
---|
| 371 | This method must work for the root logger as well.
|
---|
| 372 | */
|
---|
| 373 | void parseLogger(
|
---|
| 374 | helpers::Properties& props, LoggerPtr& logger,
|
---|
| 375 | const LogString& optionKey, const LogString& loggerName,
|
---|
| 376 | const LogString& value);
|
---|
| 377 |
|
---|
| 378 | AppenderPtr parseAppender(
|
---|
| 379 | helpers::Properties& props, const LogString& appenderName);
|
---|
| 380 |
|
---|
| 381 | void registryPut(const AppenderPtr& appender);
|
---|
| 382 | AppenderPtr registryGet(const LogString& name);
|
---|
| 383 |
|
---|
| 384 | private:
|
---|
| 385 | PropertyConfigurator(const PropertyConfigurator&);
|
---|
| 386 | PropertyConfigurator& operator=(const PropertyConfigurator&);
|
---|
| 387 | }; // class PropertyConfigurator
|
---|
| 388 | } // namespace log4cxx
|
---|
| 389 |
|
---|
| 390 | #if defined(_MSC_VER)
|
---|
| 391 | #pragma warning (pop)
|
---|
| 392 | #endif
|
---|
| 393 |
|
---|
| 394 |
|
---|
| 395 | #endif //_LOG4CXX_PROPERTY_CONFIGURATOR_H
|
---|