Commit 47ad79fd authored by Yixing Lao's avatar Yixing Lao Committed by Robert Kimball

Customizable handler for logger function (#1177)

* add lambda handler support for logger
* reuse logger function
parent ae45c984
......@@ -17,6 +17,7 @@
#include <chrono>
#include <condition_variable>
#include <ctime>
#include <functional>
#include <iomanip>
#include <iostream>
#include <mutex>
......@@ -25,107 +26,117 @@
#include "ngraph/log.hpp"
using namespace std;
using namespace ngraph;
namespace ngraph
{
class thread_starter;
class ThreadStarter;
}
string ngraph::logger::log_path;
deque<string> ngraph::logger::queue;
string Logger::m_log_path;
deque<string> Logger::m_queue;
static mutex queue_mutex;
static condition_variable queue_condition;
static unique_ptr<thread> queue_thread;
static bool active = false;
std::ostream& ngraph::get_nil_stream()
{
static std::stringstream nil;
return nil;
}
class ngraph::thread_starter
class ngraph::ThreadStarter
{
public:
thread_starter() { ngraph::logger::start(); }
virtual ~thread_starter() { ngraph::logger::stop(); }
ThreadStarter() { Logger::start(); }
virtual ~ThreadStarter() { Logger::stop(); }
};
static ngraph::thread_starter _starter;
static ThreadStarter s_starter;
void ngraph::logger::set_log_path(const string& path)
ostream& ngraph::get_nil_stream()
{
log_path = path;
static stringstream nil;
return nil;
}
void ngraph::logger::start()
void Logger::set_log_path(const string& path)
{
m_log_path = path;
}
void Logger::start()
{
active = true;
queue_thread = unique_ptr<thread>(new thread(&thread_entry, nullptr));
}
void ngraph::logger::stop()
void Logger::stop()
{
{
unique_lock<std::mutex> lk(queue_mutex);
unique_lock<mutex> lk(queue_mutex);
active = false;
queue_condition.notify_one();
}
queue_thread->join();
}
void ngraph::logger::process_event(const string& s)
void Logger::process_event(const string& s)
{
cout << s << "\n";
}
void ngraph::logger::thread_entry(void* param)
void Logger::thread_entry(void* param)
{
unique_lock<std::mutex> lk(queue_mutex);
unique_lock<mutex> lk(queue_mutex);
while (active)
{
queue_condition.wait(lk);
while (!queue.empty())
while (!m_queue.empty())
{
process_event(queue.front());
queue.pop_front();
process_event(m_queue.front());
m_queue.pop_front();
}
}
}
void ngraph::logger::log_item(const string& s)
void Logger::log_item(const string& s)
{
unique_lock<std::mutex> lk(queue_mutex);
queue.push_back(s);
unique_lock<mutex> lk(queue_mutex);
m_queue.push_back(s);
queue_condition.notify_one();
}
ngraph::log_helper::log_helper(LOG_TYPE type, const char* file, int line, const char* func)
void ngraph::default_logger_handler_func(const string& s)
{
cout << s << endl;
}
LogHelper::LogHelper(LOG_TYPE type,
const char* file,
int line,
function<void(const string&)> handler_func)
: m_handler_func(handler_func)
{
switch (type)
{
case LOG_TYPE::_LOG_TYPE_ERROR: _stream << "[ERR ] "; break;
case LOG_TYPE::_LOG_TYPE_WARNING: _stream << "[WARN] "; break;
case LOG_TYPE::_LOG_TYPE_INFO: _stream << "[INFO] "; break;
case LOG_TYPE::_LOG_TYPE_DEBUG: _stream << "[DEBUG] "; break;
case LOG_TYPE::_LOG_TYPE_ERROR: m_stream << "[ERR] "; break;
case LOG_TYPE::_LOG_TYPE_WARNING: m_stream << "[WARN] "; break;
case LOG_TYPE::_LOG_TYPE_INFO: m_stream << "[INFO] "; break;
case LOG_TYPE::_LOG_TYPE_DEBUG: m_stream << "[DEBUG] "; break;
}
std::time_t tt = chrono::system_clock::to_time_t(chrono::system_clock::now());
auto tm = std::gmtime(&tt);
time_t tt = chrono::system_clock::to_time_t(chrono::system_clock::now());
auto tm = gmtime(&tt);
char buffer[256];
// strftime(buffer,sizeof(buffer), "%d/%b/%Y:%H:%M:%S %z", tm);
// strftime(buffer,sizeof(buffer), "%Y-%m-%d %H:%M:%S UTC", tm);
strftime(buffer, sizeof(buffer), "%Y-%m-%dT%H:%M:%Sz", tm);
_stream << buffer << " ";
m_stream << buffer << " ";
_stream << file;
_stream << " " << line;
// _stream << " " << func;
_stream << "\t";
m_stream << file;
m_stream << " " << line;
m_stream << "\t";
}
ngraph::log_helper::~log_helper()
LogHelper::~LogHelper()
{
cout << _stream.str() << endl;
// logger::log_item(_stream.str());
if (m_handler_func)
{
m_handler_func(m_stream.str());
}
// Logger::log_item(m_stream.str());
}
......@@ -17,43 +17,45 @@
#pragma once
#include <deque>
#include <functional>
#include <sstream>
#include <stdexcept>
namespace ngraph
{
class conststring
class ConstString
{
public:
template <size_t SIZE>
constexpr conststring(const char (&p)[SIZE])
: _string(p)
, _size(SIZE)
constexpr ConstString(const char (&p)[SIZE])
: m_string(p)
, m_size(SIZE)
{
}
constexpr char operator[](size_t i) const
{
return i < _size ? _string[i] : throw std::out_of_range("");
return i < m_size ? m_string[i] : throw std::out_of_range("");
}
constexpr const char* get_ptr(size_t offset) const { return &_string[offset]; }
constexpr size_t size() const { return _size; }
constexpr const char* get_ptr(size_t offset) const { return &m_string[offset]; }
constexpr size_t size() const { return m_size; }
private:
const char* _string;
size_t _size;
const char* m_string;
size_t m_size;
};
constexpr const char* find_last(conststring s, size_t offset, char ch)
constexpr const char* find_last(ConstString s, size_t offset, char ch)
{
return offset == 0 ? s.get_ptr(0) : (s[offset] == ch ? s.get_ptr(offset + 1)
: find_last(s, offset - 1, ch));
}
constexpr const char* find_last(conststring s, char ch)
constexpr const char* find_last(ConstString s, char ch)
{
return find_last(s, s.size() - 1, ch);
}
constexpr const char* get_file_name(conststring s) { return find_last(s, '/'); }
constexpr const char* get_file_name(ConstString s) { return find_last(s, '/'); }
enum class LOG_TYPE
{
_LOG_TYPE_ERROR,
......@@ -62,20 +64,24 @@ namespace ngraph
_LOG_TYPE_DEBUG,
};
class log_helper
class LogHelper
{
public:
log_helper(LOG_TYPE, const char* file, int line, const char* func);
~log_helper();
LogHelper(LOG_TYPE,
const char* file,
int line,
std::function<void(const std::string&)> m_handler_func);
~LogHelper();
std::ostream& stream() { return _stream; }
std::ostream& stream() { return m_stream; }
private:
std::stringstream _stream;
std::function<void(const std::string&)> m_handler_func;
std::stringstream m_stream;
};
class logger
class Logger
{
friend class log_helper;
friend class LogHelper;
public:
static void set_log_path(const std::string& path);
......@@ -86,37 +92,41 @@ namespace ngraph
static void log_item(const std::string& s);
static void process_event(const std::string& s);
static void thread_entry(void* param);
static std::string log_path;
static std::deque<std::string> queue;
static std::string m_log_path;
static std::deque<std::string> m_queue;
};
extern std::ostream& get_nil_stream();
void default_logger_handler_func(const std::string& s);
#define NGRAPH_ERR \
ngraph::log_helper(ngraph::LOG_TYPE::_LOG_TYPE_ERROR, \
ngraph::get_file_name(__FILE__), \
__LINE__, \
__PRETTY_FUNCTION__) \
ngraph::LogHelper(ngraph::LOG_TYPE::_LOG_TYPE_ERROR, \
ngraph::get_file_name(__FILE__), \
__LINE__, \
default_logger_handler_func) \
.stream()
#define NGRAPH_WARN \
ngraph::log_helper(ngraph::LOG_TYPE::_LOG_TYPE_WARNING, \
ngraph::get_file_name(__FILE__), \
__LINE__, \
__PRETTY_FUNCTION__) \
ngraph::LogHelper(ngraph::LOG_TYPE::_LOG_TYPE_WARNING, \
ngraph::get_file_name(__FILE__), \
__LINE__, \
default_logger_handler_func) \
.stream()
#define NGRAPH_INFO \
ngraph::log_helper(ngraph::LOG_TYPE::_LOG_TYPE_INFO, \
ngraph::get_file_name(__FILE__), \
__LINE__, \
__PRETTY_FUNCTION__) \
ngraph::LogHelper(ngraph::LOG_TYPE::_LOG_TYPE_INFO, \
ngraph::get_file_name(__FILE__), \
__LINE__, \
default_logger_handler_func) \
.stream()
#ifdef NGRAPH_DEBUG_ENABLE
#define NGRAPH_DEBUG \
ngraph::log_helper(ngraph::LOG_TYPE::_LOG_TYPE_DEBUG, \
ngraph::get_file_name(__FILE__), \
__LINE__, \
__PRETTY_FUNCTION__) \
ngraph::LogHelper(ngraph::LOG_TYPE::_LOG_TYPE_DEBUG, \
ngraph::get_file_name(__FILE__), \
__LINE__, \
default_logger_handler_func) \
.stream()
#else
#define NGRAPH_DEBUG ngraph::get_nil_stream()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment