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.

374 lines
15 KiB

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