Search code examples
c++c++11boostboost-log

Boost.Log: Why it is showing duplicate the message?


I'm learning the Boost.Log library. I want to send messages to a file and std::clog. I have the following class:

class logger
{
    public:
        explicit logger(
            const std::string& tag,
            const std::string& file,
            bool console
        )
        {
            boost::log::register_simple_formatter_factory< boost::log::trivial::severity_level, char >("Severity");

            std::string the_format = "[%TimeStamp%] (%LineID%) [%Severity%]";
            if(!tag.empty()) {
                m_log_.add_attribute(
                    "Tag",
                    boost::log::attributes::constant< std::string >( tag )
                );
                the_format += " [%Tag%]";
            }

            the_format += ": %Message%";

            if(console) {
                boost::log::add_console_log(
                    std::clog,
                    boost::log::keywords::auto_flush = true,
                    boost::log::keywords::format = the_format
                );
            }

            if(!file.empty()) {
                boost::log::add_file_log(
                    boost::log::keywords::file_name = file,
                    boost::log::keywords::auto_flush = true,
                    boost::log::keywords::open_mode = (std::ios::out | std::ios::app),
                    boost::log::keywords::format = the_format
                );
            }

        }

        ~logger(void)
        { }

        void log(
            const std::string& msg
        )
        {
            BOOST_LOG_SEV ( m_log_, boost::log::trivial::info ) << msg;
        }

    private:
        boost::log::sources::severity_logger< boost::log::trivial::severity_level > m_log_;

}; // logger

I have the following main() function:

void x()
{
    logger lg("omega", "", true);
    lg.log( "Goodbye" );
}

int main(int argc, char** argv)
{
    logger lg( "alfa", "", true );
    lg.log( "Hello world!!!");
    x();
    return 0;
}

I do not understand why the duplicate message is displayed: "Hello world!!!":

[2016-Aug-23 17:51:36.852912] (1) [info] [alfa]: Hello world!!!
[2016-Aug-23 17:51:36.853359] (2) [info] [omega]: Goodbye
[2016-Aug-23 17:51:36.853359] (2) [info] [omega]: Goodbye

UPDATE: Sorry, the example was incomplete.


Solution

  • logger's constructor is calling add_console_log() and add_file_log(). If you construct logger twice, these functions will also be called twice. Since they add global sinks, every log entry will be duplicated twice on the console and in your file.

    int main(int argc, char** argv)
    {
        logger lg1("1", "", true);
        logger lg2("2", "", true);
        logger lg3("3", "", true);
        logger lg4("4", "", true);
    
        lg1.log("test");
    }
    

    This will output:

    [2016-Aug-23 13:25:56.468382] (1) [info] [1]: test
    [2016-Aug-23 13:25:56.468382] (1) [info] [1]: test
    [2016-Aug-23 13:25:56.468382] (1) [info] [1]: test
    [2016-Aug-23 13:25:56.468382] (1) [info] [1]: test
    

    You probably want some sort of reference count or flag to only call these functions once.