configurator.h 15 KB

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