diff --git a/.gitignore b/.gitignore index d13bb85..13c26a9 100644 --- a/.gitignore +++ b/.gitignore @@ -61,4 +61,4 @@ tests/TestSendRecvPacket tests/TestSendPacket tests/TestsRecvPacket tests/TestsPty2LoRa - +*.log diff --git a/CMakeLists.txt b/CMakeLists.txt index 2b6c25f..a3e31a8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,9 +20,9 @@ set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) add_compile_options(-Wall -Wextra -pedantic -lstdc++) -add_definitions(-DCFG_DEBUG -DCFG_eu868 -DCFG_sx1276_radio -DDEBUG_LMIC -DDEBUG_HAL -DDEBUG_RADIO) +add_definitions(-DCFG_DEBUG -DCFG_eu868 -DCFG_sx1276_radio -DDEBUG_LMIC -DDEBUG_HAL -DDEBUG_RADIO -DBOOST_LOG_DYN_LINK) -add_executable(mqtt2LoRaWAN main.cpp MQTTDataStreamer.cpp POHelperClasses.cpp POCmdlineHelperClasses.cpp POConfigHelperClasses.cpp ./lmic/lmic.c ./lmic/aes.c ./lmic/radio.c ./lmic/oslmic.c ./lora_gps_hat/debug.c ./lora_gps_hat/gpio.c ./lora_gps_hat/hal.c ) +add_executable(mqtt2LoRaWAN main.cpp MQTTDataStreamer.cpp POHelperClasses.cpp POCmdlineHelperClasses.cpp POConfigHelperClasses.cpp customLogger.cpp ./lmic/lmic.c ./lmic/aes.c ./lmic/radio.c ./lmic/oslmic.c ./lora_gps_hat/debug.c ./lora_gps_hat/gpio.c ./lora_gps_hat/hal.c ) target_include_directories (mqtt2LoRaWAN PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}" @@ -33,7 +33,7 @@ target_include_directories (mqtt2LoRaWAN PUBLIC target_link_directories(mqtt2LoRaWAN PUBLIC "/opt/libraries/boost/stage/lib") -target_link_libraries(mqtt2LoRaWAN PUBLIC wiringPi paho-mqttpp3 paho-mqtt3as boost_program_options pthread) +target_link_libraries(mqtt2LoRaWAN PUBLIC wiringPi paho-mqttpp3 paho-mqtt3as boost_program_options boost_log boost_log_setup boost_system boost_thread pthread) diff --git a/customLogger.cpp b/customLogger.cpp new file mode 100644 index 0000000..a9a5c42 --- /dev/null +++ b/customLogger.cpp @@ -0,0 +1,123 @@ + +#include "customLogger.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace logging = boost::log; +namespace src = boost::log::sources; +namespace expr = boost::log::expressions; +namespace sinks = boost::log::sinks; +namespace attrs = boost::log::attributes; +namespace keywords = boost::log::keywords; + +// Declare attribute keywords +BOOST_LOG_ATTRIBUTE_KEYWORD(line_id, "LineID", unsigned int) +BOOST_LOG_ATTRIBUTE_KEYWORD(timestamp, "TimeStamp", boost::posix_time::ptime) +BOOST_LOG_ATTRIBUTE_KEYWORD(severity, "Severity", logging::trivial::severity_level) +BOOST_LOG_ATTRIBUTE_KEYWORD(scope, "Scope", attrs::named_scope::value_type) + +void coloring_formatter(logging::record_view const& rec, logging::formatting_ostream& strm){ + + auto severity = rec[logging::trivial::severity]; + auto date_time_formatter = expr::stream << expr::format_date_time< boost::posix_time::ptime >("TimeStamp", "%Y-%m-%d %H:%M:%S"); + auto scope_formatter = expr::stream << expr::format_named_scope("Scope" , keywords::format = "%n (%F:%l)", keywords::iteration = expr::reverse ); + + + date_time_formatter(rec, strm); + strm << " - "; + + // strm << expr::format_date_time( "TimeStamp", "%Y-%m-%d, %H:%M:%S.%f") << " - "; + + if (severity) + { + // Set the color + switch (severity.get()) + { + case logging::trivial::severity_level::info: + strm << "\033[32m"; + break; + case logging::trivial::severity_level::warning: + strm << "\033[33m"; + break; + case logging::trivial::severity_level::error: + case logging::trivial::severity_level::fatal: + strm << "\033[31m"; + break; + default: + break; + } + } + + // Format the message here... + strm << "[" << severity << "]"; + + if (severity) + { + // Restore the default color + strm << "\033[0m"; + } + + strm << " - "; + scope_formatter(rec, strm); + strm << " "; + strm << rec[expr::smessage]; + + + +} + +BOOST_LOG_GLOBAL_LOGGER_INIT(logger, src::severity_logger_mt) { + src::severity_logger_mt logger; + + // add attributes + logger.add_attribute("LineID", attrs::counter(1)); // lines are sequentially numbered + logger.add_attribute("TimeStamp", attrs::local_clock()); // each log line gets a timestamp + logger.add_attribute("Scope", attrs::named_scope()); + + // add a text sink + typedef sinks::synchronous_sink< sinks::text_ostream_backend > text_sink; + boost::shared_ptr< text_sink > sink = boost::make_shared< text_sink >(); + + // add a logfile stream to our sink + sink->locked_backend()->add_stream( + boost::make_shared< std::ofstream >(LOGFILE)); + + + // add "console" output stream to our sink + sink->locked_backend()->add_stream(boost::shared_ptr< std::ostream>(&std::clog, boost::null_deleter())); + + // specify the format of the log message + /* + logging::formatter formatter = expr::stream + << std::setw(7) << std::setfill('0') << line_id << std::setfill(' ') << " | " + << expr::format_date_time(timestamp, "%Y-%m-%d, %H:%M:%S.%f") << " " + << "[" << logging::trivial::severity << "]" + << " - " << expr::smessage; + */ + sink->set_formatter(&coloring_formatter); + + // just log messages with severity >= SEVERITY_THRESHOLD are written + sink->set_filter(severity >= SEVERITY_THRESHOLD); + + + // "register" our sink + logging::core::get()->add_sink(sink); + + return logger; + +} + diff --git a/customLogger.hpp b/customLogger.hpp new file mode 100644 index 0000000..23193c7 --- /dev/null +++ b/customLogger.hpp @@ -0,0 +1,31 @@ +#ifndef customLogger_HPP__ +#define customLogger_HPP__ + +#define BOOST_LOG_DYN_LINK 1 // necessary when linking the boost_log library dynamically + +#include +#include +#include + +// the logs are also written to LOGFILE +#define LOGFILE "mqtt2LoRaWAN.log" + +// just log messages with severity >= SEVERITY_THRESHOLD are written +#define SEVERITY_THRESHOLD logging::trivial::debug + +// register a global logger +BOOST_LOG_GLOBAL_LOGGER(logger, boost::log::sources::severity_logger_mt) + + +// just a helper macro used by the macros below - don't use it in your code +#define LOG(severity) BOOST_LOG_SEV(logger::get(),boost::log::trivial::severity) + +// ===== log macros ===== +#define LOG_TRACE LOG(trace) +#define LOG_DEBUG LOG(debug) +#define LOG_INFO LOG(info) +#define LOG_WARNING LOG(warning) +#define LOG_ERROR LOG(error) +#define LOG_FATAL LOG(fatal) + +#endif diff --git a/main.cpp b/main.cpp index d42e99d..1316c52 100644 --- a/main.cpp +++ b/main.cpp @@ -7,10 +7,13 @@ #include "POCmdlineHelperClasses.hpp" #include "POConfigHelperClasses.hpp" #include "MQTTDataStreamer.hpp" +#include "customLogger.hpp" + #include #include #include + namespace po = boost::program_options; extern "C" @@ -181,9 +184,20 @@ static void initfunc(osjob_t *j) // init done - onEvent() callback will be invoked... } + // application entry point int main(int argc, char *argv[]) { + + BOOST_LOG_NAMED_SCOPE("named_scope_logging"); + + LOG_TRACE << "this is a trace message"; + LOG_DEBUG << "this is a debug message"; + LOG_WARNING << "this is a warning message"; + LOG_ERROR << "this is an error message"; + LOG_FATAL << "this is a fatal error message"; + + osjob_t initjob; std::string hostname;