text: Overview
  --------
  
  This is a flexible logging library for C++, targeted primarily at debug logging
  support.  It supports hierarchical log categories to easily control debug log
  levels.  It also aims to have minimal performance overhead for disabled log
  statements, making it possible to keep debug log statements throughout the code
  base, even in performance critical sections.  This allows debug log messages to
  be easily turned on for particular areas of the code at runtime when necessary
  to help debug an issue, without having to worry about the overhead of log
  messages during normal use.
  
  Log Categories
  --------------
  
  ## Log Category Names
  
  All log messages get logged to a particular log category.  Log category names
  are hierarchical, separated by periods.  For instance, `folly.io` and
  `folly.futures` are both sub-categories of `folly`.  `folly.io.async` is a
  sub-category of `folly.io`.  The root category's name is the empty string.
  
  ## Log Level Checks
  
  When a message is logged to a given category, an admittance check is performed
  to see if the log message should be enabled.  The admittance check compares the
  log level of the message against the effective level of that category.
  
  By default the effective level of a category is the minimum of its level and
  the level set for any of its parent categories.  This means that when you
  increase the log verbosity for a particular category you automatically turn up
  the verbosity for the entire tree of children categories underneath it.
  
  For example, setting the log level for the `folly` category to `WARN` means
  that log messages to any sub-category under `folly` will be admitted if they
  have a level of `WARN` or higher.  If the level for `folly.io` is `DEBUG`, then
  messages to all categories under `folly.io` will admit `DEBUG` and higher
  messages, while the rest of the categories `folly` under folly would admit
  `WARN` and higher messages.
  
  However, you can also configure specific log categories to turn off inheritance
  of their parent log levels.  This allows you to increase the log verbosity for
  a large category tree, but still use a lower verbosity for specific
  sub-categories.  For example, if the `folly` category's level is set to
  `DEBUG`, but you disable level inheritance for `folly.futures`, the
  `folly.futures` level will not use it's parent's `DEBUG` log level, and will
  only consider the level set locally on this category.
  
  Once a log message is admitted, it is processed by the `LogCategory` where it
  was logged, as well as by all parent log categories, up to the root.
  
  ## Log Handlers
  
  `LogHandler` objects can be attached to a log category.  When a log message is
  received at a given log category it will be given to all `LogHandler` objects
  attached to that category.
  
  `LogHandler` objects can perform arbitrary actions based on the log message.
  They may write the message to a local file, print it to `stderr` or `stdout`,
  or send the message to a remote logging service.
  
  `LogHandlers` may perform their own additional log level check, but by default
  `LogHandlers` process all messages received at the category they are attached
  to.
  
  Motivation
  ----------
  
  The goal of this logging library is to provide a flexible, easy to use logging
  mechanism that allows debug log statements to be used liberally throughout a
  code base.
  
  There are two primary design goals for this library:
  
  1. Log statements should be cheap when disabled.
  2. It should be easy to control log levels for specific areas of the code base.
  
  While there are a number of other logging libraries for C++, none of the ones I
  have seen fulfill both criteria.  The Google logging library (glog) satisfies
  the first goal, but not the second.  Most of the other log libraries I have
  examined satisfy the second goal, but not the first.
  
  In particular, for item 1, disabled log statements should boil down to a single
  conditional check.  Arguments for the log message should not be evaluated if
  the log message is not enabled.  Unfortunately, this generally means that
  logging must be done using preprocessor macros.
  
  Item 2 largely boils down to having hierarchical logging categories, to allow
  easily turning log levels up and down for specific sections of the code base.
  For instance, this allows a service to enable a higher log level for its
  primary functionality, while having slightly lower levels for libraries that it
  depends on.
  
  Other Advantages
  ----------------
  
  Beyond the primary goals mentioned above, this log library does have some other
  advantages over glog:
  
  ## Support for using `fmt::format()` to generate formatted log messages
  
  Two separate mechanisms are provided for formatting log messages: basic
  concatenation of arguments into string (using `folly::to<std::string>()`),
  and more flexible formatting using `fmt::format()`.  This provides convenient
  and type-safe mechanisms for formatting log messages.
  
  ## Escapes unprintable characters in log messages by default.
  
  This makes it safer to log arbitrary input data, without worrying if the data
  may contain potentially malicious terminal escape sequences.
  
  For instance, this helps avoid vulnerabilities like CVE-2013-1862 and
  CVE-2009-4496.
  
  # Support for handling multi-line log messages
  
  The LogMessage class indicates if the message contains internal newlines,
  making it easier for handlers to add a log header to each line of the message,
  avoiding subsequent lines that do not start with the correct log header.
  