You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

369 lines
14 KiB

  1. // -*- C++ -*-
  2. // Module: Log4CPLUS
  3. // File: configurator.h
  4. // Created: 3/2003
  5. // Author: Tad E. Smith
  6. //
  7. //
  8. // Copyright 2003-2010 Tad E. Smith
  9. //
  10. // Licensed under the Apache License, Version 2.0 (the "License");
  11. // you may not use this file except in compliance with the License.
  12. // You may obtain a copy of the License at
  13. //
  14. // http://www.apache.org/licenses/LICENSE-2.0
  15. //
  16. // Unless required by applicable law or agreed to in writing, software
  17. // distributed under the License is distributed on an "AS IS" BASIS,
  18. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  19. // See the License for the specific language governing permissions and
  20. // limitations under the License.
  21. /** @file */
  22. #ifndef LOG4CPLUS_CONFIGURATOR_HEADER_
  23. #define LOG4CPLUS_CONFIGURATOR_HEADER_
  24. #include <log4cplus/config.hxx>
  25. #if defined (LOG4CPLUS_HAVE_PRAGMA_ONCE)
  26. #pragma once
  27. #endif
  28. #include <log4cplus/appender.h>
  29. #include <log4cplus/logger.h>
  30. #include <log4cplus/helpers/pointer.h>
  31. #include <log4cplus/helpers/property.h>
  32. #include <map>
  33. namespace log4cplus
  34. {
  35. class Hierarchy;
  36. /**
  37. * Provides configuration from an external file. See configure() for
  38. * the expected format.
  39. *
  40. * <em>All option values admit variable substitution.</em> For
  41. * example, if <code>userhome</code> environment property is set to
  42. * <code>/home/xyz</code> and the File option is set to the string
  43. * <code>${userhome}/test.log</code>, then File option will be
  44. * interpreted as the string <code>/home/xyz/test.log</code>.
  45. *
  46. * The syntax of variable substitution is similar to that of UNIX
  47. * shells. The string between an opening <b>&quot;${&quot;</b> and
  48. * closing <b>&quot;}&quot;</b> is interpreted as a key. Its value is
  49. * searched in the environment properties. The corresponding value replaces
  50. * the ${variableName} sequence.
  51. */
  52. class LOG4CPLUS_EXPORT PropertyConfigurator
  53. {
  54. public:
  55. enum PCFlags
  56. {
  57. fRecursiveExpansion = (1 << 0)
  58. , fShadowEnvironment = (1 << 1)
  59. , fAllowEmptyVars = (1 << 2)
  60. // These encoding related options occupy 2 bits of the flags
  61. // and are mutually exclusive. These flags are synchronized with
  62. // PFlags in Properties.
  63. , fEncodingShift = 3
  64. , fEncodingMask = 0x3
  65. , fUnspecEncoding = (0 << fEncodingShift)
  66. #if defined (LOG4CPLUS_HAVE_CODECVT_UTF8_FACET) && defined (UNICODE)
  67. , fUTF8 = (1 << fEncodingShift)
  68. #endif
  69. #if (defined (LOG4CPLUS_HAVE_CODECVT_UTF16_FACET) || defined (_WIN32)) \
  70. && defined (UNICODE)
  71. , fUTF16 = (2 << fEncodingShift)
  72. #endif
  73. #if defined (LOG4CPLUS_HAVE_CODECVT_UTF32_FACET) && defined (UNICODE)
  74. , fUTF32 = (3 << fEncodingShift)
  75. #endif
  76. };
  77. // ctor and dtor
  78. PropertyConfigurator(const log4cplus::tstring& propertyFile,
  79. Hierarchy& h = Logger::getDefaultHierarchy(), unsigned flags = 0);
  80. PropertyConfigurator(const log4cplus::helpers::Properties& props,
  81. Hierarchy& h = Logger::getDefaultHierarchy(), unsigned flags = 0);
  82. PropertyConfigurator(log4cplus::tistream& propertyStream,
  83. Hierarchy& h = Logger::getDefaultHierarchy(), unsigned flags = 0);
  84. virtual ~PropertyConfigurator();
  85. /**
  86. * This method eliminates the need to create a temporary
  87. * <code>PropertyConfigurator</code> to configure log4cplus.
  88. * It is equivalent to the following:<br>
  89. * <code>
  90. * PropertyConfigurator config("filename");
  91. * config.configure();
  92. * </code>
  93. */
  94. static void doConfigure(const log4cplus::tstring& configFilename,
  95. Hierarchy& h = Logger::getDefaultHierarchy(), unsigned flags = 0);
  96. /**
  97. * Read configuration from a file. <b>The existing configuration is
  98. * not cleared nor reset.</b> If you require a different behavior,
  99. * then call {@link Hierarchy::resetConfiguration
  100. * resetConfiguration} method before calling
  101. * <code>doConfigure</code>.
  102. *
  103. * The configuration file consists of statements in the format
  104. * <code>key=value</code>. The syntax of different configuration
  105. * elements are discussed below.
  106. *
  107. * <h3>Appender configuration</h3>
  108. *
  109. * Appender configuration syntax is:
  110. * <pre>
  111. * # For appender named <i>appenderName</i>, set its class.
  112. * # Note: The appender name can contain dots.
  113. * log4cplus.appender.appenderName=fully.qualified.name.of.appender.class
  114. *
  115. * # Set appender specific options.
  116. * log4cplus.appender.appenderName.option1=value1
  117. * ...
  118. * log4cplus.appender.appenderName.optionN=valueN
  119. * </pre>
  120. *
  121. * For each named appender you can configure its {@link Layout}. The
  122. * syntax for configuring an appender's layout is:
  123. * <pre>
  124. * log4cplus.appender.appenderName.layout=fully.qualified.name.of.layout.class
  125. * log4cplus.appender.appenderName.layout.option1=value1
  126. * ....
  127. * log4cplus.appender.appenderName.layout.optionN=valueN
  128. * </pre>
  129. *
  130. * <h3>Configuring loggers</h3>
  131. *
  132. * The syntax for configuring the root logger is:
  133. * <pre>
  134. * log4cplus.rootLogger=[LogLevel], appenderName, appenderName, ...
  135. * </pre>
  136. *
  137. * This syntax means that an optional <em>LogLevel value</em> can
  138. * be supplied followed by appender names separated by commas.
  139. *
  140. * The LogLevel value can consist of the string values FATAL,
  141. * ERROR, WARN, INFO, DEBUG or a <em>custom LogLevel</em> value.
  142. *
  143. * If a LogLevel value is specified, then the root LogLevel is set
  144. * to the corresponding LogLevel. If no LogLevel value is specified,
  145. * then the root LogLevel remains untouched.
  146. *
  147. * The root logger can be assigned multiple appenders.
  148. *
  149. * Each <i>appenderName</i> (separated by commas) will be added to
  150. * the root logger. The named appender is defined using the
  151. * appender syntax defined above.
  152. *
  153. * For non-root loggers the syntax is almost the same:
  154. * <pre>
  155. * log4cplus.logger.logger_name=[LogLevel|INHERITED], appenderName, appenderName, ...
  156. * </pre>
  157. *
  158. * The meaning of the optional LogLevel value is discussed above
  159. * in relation to the root logger. In addition however, the value
  160. * INHERITED can be specified meaning that the named logger should
  161. * inherit its LogLevel from the logger hierarchy.
  162. *
  163. * By default loggers inherit their LogLevel from the
  164. * hierarchy. However, if you set the LogLevel of a logger and
  165. * later decide that that logger should inherit its LogLevel, then
  166. * you should specify INHERITED as the value for the LogLevel value.
  167. *
  168. * Similar to the root logger syntax, each <i>appenderName</i>
  169. * (separated by commas) will be attached to the named logger.
  170. *
  171. * See the <a href="../../../../manual.html#additivity">appender
  172. * additivity rule</a> in the user manual for the meaning of the
  173. * <code>additivity</code> flag.
  174. *
  175. * The user can override any of the {@link
  176. * Hierarchy#disable} family of methods by setting the a key
  177. * "log4cplus.disableOverride" to <code>true</code> or any value other
  178. * than false. As in <pre>log4cplus.disableOverride=true </pre>
  179. *
  180. * <h3>Example</h3>
  181. *
  182. * An example configuration is given below.
  183. *
  184. * <pre>
  185. *
  186. * # Set options for appender named "A1".
  187. * # Appender "A1" will be a SyslogAppender
  188. * log4cplus.appender.A1=log4cplus::SyslogAppender
  189. *
  190. * # The syslog daemon resides on www.abc.net
  191. * log4cplus.appender.A1.SyslogHost=www.abc.net
  192. *
  193. * # A1's layout is a PatternLayout, using the conversion pattern
  194. * # <b>%r %-5p %c{2} %M.%L %x - %m\n</b>. Thus, the log output will
  195. * # include # the relative time since the start of the application in
  196. * # milliseconds, followed by the LogLevel of the log request,
  197. * # followed by the two rightmost components of the logger name,
  198. * # followed by the callers method name, followed by the line number,
  199. * # the nested disgnostic context and finally the message itself.
  200. * # Refer to the documentation of {@link PatternLayout} for further information
  201. * # on the syntax of the ConversionPattern key.
  202. * log4cplus.appender.A1.layout=log4cplus::PatternLayout
  203. * log4cplus.appender.A1.layout.ConversionPattern=%-4r %-5p %c{2} %M.%L %x - %m\n
  204. *
  205. * # Set options for appender named "A2"
  206. * # A2 should be a RollingFileAppender, with maximum file size of 10 MB
  207. * # using at most one backup file. A2's layout is TTCC, using the
  208. * # ISO8061 date format with context printing enabled.
  209. * log4cplus.appender.A2=log4cplus::RollingFileAppender
  210. * log4cplus.appender.A2.MaxFileSize=10MB
  211. * log4cplus.appender.A2.MaxBackupIndex=1
  212. * log4cplus.appender.A2.layout=log4cplus::TTCCLayout
  213. * log4cplus.appender.A2.layout.ContextPrinting=enabled
  214. * log4cplus.appender.A2.layout.DateFormat=ISO8601
  215. *
  216. * # Root logger set to DEBUG using the A2 appender defined above.
  217. * log4cplus.rootLogger=DEBUG, A2
  218. *
  219. * # Logger definitions:
  220. * # The SECURITY logger inherits is LogLevel from root. However, it's output
  221. * # will go to A1 appender defined above. It's additivity is non-cumulative.
  222. * log4cplus.logger.SECURITY=INHERIT, A1
  223. * log4cplus.additivity.SECURITY=false
  224. *
  225. * # Only warnings or above will be logged for the logger "SECURITY.access".
  226. * # Output will go to A1.
  227. * log4cplus.logger.SECURITY.access=WARN
  228. *
  229. *
  230. * # The logger "class.of.the.day" inherits its LogLevel from the
  231. * # logger hierarchy. Output will go to the appender's of the root
  232. * # logger, A2 in this case.
  233. * log4cplus.logger.class.of.the.day=INHERIT
  234. * </pre>
  235. *
  236. * Refer to the <b>setOption</b> method in each Appender and
  237. * Layout for class specific options.
  238. *
  239. * Use the <code>#</code> character at the beginning of a line
  240. * for comments.
  241. */
  242. virtual void configure();
  243. /**
  244. * \return The return value is reference to Properties
  245. * container of properties with the <code>"log4cplus."</code>
  246. * prefix removed and references to other properties and/or
  247. * environment variables expanded.
  248. */
  249. log4cplus::helpers::Properties const & getProperties () const;
  250. /**
  251. * \return The return value is a reference to log4cplus::tstring
  252. * containing filename of properties source file. It will be
  253. * string "UNAVAILABLE" if the PropertyConfigurator instance has been
  254. * constructed using one of the other constructors that do not take
  255. * filename as parameter.
  256. */
  257. log4cplus::tstring const & getPropertyFilename () const;
  258. protected:
  259. // Methods
  260. void init(); // called by the ctor
  261. void reconfigure();
  262. void replaceEnvironVariables();
  263. void configureLoggers();
  264. void configureLogger(log4cplus::Logger logger, const log4cplus::tstring& config);
  265. void configureAppenders();
  266. void configureAdditivity();
  267. virtual Logger getLogger(const log4cplus::tstring& name);
  268. virtual void addAppender(Logger &logger, log4cplus::SharedAppenderPtr& appender);
  269. // Types
  270. typedef std::map<log4cplus::tstring, log4cplus::SharedAppenderPtr> AppenderMap;
  271. // Data
  272. Hierarchy& h;
  273. log4cplus::tstring propertyFilename;
  274. log4cplus::helpers::Properties properties;
  275. AppenderMap appenders;
  276. unsigned flags;
  277. private:
  278. // Disable copy
  279. PropertyConfigurator(const PropertyConfigurator&);
  280. PropertyConfigurator& operator=(PropertyConfigurator&);
  281. };
  282. /**
  283. * Use this class to quickly configure the package. For file based
  284. * configuration see PropertyConfigurator. BasicConfigurator
  285. * automatically attaches ConsoleAppender to
  286. * <code>rootLogger</code>, with output going to standard output,
  287. * using DEBUG LogLevel value. The additional parameter
  288. * logToStdErr may redirect the output to standard error.
  289. */
  290. class LOG4CPLUS_EXPORT BasicConfigurator : public PropertyConfigurator {
  291. public:
  292. // ctor and dtor
  293. BasicConfigurator(Hierarchy& h = Logger::getDefaultHierarchy(),
  294. bool logToStdErr = false);
  295. virtual ~BasicConfigurator();
  296. /**
  297. * This method eliminates the need to create a temporary
  298. * <code>BasicConfigurator</code> object to configure log4cplus.
  299. * It is equivalent to the following:<br>
  300. * <code><pre>
  301. * BasicConfigurator config;
  302. * config.configure();
  303. * </pre></code>
  304. */
  305. static void doConfigure(Hierarchy& h = Logger::getDefaultHierarchy(),
  306. bool logToStdErr = false);
  307. //! Property name for disable override.
  308. static log4cplus::tstring const DISABLE_OVERRIDE_KEY;
  309. private:
  310. // Disable copy
  311. BasicConfigurator(const BasicConfigurator&);
  312. BasicConfigurator& operator=(BasicConfigurator&);
  313. };
  314. #if !defined(LOG4CPLUS_SINGLE_THREADED)
  315. // Forward Declarations
  316. class ConfigurationWatchDogThread;
  317. class LOG4CPLUS_EXPORT ConfigureAndWatchThread {
  318. public:
  319. // ctor and dtor
  320. ConfigureAndWatchThread(const log4cplus::tstring& propertyFile,
  321. unsigned int millis = 60 * 1000);
  322. virtual ~ConfigureAndWatchThread();
  323. private:
  324. // Disallow copying of instances of this class
  325. ConfigureAndWatchThread(const ConfigureAndWatchThread&);
  326. ConfigureAndWatchThread& operator=(const ConfigureAndWatchThread&);
  327. // Data
  328. ConfigurationWatchDogThread * watchDogThread;
  329. };
  330. #endif
  331. } // end namespace log4cplus
  332. #endif // LOG4CPLUS_CONFIGURATOR_HEADER_