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