-2

I need a global logger that I can use across multiple classes in my project. I want to have logger settings in an ini file.

I start following example here and combined it with some suggestions at my earlier question here.

My Logger.h is as follows.

#pragma once

#include <boost/log/common.hpp>
#include <boost/log/attributes.hpp>
#include <boost/log/utility/setup/from_stream.hpp>
#include <boost/regex.hpp>

#include <boost/log/expressions.hpp>
#include <boost/log/sources/global_logger_storage.hpp>
#include <boost/log/support/date_time.hpp>
#include <boost/log/trivial.hpp>
#include <boost/log/utility/setup.hpp>


#define INFO  BOOST_LOG_SEV(my_logger::get(), boost::log::trivial::info)
#define WARN  BOOST_LOG_SEV(my_logger::get(), boost::log::trivial::warning)
#define ERROR BOOST_LOG_SEV(my_logger::get(), boost::log::trivial::error)

//Narrow-char thread-safe logger.
typedef boost::log::sources::severity_logger_mt<boost::log::trivial::severity_level> logger_t;

//declares a global logger with a custom initialization
BOOST_LOG_GLOBAL_LOGGER(my_logger, logger_t)
BOOST_LOG_INLINE_GLOBAL_LOGGER_DEFAULT(test_lg, boost::log::sources::severity_logger< >)

The Logger.cpp is as follows.

#include "stdafx.h"
#include "Logger.h"
#include <fstream>

namespace attrs = boost::log::attributes;
namespace expr = boost::log::expressions;
namespace logging = boost::log;

//Defines a global logger initialization routine
BOOST_LOG_GLOBAL_LOGGER_INIT(my_logger, logger_t)
{
    logger_t lg;

    logging::add_common_attributes();

    std::ifstream settings("settings.ini");
    if (!settings.is_open())
    {
        std::cout << "Could not open settings.txt file" << std::endl;
        //return 1;
    }

    // Read the settings and initialize logging library
    logging::init_from_stream(settings);

    // Add some attributes
    logging::core::get()->add_global_attribute("TimeStamp", attrs::local_clock());
    logging::register_simple_filter_factory<logging::trivial::severity_level>("Severity");

    return lg;
}

The settings.ini looks like below

#
#          Copyright Andrey Semashev 2007 - 2014.
# Distributed under the Boost Software License, Version 1.0.
#    (See accompanying file LICENSE_1_0.txt or copy at
#          http://www.boost.org/LICENSE_1_0.txt)
#

[Core]
Filter="%Severity% >= debug"

[Sinks.1]
Destination=TextFile
FileName=test.log
AutoFlush=true
Format="[%TimeStamp%] <%Severity%> (%Channel%): %Message%"

Finally I am trying to use logger as below.

#include "Logger.h"
int wmain(int argc, wchar_t* argv[])
{
    INFO << "Program started";
}

However, no log file is getting created. What am I doing wrong now?

whoami
  • 1,689
  • 3
  • 22
  • 45
  • 2
    I recommend improving the title. It contains very little information, making it harder to use for future programmers with the same or a similar problem. That said, Visual Studio has an amazing debugger. Have you used it to help narrow down the source of your problem? – user4581301 Sep 04 '18 at 19:00
  • I don't know what "again" means in the question title. Did you get your logging to work? And you then made certain changes which broke it **again**? – Drew Dormann Sep 04 '18 at 19:09
  • Is `INFO` level greater than debug?? Although I have not used this logger I think this is the correct behavior based on other similar logging classes. Try `WARN << "Program started";` and see if you get anything. – drescherjm Sep 04 '18 at 19:23
  • @user4581301 I updated the title. I try to debug with Visual Studio but it just goes in a deep level of templates that I don't pretend to understand.. There is no exception getting thrown or anything like that – whoami Sep 04 '18 at 19:27
  • Thank you. And fair enough on how crazy code can get. I'm not familiar with `boost::log`, but boost in general requires understanding that approaches grok. – user4581301 Sep 04 '18 at 19:40
  • @drescherjm I tried with WARN too and still same results. No file getting generated – whoami Sep 04 '18 at 20:18
  • @DrewDormann Sorry about the confusing title. In my question, I have link to another question that I posted. For that scenario, logging was working. However when I try to convert it as a global logger that can be used across multiple classes, I am not able to get it to work. Hopefully this gives you some context, sorry about the confusing title again – whoami Sep 04 '18 at 20:30
  • 1
    I can't test right now, but at the very least it seems the "// add some attributes" lines need to be before "init_from_stream" – sehe Sep 06 '18 at 12:55
  • @sehe you are the man my friend. Can you add this as answer so I can mark it so. – whoami Sep 06 '18 at 17:40

1 Answers1

1

The filter factory needs to be registered before parsing the settings ini.

// Add some attributes
logging::core::get()->add_global_attribute("TimeStamp", attrs::local_clock());
logging::register_simple_filter_factory<logging::trivial::severity_level>("Severity");

Needs to be in front of the call

// Read the settings and initialize logging library
logging::init_from_stream(settings);

Without the factory, the filter is not interpreted and ends up filtering everything.

sehe
  • 374,641
  • 47
  • 450
  • 633