[[libqb]] 0.17.2 and later supports "extended information logging," also referred to as "split logging." With this feature, you can log a single message with less detail in one log and greater detail in another log.
== Why ==
LibQB lets you have multiple logs, and filter messages to them differently. For example, Pacemaker uses this to put messages of notice and higher severity (which are of interest to system administrators) in the system log, and all messages (including info and lower severity, of interest mainly to developers) in /var/log/pacemaker.log.
However, average users might still find the system log messages difficult to follow. Extended information logging is one way to address that, by splitting not just separate log messages, but the contents of a single log message.
== The extended information marker ==
LibQB defines the constants `QB_XC` (character literal) and `QB_XS` (the same thing but as a string literal). If a format string contains that character, everything after it is considered "extended information". The magic character will be displayed as a pipe ('|') in actual output.
Applications can enable or disable the logging of extended information. The default is enabled, meaning the entire message goes to all logs.
Example:
```
/* Disable printing extended information to syslog */
qb_log_ctl(QB_LOG_SYSLOG, QB_LOG_CONF_EXTENDED, QB_FALSE);
/* Print a message with extended information */
/* We are just using string literal concatenation here */
qb_log(LOG_ERROR, "Something bad happened! " QB_XS " foo=2");
```
With the above, the system log will show only "Something bad happened!", but any other logs defined will show "Something bad happened! | foo=2".
The magic character is defined as the ASCII 'bell' control character ('\a'). In the unlikely event someone wants to actually log that, they can put it in the extended information (only the first occurrence is significant) or use a %c specifier in the format string (only occurrences in the format string are significant).
== Backward compatibility ==
If you want to use the new feature but still be able to link against older versions of libqb, you can wrap calls according to whether QB_XS is defined. Here is an example based on how Pacemaker does it:
```
/* "Extended information" logging support */
# ifdef QB_XS
/* Extended information is supported, so use it */
# define MY_XS QB_XS
# define enable_extended_logging(t, e) qb_log_ctl((t), QB_LOG_CONF_EXTENDED, (e))
# else
/* Extended information is not supported, so just log the entire message in all logs */
# define MY_XS "|"
/* A caller might want to check the return value, so we can't define this as a
* no-op, and we can't simply define it to be 0 because gcc will then complain
* when the value isn't checked.
*/
static inline int
enable_extended_logging(int t, int e)
{
return 0;
}
# endif
```
The main code can call `enable_extended_logging()` and log messages using `MY_XS` to separate the extended information.