# Logging

## Logging configuration

The logging system in Kea is configured through the Logging module. All modules will look at the configuration in Logging to see what should be logged and to where.

### Loggers

Within Kea, a message is logged through a component called a "logger". Different parts of log messages through different loggers, and each logger can be configured independently of one another.

In the Logging module, you can specify the configuration for zero or more loggers; any that are not specified will take appropriate default values.

The three most important elements of a logger configuration are the `name` (the component that is generating the messages), the `severity` (what to log), and the `output_options` (where to log).

#### name (string)

Each logger in the system has a name, the name being that of the component using it to log messages. For instance, if you want to configure logging for the Dhcp4 module, you add an entry for a logger named Dhcp4. This configuration will then be used by the loggers in the Dhcp4 module, and all the libraries used by it.

If you want to specify logging for one specific library within the module, you set the name to module.library. For example, the logger used by the nameserver address store component has the full name of Dhcp4.dhcpsrv. If there is no entry in Logging for a particular library, it will use the configuration given for the module.

To illustrate this, suppose you want the dhcpsrv library to log messages of severity DEBUG, and the rest of the Dhcp4 code to log messages of severity INFO. To achieve this you specify two loggers, one with the name Dhcp4 and severity INFO, and one with the name Dhcp4.dhcpsrv with severity DEBUG. As there are no entries for other libraries, they will use the configuration for the module (Dhcp4), so giving the desired behavior.

One special case is that of a module name of * (asterisks), which is interpreted as any module. You can set global logging options by using this, including setting the logging configuration for a library that is used by multiple modules (e.g. *.config specifies the configuration library code in whatever module is using it).

If there are multiple logger specifications in the configuration that might match a particular logger, the specification with the more specific logger name takes precedence. For example, if there are entries for both * and Dhcp4, the Dhcp4 module &mdash; and all libraries it uses &mdash; will log messages according to the configuration in the second entry (Dhcp4). All other modules will use the configuration of the first entry (*).

One final note about the naming. When specifying the module name within a logger, use the name of the module as specified in `bindctl`, e.g. Dhcp4 for the Dhcp4 module, Dhcp6 for the Dhcp6 module, etc. When the message is logged, the message will include the name of the logger generating the message, but with the module name replaced by the name of the process implementing the module (so for example, a message generated by the Dhcp4 logger will appear in the output with a logger name of kea-dhcp4).

#### severity (string)

This specifies the category of messages logged. Each message is logged with an associated severity which may be one of the following (in descending order of severity):

- FATAL

- ERROR

- WARN

- INFO

- DEBUG

When the severity of a logger is set to one of these values, it will only log messages of that severity, and the severities above it. The severity may also be set to NONE, in which case all messages from that logger are inhibited.

#### output_options (list)

Each logger can have zero or more `output_options`. These specify where log messages are sent to. These are explained in detail below.

The other options for a logger are:

#### debuglevel (integer)

When a logger's severity is set to DEBUG, this value specifies what debug messages should be printed. It ranges from 0 (least verbose) to 99 (most verbose).

If severity for the logger is not DEBUG, this value is ignored.

#### additive (true or false)

If this is true, the `output_options` from the parent will be used. For example, if there are two loggers configured; Dhcp4 and Dhcp4.dhcpsrv, and `additive` is true in the second, it will write the log messages not only to the destinations specified for Dhcp4.dhcpsrv, but also to the destinations as specified in the `output_options` in the logger named Dhcp4.

### Output Options

The main settings for an output option are the `destination` and a value called `output`, the meaning of which depends on the destination that is set.

#### destination (string)

The destination is the type of output. It can be one of:

- console

- file

- syslog

#### output (string)

Depending on what is set as the output destination, this value is interpreted as follows:

`destination` is console

  The value of output must be one of stdout (messages printed to standard output) or stderr (messages printed to standard error).

  Note: if output is set to stderr and a lot of messages are produced in a short time (e.g. if the logging level is set to DEBUG), you may occasionally see some messages jumbled up together. This is due to a combination of the way that messages are written to the screen and the unbuffered nature of the standard error stream. If this occurs, it is recommended that output be set to stdout.

`destination` is file

  The value of output is interpreted as a file name; log messages will be appended to this file.

`destination` is syslog

  The value of output is interpreted as the `syslog` facility (e.g. local0) that should be used for log messages.

The other options for `output_options` are:

##### flush (true of false)

Flush buffers after each log message. Doing this will reduce performance but will ensure that if the program terminates abnormally, all messages up to the point of termination are output.

##### maxsize (integer)

Only relevant when destination is file, this is maximum file size of output files in bytes. When the maximum size is reached, the file is renamed and a new file opened. (For example, a ".1" is appended to the name &mdash; if a ".1" file exists, it is renamed ".2", etc.)

If this is 0, no maximum file size is used.

Due to a limitation of the underlying logging library (log4cplus), rolling over the log files (from ".1" to ".2", etc) may show odd results: There can be multiple small files at the timing of roll over. This can happen when multiple processes try to roll over the files simultaneously. Version 1.1.0 of log4cplus solved this problem, so if this or higher version of log4cplus is used to build Kea, it shouldn't happen. Even for older versions it is normally expected to happen rarely unless the log messages are produced very frequently by multiple different processes.

##### maxver (integer)

Maximum number of old log files to keep around when rolling the output file. Only relevant when `destination` is file.

### Example session

In this example we want to set the global logging to write to the file `/var/log/my_bind10.log`, at severity WARN. We want the authoritative server to log at DEBUG with debuglevel 40, to a different file (`/tmp/debug_messages`).

Start `bindctl`.

    ["login success "]
    > config show Logging
    Logging/loggers	[]	list

By default, no specific loggers are configured, in which case the severity defaults to INFO and the output is written to stderr.

Let's first add a default logger:

    > config add Logging/loggers
    > config show Logging
    Logging/loggers/	list	(modified)

The loggers value line changed to indicate that it is no longer an empty list:

    > config show Logging/loggers
    Logging/loggers[0]/name	""	string	(default)
    Logging/loggers[0]/severity	"INFO"	string	(default)
    Logging/loggers[0]/debuglevel	0	integer	(default)
    Logging/loggers[0]/additive	false	boolean	(default)
    Logging/loggers[0]/output_options	[]	list	(default)

The name is mandatory, so we must set it. We will also change the severity as well. Let's start with the global logger.

    > config set Logging/loggers[0]/name *
    > config set Logging/loggers[0]/severity WARN
    > config show Logging/loggers
    Logging/loggers[0]/name	"*"	string	(modified)
    Logging/loggers[0]/severity	"WARN"	string	(modified)
    Logging/loggers[0]/debuglevel	0	integer	(default)
    Logging/loggers[0]/additive	false	boolean	(default)
    Logging/loggers[0]/output_options	[]	list	(default)

Of course, we need to specify where we want the log messages to go, so we add an entry for an output option.

    >  config add Logging/loggers[0]/output_options
    >  config show Logging/loggers[0]/output_options
    Logging/loggers[0]/output_options[0]/destination	"console"	string	(default)
    Logging/loggers[0]/output_options[0]/output	"stdout"	string	(default)
    Logging/loggers[0]/output_options[0]/flush	false	boolean	(default)
    Logging/loggers[0]/output_options[0]/maxsize	0	integer	(default)
    Logging/loggers[0]/output_options[0]/maxver	0	integer	(default)

These aren't the values we are looking for.

    >  config set Logging/loggers[0]/output_options[0]/destination file
    >  config set Logging/loggers[0]/output_options[0]/output /var/log/kea.log
    >  config set Logging/loggers[0]/output_options[0]/maxsize 204800
    >  config set Logging/loggers[0]/output_options[0]/maxver 8

Which would make the entire configuration for this logger look like:

    >  config show all Logging/loggers
    Logging/loggers[0]/name	"*"	string	(modified)
    Logging/loggers[0]/severity	"WARN"	string	(modified)
    Logging/loggers[0]/debuglevel	0	integer	(default)
    Logging/loggers[0]/additive	false	boolean	(default)
    Logging/loggers[0]/output_options[0]/destination	"file"	string	(modified)
    Logging/loggers[0]/output_options[0]/output	"/var/log/kea.log"	string	(modified)
    Logging/loggers[0]/output_options[0]/flush	false	boolean	(default)
    Logging/loggers[0]/output_options[0]/maxsize	204800	integer	(modified)
    Logging/loggers[0]/output_options[0]/maxver	8	integer	(modified)

That looks OK, so let's commit it before we add the configuration for the authoritative server's logger.

    >  config commit

Now that we have set it, and checked each value along the way, adding a second entry is quite similar.

    >  config add Logging/loggers
    >  config set Logging/loggers[1]/name Dhcp4
    >  config set Logging/loggers[1]/severity DEBUG
    >  config set Logging/loggers[1]/debuglevel 40
    >  config add Logging/loggers[1]/output_options
    >  config set Logging/loggers[1]/output_options[0]/destination file
    >  config set Logging/loggers[1]/output_options[0]/output /tmp/dhcp4_debug.log
    >  config commit

And that's it. Once we have found whatever it was we needed the debug messages for, we can simply remove the second logger to let the DHCP server use the same settings as the rest.

    >  config remove Logging/loggers[1]
    >  config commit

And every module will now be using the values from the logger named *.

## Logging Message Format

Each message written to the configured logging destinations comprises a number of components that identify the origin of the message and, if the message indicates a problem, information about the problem that may be useful in fixing it.

Consider the message below logged to a file:

    2014-04-11 12:58:01.005 INFO  [kea-dhcp4.dhcpsrv/27456]
        DHCPSRV_MEMFILE_DB opening memory file lease database: type=memfile universe=4

Note: the layout of messages written to the system logging file (syslog) may be slightly different. This message has been split across two lines here for display reasons; in the logging file, it will appear on one line.)

The log message comprises a number of components:

2014-04-11 12:58:01.005

  The date and time at which the message was generated.

INFO

  The severity of the message.

[kea-dhcp4.dhcpsrv/27456]

  The source of the message. This comprises two components: the BIND 10 process generating the message (in this case, `kea-dhcp4`) and the module within the program from which the message originated (which is the name of the common library used by DHCP server implementations).

DHCPSRV_MEMFILE_DB

  The message identification. Every message in Kea has a unique identification, which can be used as an index into the Kea Messages Manual () from which more information can be obtained.

opening memory file lease database: type=memfile universe=4

  A brief description. Within this text, information relating to the condition that caused the message to be logged will be included. In this example, the information is logged that the in-memory lease database backend will be used to store DHCP leases.