6

I'm using custom boost::log formatter for color coding the output log message, but I'm failing to find the proper way to add TimeStamp and ThreadID attributes to the log. When I'm using file logging I just write keywords::format = "[%TimeStamp%] [%ThreadID%] [%Severity%]: %Message%" as logging::add_file_log parameter. I want to have similar effect in the following custom formatter:

void coloring_formatter(const logging::record_view& record,
                        logging::formatting_ostream& stream)
{
  auto severity = record[logging::trivial::severity];
  assert(severity);

  stream << "\e[1m";

  switch (severity.get())
  {
  case logging::trivial::severity_level::trace:
    stream << "\e[97m";
    break;
  case logging::trivial::severity_level::debug:
    stream << "\e[34m";
    break;
  case logging::trivial::severity_level::info:
    stream << "\e[32m";
    break;
  case logging::trivial::severity_level::warning:
    stream << "\e[93m";
    break;
  case logging::trivial::severity_level::error:
    stream << "\e[91m";
    break;
  case logging::trivial::severity_level::fatal:
    stream << "\e[41m";
    break;
  }

  stream // << output TimeStamp
         // << output ThreadID
         << "[" << severity << "] "
         << record[logging::expressions::smessage]
         << "\e[0m";
}
bobeff
  • 3,543
  • 3
  • 34
  • 62

1 Answers1

5

Given that you have added these attributes to log records, there are multiple ways to extract them. The simplest way is to use keywords. First you declare keywords for the attributes:

BOOST_LOG_ATTRIBUTE_KEYWORD(a_timestamp, "TimeStamp", attrs::local_clock::value_type)
BOOST_LOG_ATTRIBUTE_KEYWORD(a_thread_id, "ThreadID", attrs::current_thread_id::value_type)

Note that the third parameter is the value type of the corresponding attribute. In this example I assumed that the attributes you used were local_clock and current_thread_id.

Now you can use these keywords to extract the value from log records.

stream << record[a_timestamp] << " "
       << record[a_thread_id]
       << " [" << severity << "] "
       << record[logging::expressions::smessage]
       << "\e[0m";
Andrey Semashev
  • 10,046
  • 1
  • 17
  • 27
  • How could you apply `format_date_time` on that timestamp attribute? – Patrizio Bertoni Dec 04 '19 at 08:16
  • 1
    Given that `format_date_time` is a formatter expression node, you'd have to construct a function object like `expressions::stream << format_date_time<...>(...)` (saving it in an `auto` variable or in a `basic_formatter` wrapper) and then invoke it with `record` and `stream` arguments. But that would be rather inefficient, you're better off with `strftime` or `snprintf`. – Andrey Semashev Dec 04 '19 at 11:53
  • Spasiba Andrey, could you provide some examples on that? How may I record a custom timestamp? I tried with `boost::log::formatting_ostream os; const boost::log::formatter TSF(boost::log::expressions::stream << boost::log::expressions::format_date_time("TimeStamp","%H:%M:%S.%f")); os << TSF;` but it fails compiling – Patrizio Bertoni Apr 20 '21 at 11:51
  • 1
    @PatrizioBertoni See [here](https://stackoverflow.com/questions/24287547/how-to-use-boostlogexpressionsformat-date-time-in-a-custom-formatting-func). – Andrey Semashev Apr 20 '21 at 14:41