@ -0,0 +1,86 @@ | |||
#include "pEpLog.hh" | |||
#include <iostream> // cout and cerr | |||
#include <sstream> // for stringstream | |||
#include <pEp/pEpEngine.h> // 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<std::mutex> 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 |
@ -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 <sstream> | |||
#include <thread> | |||
// 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 <pEpLog.hh> | |||
// 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_<backend>(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 <iostream> | |||
#define pEpLog(msg) do{std::cerr << __FILE__ << "::" << __FUNCTION__ << " - " << msg << '\n';} while(0) | |||
#endif | |||
#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 | |||