Hi all,
 
I am still having the issue with the missing severity level string in the logs and have decided to give you my latest code.
Here is my current code:
 
#include <iostream>
#include <iomanip>
#include <cstdlib>
#include <fstream>
#include <boost/log/core.hpp>
#include <boost/log/sources/global_logger_storage.hpp>
#include <boost/log/sources/severity_logger.hpp>
#include <boost/log/sources/record_ostream.hpp>
#include <boost/log/attributes/clock.hpp>
#include <boost/log/attributes/current_process_name.hpp>
#include <boost/log/attributes/current_process_id.hpp>
#include <boost/log/attributes/current_thread_id.hpp>
#include <boost/log/utility/setup/file.hpp>
#include <boost/log/utility/setup/from_stream.hpp>
#include <boost/log/utility/manipulators/to_log.hpp>
#include <boost/log/utility/formatting_ostream.hpp>
 
using namespace std;
 
namespace logging = boost::log;
namespace keywords = boost::log::keywords;
namespace expr = boost::log::expressions;
namespace attr = boost::log::attributes;
namespace src = boost::log::sources;
 
#define LFC1_LOG_TRACE(logger) BOOST_LOG_SEV(logger, trace) << "(" << __FILE__ << ", " << __LINE__ << ") "
#define LFC1_LOG_DEBUG(logger) BOOST_LOG_SEV(logger, debug) << "(" << __FILE__ << ", " << __LINE__ << ") "
#define LFC1_LOG_INFO(logger) BOOST_LOG_SEV(logger, info) << "(" << __FILE__ << ", " << __LINE__ << ") "
#define LFC1_LOG_WARNING(logger) BOOST_LOG_SEV(logger, warning) << "(" << __FILE__ << ", " << __LINE__ << ") "
#define LFC1_LOG_ERROR(logger) BOOST_LOG_SEV(logger, error) << "(" << __FILE__ << ", " << __LINE__ << ") "
 
static const auto RET_SUCCESS = 0;
static const auto RET_FAIL = 1;
static const auto LOGGING_ENVIRONMENT_NAME = "LOGGING_CONFIG_FILE_NAME";
static const auto DEFAULT_LOGGING_CONFIG_FILE_NAME = "config/LogSettings.txt";
 
enum ESeverityLevel
{
trace,
debug,
info,
warning,
error
};
 
BOOST_LOG_ATTRIBUTE_KEYWORD(severity, "Severity", ESeverityLevel)
 
ostream& operator<<(ostream& arStream, ESeverityLevel avLevel)
{
static const char* pStrings[] =
{
  "trace",
  "debug",
  "info",
  "warning",
  "error"
};
 
if (static_cast<size_t>(avLevel) < sizeof(pStrings) / sizeof(*pStrings))
{
  arStream << pStrings[avLevel];
}
else
{
  arStream << static_cast<int>(avLevel);
}
 
return arStream;
}
 
logging::formatting_ostream& operator<<
(
logging::formatting_ostream& arStream,
logging::to_log_manip<ESeverityLevel, tag::severity> const& arManip
)
{
static const char* pStrings[] =
{
  "TRACE",
  "DEBUG",
  "INFO",
  "WARNING",
  "ERROR"
};
 
ESeverityLevel vLevel = arManip.get();
if (static_cast<size_t>(vLevel) < sizeof(pStrings) / sizeof(*pStrings))
{
  arStream << pStrings[vLevel];
}
else
{
  arStream << static_cast<int>(vLevel);
}
 
return arStream;
}
 
BOOST_LOG_INLINE_GLOBAL_LOGGER_DEFAULT(SLogger, src::severity_logger<ESeverityLevel>)
 
static void gvLoggingInit(const char* apConfigFileName = nullptr)
{
// Obtain the name of the logging configuration file.
if (apConfigFileName == nullptr || apConfigFileName[0] == 0)
{
  if ((apConfigFileName = getenv(LOGGING_ENVIRONMENT_NAME)) == 0 || apConfigFileName[0] == 0)
  {
   apConfigFileName = DEFAULT_LOGGING_CONFIG_FILE_NAME;
  }
}
 
// Open the logging configuration file.
ifstream vConfigFile(apConfigFileName);
if (!vConfigFile.is_open())
{
  // TODO: throw an exception
}
 
// Read the contents of the logging configuration file.
logging::init_from_stream(vConfigFile);
 
// Add the logging attributes that we require.
auto pCore = logging::core::get();
pCore->add_global_attribute("TimeStamp", attr::local_clock());
pCore->add_global_attribute("Process", attr::current_process_name());
pCore->add_global_attribute("ProcessID", attr::current_process_id());
pCore->add_global_attribute("ThreadID", attr::current_thread_id());
pCore->set_filter(severity >= info);
}
 
int main()
{
auto vRetVal = RET_SUCCESS;
 
try
{
  gvLoggingInit();
 
  auto& vLogger = SLogger::get();
 
     LFC1_LOG_TRACE(vLogger) << "A trace severity message";
     LFC1_LOG_DEBUG(vLogger) << "A debug severity message";
     LFC1_LOG_INFO(vLogger) << "An informational severity message";
     LFC1_LOG_WARNING(vLogger) << "A warning severity message";
     LFC1_LOG_ERROR(vLogger) << "An error severity message";
}
catch (exception& crException)
{
  cerr << crException.what() << endl;
  vRetVal = RET_FAIL;
}
catch (...)
{
  cerr << "Unknown exception" << endl;
  vRetVal = RET_FAIL;
}
 
return vRetVal;
}
 
Here is what’s in the settings file:
 
[Core]
Filter="%Severity% >= 2"
DisableLogging=false
 
[Sinks.File]
Destination=TextFile
FileName=log/test_logging_%N.log
RotationSize=1048576
Target=logs
MaxSize=10485760
ScanForFiles=All
Format="%TimeStamp% [%Severity%] %Process%:%ProcessID%:%ThreadID% %Message%"
As mentioned in a previous post, the issue I’m having is this is how the resulting log records look like:
 
2013-Jul-16 11:24:59.758177 [] test_logging:000000x9f3:0x403cc6c0 (src/test_logging.cpp, 240) An informational severity message
2013-Jul-16 11:24:59.758812 [] test_logging:000000x9f3:0x403cc6c0 (src/test_logging.cpp, 241) A warning severity message
2013-Jul-16 11:24:59.758851 [] test_logging:000000x9f3:0x403cc6c0 (src/test_logging.cpp, 242) An error severity message
Note that the severity string is missing from the above log records.
 
Does anyone know I can fix the code to make the severity string show up in the log records?
 
Another question I have is how do I change the format of the date in the timestamp from YYY-MMM-DD to YYYY-MM-DD.

I am sticking to using logging settings from a file because I want an application user to be able to control where log records go.
However, I am open to the idea of setting the format within the code but at the moment there is no option of setting the format when a settings file is used.
It would be nice to have a function within the logging core which allows us to obtain a pointer/reference to the existing sinks.
 
Kind regards,
Leo