-// Copyright (C) 2011,2015 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2011, 2015 Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
/// \b Invocation<BR>
/// The program is invoked with the command:
///
-/// <tt>message [-v | -h | -p | -d <dir> | <message-file>]</tt>
+/// <tt>message [-v | -h | -d <dir> | <message-file>]</tt>
///
/// It reads the message file and writes out two files of the same
/// name in the current working directory (unless -d is used) but
-/// with extensions of .h and .cc, or .py if -p is used.
+/// with extensions of .h and .cc.
///
-/// -v causes it to print the version number and exit. -h prints a help
-/// message (and exits). -p sets the output to python. -d <dir> will make
-/// it write the output file(s) to dir instead of current working
-/// directory
+/// -v causes it to print the version number and exit. -h prints a
+/// help message (and exits). -d <dir> will make it write the
+/// output file(s) to dir instead of current working directory
/// \brief Print Version
void
usage() {
cout <<
- "Usage: message [-h] [-v] [-p] [-d dir] <message-file>\n" <<
+ "Usage: message [-h] [-v] [-d dir] <message-file>\n" <<
"\n" <<
"-h Print this message and exit\n" <<
"-v Print the program version and exit\n" <<
- "-p Output python source instead of C++ ones\n" <<
"-d <dir> Place output files in given directory\n" <<
"\n" <<
"<message-file> is the name of the input message file.\n";
}
}
-/// \brief Write python file
-///
-/// Writes the python file containing the symbol definitions as module level
-/// constants. These are objects which register themselves at creation time,
-/// so they can be replaced by dictionary later.
-///
-/// \param file Name of the message file. The source code is written to a file
-/// file of the same name but with a .py suffix.
-/// \param dictionary The dictionary holding the message definitions.
-/// \param output_directory if not null NULL, output files are written
-/// to the given directory. If NULL, they are written to the current
-/// working directory.
-///
-/// \note We don't use the namespace as in C++. We don't need it, because
-/// python file/module works as implicit namespace as well.
-
-void
-writePythonFile(const string& file, MessageDictionary& dictionary,
- const char* output_directory)
-{
- Filename message_file(file);
- Filename python_file(Filename(message_file.name()).useAsDefault(".py"));
- if (output_directory != NULL) {
- python_file.setDirectory(output_directory);
- }
-
- // Open the file for writing
- ofstream pyfile(python_file.fullName().c_str());
-
- // Write the comment and imports
- pyfile <<
- "# File created from " << message_file.fullName() << " on " <<
- currentTime() << "\n" <<
- "\n" <<
- "import isc.log\n" <<
- "\n";
-
- vector<string> idents(sortedIdentifiers(dictionary));
- BOOST_FOREACH(const string& ident, idents) {
- pyfile << ident << " = isc.log.create_message(\"" <<
- ident << "\", \"" << quoteString(dictionary.getText(ident)) <<
- "\")\n";
- }
-
- pyfile.close();
-}
-
/// \brief Write Header File
///
/// Writes the C++ header file containing the symbol definitions. These are
optind = 1; // Ensure we start a new scan
int opt; // Value of the option
- bool doPython = false;
const char *output_directory = NULL;
while ((opt = getopt(argc, argv, soptions)) != -1) {
output_directory = optarg;
break;
- case 'p':
- doPython = true;
- break;
-
case 'h':
usage();
return (0);
// Error (and quit) if there are of any duplicates encountered.
errorDuplicates(reader);
- if (doPython) {
- // Warn in case of ignored directives
- if (!reader.getNamespace().empty()) {
- cerr << "Python mode, ignoring the $NAMESPACE directive" <<
- endl;
- }
-
- // Write the whole python file
- writePythonFile(message_file, dictionary, output_directory);
- } else {
- // Get the namespace into which the message definitions will be put and
- // split it into components.
- vector<string> ns_components =
- splitNamespace(reader.getNamespace());
-
- // Write the header file.
- writeHeaderFile(message_file, ns_components, dictionary,
- output_directory);
-
- // Write the file that defines the message symbols and text
- writeProgramFile(message_file, ns_components, dictionary,
- output_directory);
- }
+ // Get the namespace into which the message definitions will be put and
+ // split it into components.
+ vector<string> ns_components =
+ splitNamespace(reader.getNamespace());
+
+ // Write the header file.
+ writeHeaderFile(message_file, ns_components, dictionary,
+ output_directory);
+
+ // Write the file that defines the message symbols and text
+ writeProgramFile(message_file, ns_components, dictionary,
+ output_directory);
}
catch (const MessageException& e) {
have a parent. The reason for this hierarchy is that unless a logger
explicitly assigns a value to an attribute (such as severity of messages
it should log), it picks it up the value from the parent. In Kea,
-each component (b10-dhcp4, b10-dhcp-ddns etc.) has a root logger (named
+each component (kea-dhcp4, kea-dhcp-ddns etc.) has a root logger (named
after the program) and every other logger in the component is a child
of that. So in the example above, the error/syslog attributes could be
-associated with the b10-resolver logger while the logger associated with
+associated with the kea-resolver logger while the logger associated with
the cache sets its own values for the debug/file attributes.
More information about the logging hierarchy can be found in the section
For C++ development, the message compiler produces two files in the
default directory, having the same name as the input file but with file
-types of ".h" and ".cc". For Python, the message compiler will produce
-a Python module containing the symbols.</li>
+types of ".h" and ".cc".</li>
<li>Include the resultant files in your source code to define message symbols,
-and (for C++) compile the code and link it into your program.</li>
+and compile the code and link it into your program.</li>
<li>Declare loggers in your code and use them to log messages.</li>
The message compiler is a program built in the src/log/compiler directory.
It is invoked by the command:
@code
-message [-h] [-v] [-p] [-d dir] <message-file>
+message [-h] [-v] [-d dir] <message-file>
@endcode
"-v" prints the version number and exits; "-h" prints brief help text.
-The compiler produces source files for C++ unless the "-p" switch is
-specified, in which case it produces Python code. Finally, the "-d"
-switch directs the compiler to produce the output files in the specified
-directory (the default being the current working directory).
+Finally, the "-d" switch directs the compiler to produce the output
+files in the specified directory (the default being the current
+working directory).
<b>C++ Files</b><br/>
-Without the "-p" option, the message compiler processes the message file
-to produce two files:
<ol>
<li>A C++ header file (called <message-file-name>.h) holding lines of
</li>
</ol>
-<b>Python Files</b><br/>
-If the "-p" option is given, the compiler produces a Python module defining
-the messages. The content of this is of the form:
-@code
-import isc.log
- :
-LOG_WRITE_ERROR = isc.log.create_message("LOG_WRITE_ERROR",
- "error writing to %1 : %2")
-@endcode
-(The definition is output on one line - it is split across two lines in this
-document for readability.)
-
-The module can be imported into other Python code, and messages logged
-in a similar way to C++ using the Python logging library.
-
@subsubsection logMakefile Include Message Compilation in Makefile
-The source file for the messages is the ".mes" file, but the files used
-by the code (which, in the case of C++, must be compiled and linked)
-are the output of the message compiler. (The compiler is produced very
-early on in the Kea build sequence, so is available for use in the
-building of subsequent components.) To allow this, certain dependencies
-must be included in the Makefile.am for each component that uses logging.
+The source file for the messages is the ".mes" file, but the files
+used by the code which must be compiled and linked are the output of
+the message compiler. (The compiler is produced very early on in the
+Kea build sequence, so is available for use in the building of
+subsequent components.) To allow this, certain dependencies must be
+included in the Makefile.am for each component that uses logging.
<b>Including Message files in C++ Component Builds</b><br/>
The following segment from the "hooks" Makefile.am illustrates
Not shown are the Makefile.am lines where the .h and .cc file are used. These
are the same as other lines specifying .h and .cc source files.
-<b>Including Message files in Python Component Builds</b><br/>
-The following (modified) segments from the "xfrin" Makefile.am illustrates
-the entries needed.
-
-@code
-CLEANFILES = $(PYTHON_LOGMSGPKG_DIR)/work/xfrin_messages.py
-CLEANFILES += $(PYTHON_LOGMSGPKG_DIR)/work/xfrin_messages.pyc
- :
-EXTRA_DIST += xfrin_messages.mes
- :
-# Define rule to build logging source files from message file
-$(PYTHON_LOGMSGPKG_DIR)/work/xfrin_messages.py : xfrin_messages.mes
- $(top_builddir)/src/lib/log/compiler/message \
- -d $(PYTHON_LOGMSGPKG_DIR)/work -p $(srcdir)/xfrin_messages.mes
-@endcode
-The CLEANFILES lines remove the created Python (and compiled Python)
-code when "make clean" is run.
-
-The EXTRA_DIST line ensures that the .mes file is copied to the
-distribution tarball.
-
-The final dependency shows the use of the message compiler to
-create the Python message module in a working directory.
-
-
@subsection logUsage Using Logging Files in Program Development
@subsubsection logCppUsage Use in a C++ Program or Module
the logger (it can be any string) and is used when configuring it.
(Remember though that the name of root logger for the program will be
prepended to the name chosen. So if, for example, the name "cache"
-is chosen and the model is included in the "b10-resolver" program, the
-full name of the logger will be "b10-resolver.cache".) Loggers with
+is chosen and the model is included in the "kea-resolver" program, the
+full name of the logger will be "kea-resolver.cache".) Loggers with
the same name share the same configuration. For this reason if, as is
usual, messages logged in different files in the same component (e.g.
hooks module, nameserver address store, etc.) originate from loggers
level, and external message file.
</ol>
-@subsubsection logPythonUsage Use in a Python Module
-To use logging in a Python module:
-<ol>
-<li>Build message module as described above.</li>
-
-<li>Declare a logger through which the message will be logged.
-@code
-isc.log.Logger logger("name")
-@endcode
-The string passed to the constructor is the name of the logger (it can
-be any string) and is used when configuring it. Loggers with the same
-name share the same configuration.</li>
-
-<li>Issue calls to the logging methods:
-@code
-logger.error(LOG_WRITE_ERROR, "output.txt")
-@endcode
-The message parameters are included as trailing arguments in the
-logger call.</li>
-
-<li>The main program unit must include a call to isc.log.init() (described
-in more detail below) to set the to set the logging severity, debug log
-level, and external message file. The settings remain in effect until
-the logging configuration is read, so are the ones used during program
-initialization.</li>
-</ol>
-
-
@subsection logInitialization Logging Initialization
In all cases, if an attempt is made to use a logging method before
the logging has been initialized, the program will terminate with a
<dl>
<dt><code>root</code></dt>
<dd>Name of the root logger. This should be the name of the program
-(e.g. "b10-auth") and is used when configuring logging.</dd>
+(e.g. "kea-auth") and is used when configuring logging.</dd>
<dt><code>severity</code></dt>
<dd>Default severity that the program will start logging with. Although
The hook library itself must not perform any action to register or
unregister log messages in the global dictionary!
-@subsection logInitializationPython Python Initialization
-To initialize the logger in a Python program, the "init" method must be
-called:
-@code
-isc.log.init(name, severity, debuglevel, file, buffer)
-@endcode
-
-<dl>
-<dt><code>name</code></dt>
-<dd>String giving the name of the root logger. This is the only mandatory
-argument, the rest are optional.</dd>
-
-<dt><code>severity</code></dt>
-<dd>The severity, and is one of the strings "DEBUG", INFO" etc.
-The default is "INFO".</dd>
-
-<dt><code>debuglevel</code></dt>
-<dd>Debug level, an integer between 0 and 99. A default value of 0 will
-be used if this is not specified.</dd>
-
-<dt><code>file</code></dt>
-<dd>Name of the external message file (if present). By default, no
-external message file is used.</dd>
-
-<dt><code>buffer</code></dt>
-<dd>If set to true, initial log messages will be internally buffered,
-until the first time a logger specification is processed. This
-way the program can use logging before even processing its logging
-configuration. By default, no buffer is used.</dd>
-</dl>
-
-
@section logNotes Notes on the Use of Logging
One thing that should always be kept in mind is whether the logging
could be used as a means for a DOS attack. For example, if a warning