logging.dox 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790
  1. // Copyright (C) 2013-2015 Internet Systems Consortium, Inc. ("ISC")
  2. //
  3. // Permission to use, copy, modify, and/or distribute this software for any
  4. // purpose with or without fee is hereby granted, provided that the above
  5. // copyright notice and this permission notice appear in all copies.
  6. //
  7. // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
  8. // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  9. // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
  10. // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  11. // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  12. // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  13. // PERFORMANCE OF THIS SOFTWARE.
  14. // Note: the prefix "log" to all labels is an abbreviation for "Logging"
  15. // and is used to prevent a clash with symbols in any other Doxygen file.
  16. /**
  17. @page logKeaLogging Kea Logging
  18. @section logBasicIdeas Basic Ideas
  19. The Kea logging system is based on the log4J logging system
  20. common in Java development, and includes the following ideas:
  21. - A set of severity levels.
  22. - A hierarchy of logging sources.
  23. - Separation of message use from message text.
  24. @subsection logSeverity Message Severity
  25. Each message logged by Kea has a severity associated with it, ranging
  26. from FATAL - the most severe - to DEBUG - messages output as the code
  27. executes to facilitate debugging. In order of decreasing severity,
  28. the levels are:
  29. <dl>
  30. <dt>FATAL</dt>
  31. <dd>The program has encountered an error that is so severe that it
  32. cannot continue (or there is no point in continuing). For example, an
  33. unhandled exception generated deep within the code has been caught by the
  34. top-level program. When a fatal error has been logged, the program will
  35. exit immediately (or shortly afterwards) after dumping some diagnostic
  36. information.</dd>
  37. <dt>ERROR</dt>
  38. <dd>Something has happened such that the program can continue but the
  39. results for the current (or future) operations cannot be guaranteed to
  40. be correct, or the results will be correct but the service is impaired.
  41. For example, the program started but attempts to open one or more network
  42. interfaces failed.</dd>
  43. <dt>WARN</dt>
  44. <dd>(Warning) An unusual event happened. Although the program will
  45. continue working normally, the event was sufficiently out of the ordinary
  46. to warrant drawing attention to it. For example, the authoritative
  47. server loaded a zone that contained no resource records.</dd>
  48. <dt>INFO</dt>
  49. <dd>(Information) A normal but significant event has occurred that should
  50. be recorded, e.g. the program has started or is just about to terminate,
  51. a new zone has been created, etc.</dd>
  52. <dt>DEBUG</dt>
  53. <dd>Debug messages are output at this severity. Each message also
  54. has a debug level associated with it, ranging from 0 (the default)
  55. for high-level messages and level 99 (the maximum) for the the lowest
  56. level.</dd>
  57. </dl>
  58. When logging is enabled for a component, it is enabled for a particular
  59. severity level and all higher severities. So if logging is enabled
  60. for INFO messages, WARN, ERROR and FATAL messages will also be logged,
  61. but not DEBUG ones. If enabled for ERROR, only ERROR and FATAL messages
  62. will be logged.
  63. As noted above, DEBUG messages are also associated with a debug level.
  64. This allows the developer to control the amount of debugging information
  65. produced; the higher the debug level, the more information is output.
  66. For example, if debugging the NSAS (nameserver address store), debug
  67. levels might be assigned as follows: a level 0 debug message records
  68. the creation of a new zone, a level 10 logs every timeout when trying
  69. to get a nameserver address, a level of 50 records every query for an
  70. address and a level of 70 records every update of the round-trip time.
  71. Like severities, levels are cumulative; so if level 25 is set as the
  72. debug level, all debug messages associated levels 0 to 25 (inclusive)
  73. will be output. In fact, it is probably easier to visualize the debug
  74. levels as part of the severity system:
  75. @code
  76. FATAL Most severe
  77. ERROR
  78. WARN
  79. INFO
  80. DEBUG level 0
  81. DEBUG level 1
  82. :
  83. DEBUG level 99 Least severe
  84. @endcode
  85. When a particular debug level is set, it - and all debug levels and
  86. severities above it - will be logged.
  87. To try to ensure that the information from different modules is roughly
  88. comparable for the same debug level, a set of standard debug levels has
  89. been defined for common types of debug output. (These can be found in
  90. @ref log_dbglevels.h) However, modules are free to set their own debug
  91. levels or define additional ones.
  92. @subsection logHierarchical Hierarchical Logging System
  93. When a program writes a message to the logging system, it does so using an
  94. instance of the @ref isc::log::Logger class. As well as performing the
  95. write of the message, the logger identifies the source of the message:
  96. different sources can write to different destinations and can log
  97. different severities of messages. For example, the logger associated
  98. with the resolver's cache code could write debugging and other messages
  99. to a file while all other components only write messages relating to
  100. errors to the syslog file.
  101. The loggers are hierarchical in that each logger is the child of another
  102. logger. The top of the hierarchy is the root logger; this does not
  103. have a parent. The reason for this hierarchy is that unless a logger
  104. explicitly assigns a value to an attribute (such as severity of messages
  105. it should log), it picks it up the value from the parent. In Kea,
  106. each component (b10-dhcp4, b10-dhcp-ddns etc.) has a root logger (named
  107. after the program) and every other logger in the component is a child
  108. of that. So in the example above, the error/syslog attributes could be
  109. associated with the b10-resolver logger while the logger associated with
  110. the cache sets its own values for the debug/file attributes.
  111. More information about the logging hierarchy can be found in the section
  112. on Logging configuration in the <a
  113. href="http://kea.isc.org/docs/kea-guide.html#logging">Kea Administrator
  114. Reference Manual</a>.
  115. @subsection logSeparationUseText Separation of Messages Use from Message Text
  116. Separating the use of the message from the text associated with it -
  117. in essence, defining message text in an external file - allows for the
  118. replacement the supplied text of the messages with a local language version.
  119. It also means that other attributes can be associated with the message,
  120. for example, an explanation of the meaning of the message and other
  121. information such as remedial action in the case of errors.
  122. Each message has an identifier such as "LOG_WRITE_ERROR".
  123. Within the program, this is the symbol passed to the logging system
  124. which uses the symbol as an index into a dictionary to retrieve the message
  125. associated with it (e.g. "unable to open %1 for input"), after which it
  126. substitutes any message parameters (in this example, the name of the file
  127. where the write operation failed) and logs the result to the destination.
  128. In Kea, a the default text for each message is linked into the
  129. program. Each program is able to read a locally-defined message file
  130. when it starts, updating the stored definitions with site-specific text.
  131. When the message is logged, the updated text is output. However, the
  132. message identifier is always included in the output so that the origin
  133. of the message can be identified even if the text has been changed.
  134. @note Local message files have not yet been implemented in Kea.
  135. @section logDeveloperUse Using Logging in a Kea Component
  136. The steps in using the logging system in a Kea component (such as
  137. an executable or library) are:
  138. <ol>
  139. <li>Create a message file. This defines messages by an identification
  140. string and and text that explains the message in more detail. Ideally the
  141. file should have a file type of ".mes".</li>
  142. <li>Run it through the message compiler to produce the files for your
  143. module. This step should be included in the build process. The message
  144. compiler is a Kea program and is one of the first programs built and
  145. linked in the build process. As a result, it should be available for
  146. compiling the message files of all Kea components and libraries.
  147. For C++ development, the message compiler produces two files in the
  148. default directory, having the same name as the input file but with file
  149. types of ".h" and ".cc". For Python, the message compiler will produce
  150. a Python module containing the symbols.</li>
  151. <li>Include the resultant files in your source code to define message symbols,
  152. and (for C++) compile the code and link it into your program.</li>
  153. <li>Declare loggers in your code and use them to log messages.</li>
  154. <li>Call the logger initialization function in the program's main module.</li>
  155. </ol>
  156. The following sections describe these steps in more detail.
  157. @subsection logMessageFiles Create a Message File
  158. A message file contains message definitions. Typically there
  159. will be one message file for each component that uses Kea logging.
  160. An example file could be:
  161. @code
  162. # Example message file
  163. $NAMESPACE isc::log
  164. % LOG_UNRECOGNIZED_DIRECTIVE line %1: unrecognized directive '%2'
  165. A line starting with a dollar symbol was found, but the first word on the line
  166. (shown in the message) was not a recognized message compiler directive.
  167. % LOG_WRITE_ERROR error writing to %1: %2
  168. The specified error was encountered by the message compiler when writing to
  169. the named output file.
  170. @endcode
  171. Points to note are:
  172. <ul>
  173. <li>Leading and trailing spaces are trimmed from each line before it
  174. is processed. Although the above example has every line starting at
  175. column 1, the lines could be indented if desired.</li>
  176. <li>Lines starting with "#" are comments are are ignored. Comments must
  177. be on a line by themselves; inline comments will be interpreted as part
  178. of the text of that line.</li>
  179. <li>Lines starting with "$" are directives. At present, just one
  180. directive is recognized:
  181. <dl>
  182. <dt>$NAMESPACE &lt;namespace-name&gt;</dt>
  183. <dd>The sole argument is the name of the namespace in which the
  184. symbols are created. In the absence of a $NAMESPACE directive,
  185. symbols will be put in the anonymous namespace.</dd>
  186. </dl>
  187. </li>
  188. <li>Lines starting with "%" are message definitions and comprise the message
  189. identification and the message text. For example:
  190. @code
  191. % LOG_WRITE_ERROR error writing to %1: %2
  192. @endcode
  193. There may be zero or more spaces between the leading "%" and the
  194. message identification (which, in the example above, is the string
  195. "LOG_WRITE_ERROR").</li>
  196. <li>The message identification can be any string of letters, digits and
  197. underscores, but must not start with a digit.</li>
  198. <li>The rest of the line - from the first non-space character to the
  199. last non- space character - is the text of the message. There are no
  200. restrictions on what characters may be in this text, other than they be
  201. printable (so both single-quote (') and double-quote (") characters are
  202. allowed). The message text may include replacement tokens (the strings
  203. "%1", "%2" etc.). When a message is logged, these are replaced with the
  204. arguments passed to the logging call: %1 refers to the first argument,
  205. %2 to the second etc. Within the message text, the placeholders can
  206. appear in any order and placeholders can be repeated. Otherwise, the
  207. message is printed unmodified.</li>
  208. <li>Remaining lines indicate an explanation for the preceding message.
  209. The explanation can comprise multiple paragraphs, the paragraphs being
  210. separated by blank lines. These lines are intended to be processed by a
  211. separate program to generate an error messages manual; they are ignored
  212. by the message compiler.</li>
  213. <li>Except when used to separate paragraphs in the message explanation,
  214. blank lines are ignored.</li>
  215. </ul>
  216. Although there are few restriction on what can be in the message
  217. identification and text, there are a number of conventions used by Kea,
  218. both in the contents of the message and in the usage. All code
  219. should adhere to these:
  220. <ul>
  221. <li>Message identifications should include at least one underscore.
  222. The component before the first underscore is a string indicating the
  223. origin of the message, and the remainder describes the condition.
  224. So in the example above, the LOG indicates that the error originated
  225. from the logging library and the "WRITE_ERROR" indicates that there was
  226. a problem in a write operation.</li>
  227. <li>The part of the message identification describing the error (e.g.
  228. "WRITE_ERROR" in the example above) should comprise no more than
  229. two or three words separated by underscores. An excessive number
  230. of words or overly long message identification should be avoided;
  231. such information should be put in the text of the message. For example,
  232. "RECEIVED_EMPTY_HOSTNAME_FROM_CLIENT" is excessively long,
  233. "EMPTY_HOSTNAME" being better.</li>
  234. <li>Similarly, the text of the message should be reasonably concise. It should
  235. include enough information (possibly supplied at run-time in the form of
  236. parameters) to allow further investigations to be undertaken if required.
  237. Taking the above example, a suitable error message to indicate that the
  238. resolver has failed to read a name from an upstream authoritative server
  239. could be:
  240. @code
  241. % RESOLVER_FETCH_ERROR fetch from %1 failed, error code %2 (%3)
  242. @endcode
  243. ... where %1 indicates the name or IP address of the server to which the
  244. fetch was sent, %2 the errno value returned and %3 the message associated
  245. with that error number (retrieved via a call to "strerror()").
  246. </li>
  247. <li>The message should not have a comma after the message identification.
  248. The message text should neither start with a capital letter (unless
  249. the first word is a proper noun or is normally written in capitals)
  250. nor end with a period. The message reporting system takes care of such
  251. punctuation.</li>
  252. <li>The parameters substituted into the message text should not include
  253. line breaks. Messages are normally output to the syslog file which
  254. has the inbuilt assumption of one line per message. Splitting a message
  255. across multiple lines makes it awkward to search the file for messages
  256. and associated information.</li>
  257. <li>The message identifier should be unique across the entire Kea
  258. system. (An error will be reported at system start-up if an identifier
  259. is repeated.)</li>
  260. <li>A particular message identifier should only be used at one place in
  261. the Kea code. In this way, if the message indicates a problem, the
  262. code in question can be quickly identified.</li>
  263. <li>The explanation of the message - the free-form text following the
  264. message identification - appears in the Kea message manual. It
  265. should:
  266. <ul>
  267. <li>Describe the severity of the message (debug, informational etc.)</li>
  268. <li>Expand on the text of the message. In some cases, such as
  269. debug messages, the message text may provide more or less sufficient
  270. description. For warnings and errors, the explanation should provide
  271. sufficient background to the problem to allow a non-developer to
  272. understand the issue and to begin fault-finding. If possible, the
  273. explanation should also include suggested remedial action.</li>
  274. </ul>
  275. </ul>
  276. @subsection logSourceFiles Produce Source Files
  277. The message file created in the previous step is then run through the
  278. message compiler to produce source files that are included in the Kea
  279. programs.
  280. @subsubsection logMessageCompiler Message Compiler
  281. The message compiler is a program built in the src/log/compiler directory.
  282. It is invoked by the command:
  283. @code
  284. message [-h] [-v] [-p] [-d dir] <message-file>
  285. @endcode
  286. "-v" prints the version number and exits; "-h" prints brief help text.
  287. The compiler produces source files for C++ unless the "-p" switch is
  288. specified, in which case it produces Python code. Finally, the "-d"
  289. switch directs the compiler to produce the output files in the specified
  290. directory (the default being the current working directory).
  291. <b>C++ Files</b><br/>
  292. Without the "-p" option, the message compiler processes the message file
  293. to produce two files:
  294. <ol>
  295. <li>A C++ header file (called <message-file-name>.h) holding lines of
  296. the form:
  297. @code
  298. namespace <namespace-name> {
  299. extern const isc::log::MessageID LOG_BAD_DESTINATION;
  300. extern const isc::log::MessageID LOG_BAD_SEVERITY;
  301. :
  302. }
  303. @endcode
  304. The symbols define keys in the global message dictionary, with
  305. the namespace enclosing the symbols set by the $NAMESPACE directive.
  306. (This is the reason for the restriction on message identifiers - they
  307. have to be valid C++ symbol names.)</li>
  308. <li>A C++ source file (called <message-file-name>.cc) that holds the definitions
  309. of the global symbols and code to insert the symbols and messages into
  310. an internal dictionary.
  311. Symbols are defined to be equal to strings equal to the identifier, e.g.
  312. @code
  313. extern const isc::log::MessageID LOG_BAD_DESTINATION = "LOG_BAD_DESTINATION";
  314. extern const isc::log::MessageID LOG_BAD_SEVERITY = "LOG_BAD_SEVERITY";
  315. :
  316. @endcode
  317. (The current implementation allows symbols to be compared. However,
  318. use of strings should not be assumed - a future implementation may change
  319. this.) In addition, the file declares an array of identifiers/messages
  320. and an object to add them to the global dictionary, e.g.:
  321. @code
  322. namespace {
  323. const char* values[] = {
  324. "LOG_BAD_DESTINATION", "unrecognized log destination: %1",
  325. "LOG_BAD_SEVERITY", "unrecognized log severity: %1",
  326. :
  327. NULL
  328. };
  329. const isc::log::MessageInitializer initializer(values);
  330. }
  331. @endcode
  332. The constructor of the @ref isc::log::MessageInitializer object retrieves
  333. the singleton global @ref isc::log::MessageDictionary object (created
  334. using standard methods to avoid the "static initialization fiasco") and
  335. adds each identifier and associated text to it. These constructors are run
  336. when the program starts; a check is made as each identifier is added and,
  337. if the identifier already exists in the dictionary, a warning message
  338. is printed to the main logging output when logging is finally enabled.
  339. The appearance of such a message indicates a programming error.
  340. </li>
  341. </ol>
  342. <b>Python Files</b><br/>
  343. If the "-p" option is given, the compiler produces a Python module defining
  344. the messages. The content of this is of the form:
  345. @code
  346. import isc.log
  347. :
  348. LOG_WRITE_ERROR = isc.log.create_message("LOG_WRITE_ERROR",
  349. "error writing to %1 : %2")
  350. @endcode
  351. (The definition is output on one line - it is split across two lines in this
  352. document for readability.)
  353. The module can be imported into other Python code, and messages logged
  354. in a similar way to C++ using the Python logging library.
  355. @subsubsection logMakefile Include Message Compilation in Makefile
  356. The source file for the messages is the ".mes" file, but the files used
  357. by the code (which, in the case of C++, must be compiled and linked)
  358. are the output of the message compiler. (The compiler is produced very
  359. early on in the Kea build sequence, so is available for use in the
  360. building of subsequent components.) To allow this, certain dependencies
  361. must be included in the Makefile.am for each component that uses logging.
  362. <b>Including Message files in C++ Component Builds</b><br/>
  363. The following segment from the "hooks" Makefile.am illustrates
  364. the entries needed.
  365. @code
  366. # Define rule to build logging source files from message file
  367. hooks_messages.h hooks_messages.cc: s-messages
  368. s-messages: hooks_messages.mes
  369. $(top_builddir)/src/lib/log/compiler/message $(top_srcdir)/src/lib/hooks/hooks_messages.mes
  370. touch $@
  371. # Tell automake that the message files are built as part of the build process
  372. # (so that they are built before the main library is built).
  373. BUILT_SOURCES = hooks_messages.h hooks_messages.cc
  374. # Ensure that the message file is included in the distribution
  375. EXTRA_DIST = hooks_messages.mes
  376. # Get rid of generated message files on a clean
  377. CLEANFILES = *.gcno *.gcda hooks_messages.h hooks_messages.cc s-messages
  378. @endcode
  379. The first two rules relate the output .h and .cc files produced by the
  380. message compiler to the input .mes file. The intermediate "s-messages"
  381. file is used to overcome synchronization issues with parallel builds
  382. (where "make" uses multiple processes running in parallel). Note that the
  383. reference to both the compiler and the input message file are via absolute
  384. paths defined in terms of Automake macros. In particular it is important
  385. that the message compiler - which is created during the build process - is
  386. referred to via the "top_builddir" macro, whereas the input message file -
  387. which is in the repository - is accessed through the "top_srcdir" macro.
  388. The BUILT_SOURCES line notifies the Automake that the .h and .cc files
  389. need to be created before they can be used in the compilation, so
  390. instructs it to organize things so that the message compiler is run first.
  391. As the .mes file is not directly included in any compilation, it will
  392. not be automatically copied into a distribution created through this
  393. Makefile.am. The EXTRA_DIST line informs Automake that this file does
  394. need to be included.
  395. Finally, the intermediate files - the .cc and .h file, as well as the
  396. intermediate s-messages file - need to be removed when "make clean" is run.
  397. These files are therefore included in the definition of the CLEANFILES macro.
  398. Not shown are the Makefile.am lines where the .h and .cc file are used. These
  399. are the same as other lines specifying .h and .cc source files.
  400. <b>Including Message files in Python Component Builds</b><br/>
  401. The following (modified) segments from the "xfrin" Makefile.am illustrates
  402. the entries needed.
  403. @code
  404. CLEANFILES = $(PYTHON_LOGMSGPKG_DIR)/work/xfrin_messages.py
  405. CLEANFILES += $(PYTHON_LOGMSGPKG_DIR)/work/xfrin_messages.pyc
  406. :
  407. EXTRA_DIST += xfrin_messages.mes
  408. :
  409. # Define rule to build logging source files from message file
  410. $(PYTHON_LOGMSGPKG_DIR)/work/xfrin_messages.py : xfrin_messages.mes
  411. $(top_builddir)/src/lib/log/compiler/message \
  412. -d $(PYTHON_LOGMSGPKG_DIR)/work -p $(srcdir)/xfrin_messages.mes
  413. @endcode
  414. The CLEANFILES lines remove the created Python (and compiled Python)
  415. code when "make clean" is run.
  416. The EXTRA_DIST line ensures that the .mes file is copied to the
  417. distribution tarball.
  418. The final dependency shows the use of the message compiler to
  419. create the Python message module in a working directory.
  420. @subsection logUsage Using Logging Files in Program Development
  421. @subsubsection logCppUsage Use in a C++ Program or Module
  422. To use logging in a C++ program or module:
  423. <ol>
  424. <li>Build the message header file and source file as described above.</li>
  425. <li>In each C++ file in which logging is to be used, declare a logger
  426. through which the message will be logged.
  427. @code
  428. isc::log::Logger logger("name");
  429. @endcode
  430. This declaration can be per-function, or it can be declared statically
  431. in file scope. The string passed to the constructor is the name of
  432. the logger (it can be any string) and is used when configuring it.
  433. (Remember though that the name of root logger for the program will be
  434. prepended to the name chosen. So if, for example, the name "cache"
  435. is chosen and the model is included in the "b10-resolver" program, the
  436. full name of the logger will be "b10-resolver.cache".) Loggers with
  437. the same name share the same configuration. For this reason if, as is
  438. usual, messages logged in different files in the same component (e.g.
  439. hooks module, nameserver address store, etc.) originate from loggers
  440. with the same name, the logger declaration can be placed into a header
  441. file.</li>
  442. <li>Issue logging calls using supplied macros in "log/macros.h", e.g.
  443. @code
  444. LOG_ERROR(logger, LOG_WRITE_ERROR).arg("output.txt");
  445. LOG_DEBUG(nsas_logger, NSAS_DBG_TRACE, NSAS_LOOKUP_CANCEL).arg(zone);
  446. @endcode
  447. All macros (with the exception of LOG_DEBUG) take two arguments:
  448. the C++ logger object that will be used to log the message, and the
  449. identification of the message to be logged. LOG_DEBUG takes three
  450. arguments, the additional one being the debug level associated with
  451. the message. The .arg() call appended to the end of the LOG_XXX()
  452. macro handles the arguments to the message. A chain of these is used
  453. in cases where a message takes multiple arguments, e.g.
  454. @code
  455. LOG_DEBUG(nsas_logger, NSAS_DBG_RTT, NSAS_UPDATE_RTT)
  456. .arg(addresses_[family][index].getAddress().toText())
  457. .arg(old_rtt).arg(new_rtt);
  458. @endcode
  459. Using the macros is more efficient than direct calls to the methods on
  460. the logger class: they avoid the overhead of evaluating the parameters
  461. to arg() if the logging settings are such that the message is not going
  462. to be output (e.g. it is a DEBUG message and the logging is set to output
  463. messages of INFO severity or above).</li>
  464. <li>The main program unit must include a call to isc::log::initLogger()
  465. (described in more detail below) to set the initial logging severity, debug log
  466. level, and external message file.
  467. </ol>
  468. @subsubsection logPythonUsage Use in a Python Module
  469. To use logging in a Python module:
  470. <ol>
  471. <li>Build message module as described above.</li>
  472. <li>Declare a logger through which the message will be logged.
  473. @code
  474. isc.log.Logger logger("name")
  475. @endcode
  476. The string passed to the constructor is the name of the logger (it can
  477. be any string) and is used when configuring it. Loggers with the same
  478. name share the same configuration.</li>
  479. <li>Issue calls to the logging methods:
  480. @code
  481. logger.error(LOG_WRITE_ERROR, "output.txt")
  482. @endcode
  483. The message parameters are included as trailing arguments in the
  484. logger call.</li>
  485. <li>The main program unit must include a call to isc.log.init() (described
  486. in more detail below) to set the to set the logging severity, debug log
  487. level, and external message file. The settings remain in effect until
  488. the logging configuration is read, so are the ones used during program
  489. initialization.</li>
  490. </ol>
  491. @subsection logInitialization Logging Initialization
  492. In all cases, if an attempt is made to use a logging method before
  493. the logging has been initialized, the program will terminate with a
  494. LoggingNotInitialized exception.
  495. @subsection logInitializationCpp C++ Initialization
  496. Logging Initialization is carried out by calling @ref
  497. isc::log::initLogger(). There are two variants to the call, one for
  498. use by production programs and one for use by unit tests.
  499. @subsubsection logInitializationCppVariant1 Variant #1, Used by Production Programs
  500. The call that should be used by all production programs is:
  501. @code
  502. void isc::log::initLogger(const std::string& root,
  503. isc::log::Severity severity = isc::log::INFO,
  504. int dbglevel = 0, const char* file = NULL,
  505. bool buffer = false);
  506. @endcode
  507. Arguments are:
  508. <dl>
  509. <dt><code>root</code></dt>
  510. <dd>Name of the root logger. This should be the name of the program
  511. (e.g. "b10-auth") and is used when configuring logging.</dd>
  512. <dt><code>severity</code></dt>
  513. <dd>Default severity that the program will start logging with. Although
  514. this may be overridden when the program obtains its configuration from
  515. the configuration database, this is the severity that it used until then.
  516. The logging severity is one of the enum defined in @ref logger.h, i.e.
  517. @code
  518. isc::log::DEBUG
  519. isc::log::INFO
  520. isc::log::WARN
  521. isc::log::ERROR
  522. isc::log::FATAL
  523. isc::log::NONE
  524. @endcode
  525. (The level NONE may be used to disable logging.)
  526. </dd>
  527. <dt><code>dbglevel</code></dt>
  528. <dd>The debug log level is only interpreted when the severity is
  529. isc::log::DEBUG and is an integer ranging from 0 to 99. 0 should be
  530. used for the highest-level debug messages and 99 for the lowest-level
  531. (and typically more verbose) messages.</dd>
  532. <dt><code>file</code></dt>
  533. <dd>The name of a local message file. This will be read and its
  534. definitions used to replace the compiled-in text of the messages.
  535. The default value of NULL indicates that no local message file is
  536. supplied.</dd>
  537. <dt><code>buffer</code></dt>
  538. <dd>If set to true, initial log messages will be internally buffered,
  539. until the first time a logger specification is processed. This
  540. way the program can use logging before even processing its logging
  541. configuration. As soon as any specification is processed (even an
  542. empty one), the buffered log messages will be flushed according to
  543. the specification. Note that if this option is used, the program
  544. SHOULD call one of the @ref isc::log::LoggerManager::process() calls.
  545. (If you are using the built-in logging configuration handling in @ref
  546. isc::config::ModuleCCSession, this is automatically handled.) If the
  547. program exits before this is done, all log messages are dumped in a raw
  548. format to stdout (so that no messages get lost).</dd>
  549. </dl>
  550. @subsubsection logInitializationCppVariant2 Variant #2, Used by Unit Tests
  551. @code
  552. void isc::log::initLogger()
  553. @endcode
  554. This is the call that should be used by unit tests. In this variant,
  555. all the options are supplied by environment variables: it should not
  556. be used for production programs to avoid the chance that the program
  557. operation is affected by inadvertently-defined environment variables. The
  558. environment variables are:
  559. <dl>
  560. <dt>KEA_LOGGER_ROOT</dt>
  561. <dd>Sets the "root" for the unit test. If not defined, the name "kea"
  562. is used.</dd>
  563. <dt>KEA_LOGGER_SEVERITY</dt>
  564. <dd>The severity to set for the root logger in the unit test.
  565. Valid values are "DEBUG", "INFO", "WARN", "ERROR", "FATAL" and "NONE".
  566. If not defined, "INFO" is used.</dd>
  567. <dt>KEA_LOGGER_DBGLEVEL</dt>
  568. <dd>If KEA_LOGGER_SEVERITY is set to "DEBUG", the debug level. This can
  569. be a number between 0 and 99, and defaults to 0.</dd>
  570. <dt>KEA_LOGGER_LOCALMSG</dt>
  571. <dd>If defined, points to a local message file. The default is not to
  572. use a local message file.</dd>
  573. <dt>KEA_LOGGER_DESTINATION</dt>
  574. <dd>The location to which log message are written. This can be one of:
  575. <ul>
  576. <li><b>stdout</b> Message are written to stdout.</li>
  577. <li><b>stderr</b> Messages are written to stderr.</li>
  578. <li><b>syslog[:facility]</b> Messages are written to syslog. If the
  579. optional "facility" is used, the messages are written using that facility.
  580. (This defaults to "local0" if not specified.)</li>
  581. <li><b>Anything else</b> Interpreted as the name of a file to which
  582. output is appended. If the file does not exist, a new one is opened.</li>
  583. </ul>
  584. In the case of "stdout", "stderr" and "syslog", they must be written exactly
  585. as is - no leading or trailing spaces, and in lower-case.</dd>
  586. </dl>
  587. @subsection logInitializationHooks Hooks Specific Notes
  588. All hooks libraries should use Kea logging mechanisms. The loggers and the
  589. library specific log messages are created in the same way as for the core
  590. Kea modules. The loggers created within the hook library belong to the
  591. logging hierarchy of the Kea process and their configuration can be
  592. controlled from the Kea configuration file. If the configuration file doesn't
  593. contain the specific configuration for the logger used in the library,
  594. this logger is given the configuration of the root Kea logger.
  595. The hook libraries are loaded dynamically. This requires that the global log
  596. messages dictionary, holding the mapping of specific log message
  597. identifiers to the actual messages, is updated to include the messages
  598. specified in the hook library when the library is loaded. Conversely, the
  599. messages have to be removed from the dictionary when the library is unloaded.
  600. The new messages are added to the global dictionary using the
  601. @c isc::log::MessageInitializer::loadDictionary static function. It is
  602. called by the @c isc::hooks::LibraryManager::loadLibrary for each loaded
  603. library.
  604. When the library is unloaded, the instance of the
  605. @c isc::log::MessageInitializer defined in the library is destroyed
  606. and its destructor removes the messages registered by the destroyed
  607. instance from the global dictionary.
  608. The hook library itself must not perform any action to register or
  609. unregister log messages in the global dictionary!
  610. @subsection logInitializationPython Python Initialization
  611. To initialize the logger in a Python program, the "init" method must be
  612. called:
  613. @code
  614. isc.log.init(name, severity, debuglevel, file, buffer)
  615. @endcode
  616. <dl>
  617. <dt><code>name</code></dt>
  618. <dd>String giving the name of the root logger. This is the only mandatory
  619. argument, the rest are optional.</dd>
  620. <dt><code>severity</code></dt>
  621. <dd>The severity, and is one of the strings "DEBUG", INFO" etc.
  622. The default is "INFO".</dd>
  623. <dt><code>debuglevel</code></dt>
  624. <dd>Debug level, an integer between 0 and 99. A default value of 0 will
  625. be used if this is not specified.</dd>
  626. <dt><code>file</code></dt>
  627. <dd>Name of the external message file (if present). By default, no
  628. external message file is used.</dd>
  629. <dt><code>buffer</code></dt>
  630. <dd>If set to true, initial log messages will be internally buffered,
  631. until the first time a logger specification is processed. This
  632. way the program can use logging before even processing its logging
  633. configuration. By default, no buffer is used.</dd>
  634. </dl>
  635. @section logNotes Notes on the Use of Logging
  636. One thing that should always be kept in mind is whether the logging
  637. could be used as a means for a DOS attack. For example, if a warning
  638. message is logged every time an invalid packet is received, an attacker
  639. could simply send large numbers of invalid packets. Of course, warnings
  640. could be disabled (or just warnings for that that particular logger),
  641. but nevertheless the message is an attack vector. As a general rule,
  642. if the message can be triggered by a user action, it can be used as an
  643. attack vector.
  644. There are two approaches to get round this:
  645. <ol>
  646. <li>Log messages generated by such user actions as DEBUG messages. DEBUG
  647. is not enabled by default, so these events will not be recorded unless
  648. DEBUG is specifically enabled. Choosing a suitable debug level for
  649. such messages will select only those messages and not the more general
  650. debug messages.</li>
  651. <li>Record system-related and packet-related messages via different
  652. loggers. As the loggers are independent and the severity levels
  653. independent, fine-tuning of what and what is not recorded can be achieved.</li>
  654. </ol>
  655. */