0

Here is how I set up my loggers:

namespace logger = boost::log;
namespace src = boost::log::sources;
namespace sinks = boost::log::sinks;
namespace expr = boost::log::expressions;
using LEVEL = boost::log::trivial::severity_level;


static void log_Severity(LEVEL level, sender_t sender, std::string message);
static void throw_Severity(LEVEL level, sender_t sender, std::string message);
static std::string getUnescaped(std::string input);
static std::string format(sender_t sender, std::string message);;
static std::string HRESULTSTRING(HRESULT result);

typedef sinks::synchronous_sink< sinks::text_ostream_backend > text_sink;

static std::string CreateFormat()
{
    logger::add_common_attributes();
    logger::register_simple_formatter_factory< LEVEL, char >("Severity");
    return "[%TimeStamp%] [%ThreadID%] [%Severity%]: %Message%";
}

static void AddTerminalLogger(std::string format)
{
    auto sink = boost::make_shared<text_sink>();
    sink->locked_backend()->add_stream(boost::shared_ptr<std::ostream>(&std::cout, boost::null_deleter()));
    sink->locked_backend()->auto_flush(true);
    //sink->set_formatter( format );
    logger::core::get()->add_sink(sink);
}

static void AddFileLogger(std::string path, std::string format)
{
    logger::add_file_log
        (
        logger::keywords::file_name = path + "ManualTest_%Y-%m-%d_%H-%M-%S.%N.log",
        logger::keywords::rotation_size = 10 * 1024 * 1024,
        logger::keywords::time_based_rotation = sinks::file::rotation_at_time_point(0, 0, 0),
        logger::keywords::format = format
        );
}

static void SetLogLevel(LEVEL level)
{
    logger::core::get()->set_filter(logger::trivial::severity >= level);
}

void LogHelper::SetupLoggers(std::string path)
{
    std::string format = CreateFormat();
    AddFileLogger(path, format);
    AddTerminalLogger(format);
    SetLogLevel(LEVEL::trace);
}

I want to use my existing format string to set up my console logging as well. How can I reuse "[%TimeStamp%] [%ThreadID%] [%Severity%]: %Message%" so I do not repeat myself when I create my format expression?

Edit: To clarify: This is not valid as far as I know: sink->set_formatter(expr::format("[%TimeStamp%] [%ThreadID%] [%Severity%]: %Message%")); If I wanted to use set_formatter I would have to write an expression that does the same thing as this logger::keywords::format = "[%TimeStamp%] [%ThreadID%] [%Severity%]: %Message%". If I do so I would use one approach per logger (Terminal, File) to hopefully get the same formatting in both. Both loggers are a sink that is added to the core. So i assume the method logger::add_file_log uses something like set_formatter under the hood. I would like to use the capabilities that are built in somewhere that would allow me to apply the string "[%TimeStamp%] [%ThreadID%] [%Severity%]: %Message%" to a sink. I can not find the documentation though. When I look this topic up I do find how to use set_formatter but it always ends up in developing something different that gets the same result. I feel this introduces error potential since I would just repeat myself in the sense that I would rewrite the formatting I want in my logging just with slight variations.

Edit: Changed the source code to better reflect the question.

2
  • Make it a global constant or a #define? Or am I missing something? Commented Jan 21, 2016 at 17:36
  • Ah, i should refine my question, this is not about how to pass things as parameters. This is about how an expression is way more complicated than the logger keyword. I would like to use one way of doing this rather than maintaining two ways of doing the same thing. Commented Jan 21, 2016 at 21:50

1 Answer 1

1

First, you can use add_console_log function similarly to how you use add_file_log in your code.

Second, both these functions use the formatter parser (the parse_formatter function) to convert the format string to the actual formatter you can supply to set_formatter. You can use this function directly to avoid parsing the string multiple times.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.