Polished Logger template, semi working
This commit is contained in:
parent
847bf3a078
commit
f8a8813b3e
@ -30,99 +30,119 @@ struct LogEvent{
|
|||||||
typedef std::string (*LogProcessFunction)(const LoggerTimePoint&, const std::string&);
|
typedef std::string (*LogProcessFunction)(const LoggerTimePoint&, const std::string&);
|
||||||
typedef std::unordered_map<uint8_t, LogProcessFunction> LogProcessFunctionMap;
|
typedef std::unordered_map<uint8_t, LogProcessFunction> LogProcessFunctionMap;
|
||||||
|
|
||||||
template<typename StreamType>
|
template<typename LoggerName>
|
||||||
class Logger {
|
class Logger {
|
||||||
public:
|
public:
|
||||||
Logger(StreamType& stream) : _ostream(&stream) {}
|
using Type = LoggerName;
|
||||||
|
|
||||||
bool isRunning() const;
|
Logger(std::ostream& stream) : _ostream(&stream) {}
|
||||||
unsigned int count() const;
|
|
||||||
|
bool isRunning() const {
|
||||||
|
return _running && bool(_runningThread);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int count() const {
|
||||||
|
return _queue.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool run() {
|
||||||
|
auto this_type = static_cast<Type*>(this);
|
||||||
|
if (!isRunning()) {
|
||||||
|
_runningThread = std::make_shared<std::thread>([&]{
|
||||||
|
while(this_type->isRunning()) {
|
||||||
|
this_type->flush();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return isRunning();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool stop() {
|
||||||
|
if (isRunning()) {
|
||||||
|
_running = false;
|
||||||
|
_runningThread->join();
|
||||||
|
_runningThread = nullptr;
|
||||||
|
flush();
|
||||||
|
}
|
||||||
|
return isRunning();
|
||||||
|
}
|
||||||
|
|
||||||
|
LogEvent pop() {
|
||||||
|
std::shared_ptr<LogEvent> event;
|
||||||
|
_queue.pop(event);
|
||||||
|
static_cast<Type*>(this)->process(*event);
|
||||||
|
return *event;
|
||||||
|
}
|
||||||
|
|
||||||
bool run();
|
|
||||||
bool stop();
|
|
||||||
LogEvent pop();
|
|
||||||
void flush() {
|
void flush() {
|
||||||
while(_queue.size()) {
|
while(_queue.size()) {
|
||||||
pop();
|
pop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void deleteAll() {
|
void deleteAll() {
|
||||||
_queue.empty();
|
_queue.empty();
|
||||||
}
|
}
|
||||||
void msg(const std::string& _msg, uint8_t lvl=0) {
|
|
||||||
|
template <typename T>
|
||||||
|
void log(const T&, const uint8_t);
|
||||||
|
|
||||||
|
void log(const std::string& msg, const uint8_t& lvl) {
|
||||||
_queue.push(LogEvent{
|
_queue.push(LogEvent{
|
||||||
std::chrono::system_clock::now(),
|
std::chrono::system_clock::now(),
|
||||||
lvl,
|
lvl,
|
||||||
_msg,
|
msg,
|
||||||
std::this_thread::get_id(),
|
std::this_thread::get_id(),
|
||||||
get_pid()
|
get_pid(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
void warn(const std::string& _msg, uint8_t lvl=1) {
|
|
||||||
msg(_msg, lvl);
|
void log(const std::exception& err, const uint8_t& lvl) {
|
||||||
|
_queue.push(LogEvent{
|
||||||
|
std::chrono::system_clock::now(),
|
||||||
|
lvl,
|
||||||
|
err.what(),
|
||||||
|
std::this_thread::get_id(),
|
||||||
|
get_pid(),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
void warn(const std::exception& _err, uint8_t lvl=1) {
|
|
||||||
msg(_err.what(), lvl);
|
void msg(const std::string& msg, const uint8_t& lvl=0x00) {
|
||||||
|
static_cast<Type>(this)->log(msg, lvl);
|
||||||
}
|
}
|
||||||
void error(const std::string& _msg, uint8_t lvl=0xFF) {
|
|
||||||
msg(_msg, lvl);
|
void warn(const std::string& msg, const uint8_t& lvl=0x01) {
|
||||||
|
static_cast<Type>(this)->log(msg, lvl);
|
||||||
}
|
}
|
||||||
void error(const std::exception& _err, uint8_t lvl=0xFF) {
|
void warn(const std::exception& err, const uint8_t lvl=0x01) {
|
||||||
msg(_err.what(), lvl);
|
static_cast<Type>(this)->log(err, lvl);
|
||||||
|
}
|
||||||
|
|
||||||
|
void error(const std::string& msg, const uint8_t lvl=0xFF) {
|
||||||
|
static_cast<Type>(this)->log(msg, lvl);
|
||||||
|
}
|
||||||
|
void error(const std::exception& err, const uint8_t lvl=0xFF) {
|
||||||
|
static_cast<Type*>(this)->log(err, lvl);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void process(const LogEvent& event) {
|
void process(const LogEvent&);
|
||||||
uint8_t lvl = event.lvl;
|
|
||||||
*_ostream << "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
ThreadsafeQueue<LogEvent> _queue;
|
ThreadsafeQueue<LogEvent> _queue;
|
||||||
StreamType* const _ostream;
|
std::ostream* const _ostream;
|
||||||
std::atomic<bool> _running;
|
std::atomic<bool> _running;
|
||||||
std::shared_ptr<std::thread> _runningThread = nullptr;
|
std::shared_ptr<std::thread> _runningThread = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename ST>
|
class BasicLogger : public Logger<BasicLogger> {
|
||||||
bool Logger<ST>::isRunning() const {
|
public:
|
||||||
return _running && bool(_runningThread);
|
using Base = Logger<BasicLogger>;
|
||||||
}
|
BasicLogger(std::ostream& stream) : Base(stream) {}
|
||||||
|
|
||||||
template <typename ST>
|
virtual void process(const LogEvent& event) {
|
||||||
unsigned int Logger<ST>::count() const {
|
*_ostream << event.msg << "\n";
|
||||||
return _queue.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename ST>
|
|
||||||
bool Logger<ST>::run() {
|
|
||||||
if (!isRunning()) {
|
|
||||||
_runningThread = std::make_shared<std::thread>([&]{
|
|
||||||
while(this->isRunning()) {
|
|
||||||
this->flush();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
return isRunning();
|
};
|
||||||
}
|
|
||||||
|
|
||||||
template <typename ST>
|
|
||||||
bool Logger<ST>::stop() {
|
|
||||||
if (isRunning()) {
|
|
||||||
_running = false;
|
|
||||||
_runningThread->join();
|
|
||||||
_runningThread = nullptr;
|
|
||||||
flush();
|
|
||||||
}
|
|
||||||
return isRunning();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename ST>
|
|
||||||
LogEvent Logger<ST>::pop() {
|
|
||||||
std::shared_ptr<LogEvent> event;
|
|
||||||
_queue.pop(event);
|
|
||||||
process(*event);
|
|
||||||
return *event;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace nb
|
} // namespace nb
|
||||||
#endif // _NB_LOGGER
|
#endif // _NB_LOGGER
|
||||||
@ -42,7 +42,7 @@ int main() {
|
|||||||
}
|
}
|
||||||
} catch(const std::exception& e) {
|
} catch(const std::exception& e) {
|
||||||
// THROW(Error, Error::ErrorCodes::UNDEFINED, e);
|
// THROW(Error, Error::ErrorCodes::UNDEFINED, e);
|
||||||
Logger log(std::cout);
|
BasicLogger log(std::cout);
|
||||||
std::cout << "Logger is starting: " << log.run() << std::endl;
|
std::cout << "Logger is starting: " << log.run() << std::endl;
|
||||||
std::cout << "Logger is running: " << log.isRunning() << std::endl;
|
std::cout << "Logger is running: " << log.isRunning() << std::endl;
|
||||||
log.error(e);
|
log.error(e);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user