diff --git a/pEpLog.cc b/pEpLog.cc new file mode 100644 index 0000000..ec6f80d --- /dev/null +++ b/pEpLog.cc @@ -0,0 +1,86 @@ +#include "pEpLog.hh" +#include // cout and cerr +#include // for stringstream +#include // for log_event() +#include "Adapter.hh" // for session() + +namespace pEp { +namespace Adapter { +namespace pEpLog { + +std::mutex mtx; + +std::atomic_bool is_initialized{false}; +std::atomic_bool is_enabled{true}; +std::atomic_bool is_enabled_backend_pEpEngine{true}; +std::atomic_bool is_enabled_backend_cout{false}; +std::atomic_bool is_enabled_backend_cerr{false}; + + +void set_enabled(bool enabled) { + is_enabled.store(enabled); +} + +bool get_enabled() { + return is_enabled.load(); +} + +void set_enabled_cout(bool enabled){ + is_enabled_backend_cout.store(enabled); +} + +bool get_enabled_cout(){ + return is_enabled_backend_cout.load(); +} + +void set_enabled_cerr(bool enabled){ + is_enabled_backend_cerr.store(enabled); +} + +bool get_enabled_cerr(){ + return is_enabled_backend_cerr.load(); +} + +void set_enabled_pEpEngine(bool enabled){ + is_enabled_backend_pEpEngine.store(enabled); +} + +bool get_enabled_pEpEngine(){ + return is_enabled_backend_pEpEngine.load(); +} + +void log_pEpEngine(std::string &msg) { + if (!is_initialized.load()) { + ::config_service_log(pEp::Adapter::session(), true); + ::log_service(pEp::Adapter::session(), "pEpLog init", nullptr, nullptr, nullptr); + is_initialized.store(true); + } + ::log_service(pEp::Adapter::session(), msg.c_str(), nullptr, nullptr, nullptr); +} + +void log_cout(std::string &msg) { + std::cout << msg << std::endl; //std::endl also flushes +} + +void log_cerr(std::string &msg) { + std::cerr << msg << std::endl; //std::endl also flushes +} + +void log(std::string msg) { + std::lock_guard l(mtx); + if (is_enabled.load()) { + if (is_enabled_backend_cout.load()) { + log_cout(msg); + } + if (is_enabled_backend_cerr.load()) { + log_cerr(msg); + } + if (is_enabled_backend_pEpEngine.load()) { + log_pEpEngine(msg); + } + } +} + +} // pEpLog +} // Adapter +} // pEp diff --git a/pEpLog.hh b/pEpLog.hh index 12937e1..e515db7 100644 --- a/pEpLog.hh +++ b/pEpLog.hh @@ -1,7 +1,71 @@ -// TODO: put into not yet existing libpEpAdapter_utils.h, to be across whole libpEpAdapter +#ifndef LIBPEPADAPTER_PEPLOG_HH +#define LIBPEPADAPTER_PEPLOG_HH + +#include +#include + +// pEpLog +// ====== +// a "to be kept small and simple" logging unit. +// featuring: +// * pEpLog macro that will be eliminated in release-builds (-DNDEBUG=1) +// * all functions thread safe (no interleave when logging from diff threads) +// * logging backend: pEpEngine logging API (providing platform abstractions and portability) +// * logging backend: cout +// * logging backend: cerr +// * runtime enabled/disabled switch (global) +// * runtime enabled/disabled switch per backend +// +// You might want more and more features, but the feature-policy is very restrictive, and there is a +// primary design goal to keep it simple, maintainable and portable. +// +// How to use: +// include +// use the macro pEpLog(msg) to do logging +// use NDEBUG=1 to turn logging on/off at compile-time +// use set_enabled(bool) to turn logging on/off at runtime +// use set_enabled_(bool) to turn logging on/off per backend +// All these functions are thread-safe +// +// Thats all there is to it. + #ifdef NDEBUG #define pEpLog(msg) do{}while(0) #else - #include - #define pEpLog(msg) do{std::cerr << __FILE__ << "::" << __FUNCTION__ << " - " << msg << '\n';} while(0) -#endif \ No newline at end of file + #define pEpLog(msg) \ + do { \ + std::stringstream msg_ss; \ + msg_ss << std::this_thread::get_id() << " - " << __FILE__ << "::" << __FUNCTION__ << " - " << msg; \ + pEp::Adapter::pEpLog::log(msg_ss.str()); \ + } while(0) +#endif // NDEBUG + +namespace pEp { +namespace Adapter { +namespace pEpLog { + +void log(std::string msg); + +void set_enabled(bool is_enabled); + +bool get_enabled(); + +void set_enabled_cout(bool is_enabled); + +bool get_enabled_cout(); + +void set_enabled_cerr(bool is_enabled); + +bool get_enabled_cerr(); + +void set_enabled_pEpEngine(bool is_enabled); + +bool get_enabled_pEpEngine(); + +} // pEpLog +} // Adapter +} // pEp + + +#endif // LIBPEPADAPTER_PEPLOG_HH +