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 @@ ...@@ -17,6 +17,7 @@
#include <chrono> #include <chrono>
#include <condition_variable> #include <condition_variable>
#include <ctime> #include <ctime>
#include <functional>
#include <iomanip> #include <iomanip>
#include <iostream> #include <iostream>
#include <mutex> #include <mutex>
...@@ -25,107 +26,117 @@ ...@@ -25,107 +26,117 @@
#include "ngraph/log.hpp" #include "ngraph/log.hpp"
using namespace std; using namespace std;
using namespace ngraph;
namespace ngraph namespace ngraph
{ {
class thread_starter; class ThreadStarter;
} }
string ngraph::logger::log_path; string Logger::m_log_path;
deque<string> ngraph::logger::queue; deque<string> Logger::m_queue;
static mutex queue_mutex; static mutex queue_mutex;
static condition_variable queue_condition; static condition_variable queue_condition;
static unique_ptr<thread> queue_thread; static unique_ptr<thread> queue_thread;
static bool active = false; static bool active = false;
std::ostream& ngraph::get_nil_stream() class ngraph::ThreadStarter
{
static std::stringstream nil;
return nil;
}
class ngraph::thread_starter
{ {
public: public:
thread_starter() { ngraph::logger::start(); } ThreadStarter() { Logger::start(); }
virtual ~thread_starter() { ngraph::logger::stop(); } 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; active = true;
queue_thread = unique_ptr<thread>(new thread(&thread_entry, nullptr)); 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; active = false;
queue_condition.notify_one(); queue_condition.notify_one();
} }
queue_thread->join(); queue_thread->join();
} }
void ngraph::logger::process_event(const string& s) void Logger::process_event(const string& s)
{ {
cout << s << "\n"; 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) while (active)
{ {
queue_condition.wait(lk); queue_condition.wait(lk);
while (!queue.empty()) while (!m_queue.empty())
{ {
process_event(queue.front()); process_event(m_queue.front());
queue.pop_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); unique_lock<mutex> lk(queue_mutex);
queue.push_back(s); m_queue.push_back(s);
queue_condition.notify_one(); 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) switch (type)
{ {
case LOG_TYPE::_LOG_TYPE_ERROR: _stream << "[ERR ] "; break; case LOG_TYPE::_LOG_TYPE_ERROR: m_stream << "[ERR] "; break;
case LOG_TYPE::_LOG_TYPE_WARNING: _stream << "[WARN] "; break; case LOG_TYPE::_LOG_TYPE_WARNING: m_stream << "[WARN] "; break;
case LOG_TYPE::_LOG_TYPE_INFO: _stream << "[INFO] "; break; case LOG_TYPE::_LOG_TYPE_INFO: m_stream << "[INFO] "; break;
case LOG_TYPE::_LOG_TYPE_DEBUG: _stream << "[DEBUG] "; 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()); time_t tt = chrono::system_clock::to_time_t(chrono::system_clock::now());
auto tm = std::gmtime(&tt); auto tm = gmtime(&tt);
char buffer[256]; 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); strftime(buffer, sizeof(buffer), "%Y-%m-%dT%H:%M:%Sz", tm);
_stream << buffer << " "; m_stream << buffer << " ";
_stream << file; m_stream << file;
_stream << " " << line; m_stream << " " << line;
// _stream << " " << func; m_stream << "\t";
_stream << "\t";
} }
ngraph::log_helper::~log_helper() LogHelper::~LogHelper()
{ {
cout << _stream.str() << endl; if (m_handler_func)
// logger::log_item(_stream.str()); {
m_handler_func(m_stream.str());
}
// Logger::log_item(m_stream.str());
} }
...@@ -17,43 +17,45 @@ ...@@ -17,43 +17,45 @@
#pragma once #pragma once
#include <deque> #include <deque>
#include <functional>
#include <sstream> #include <sstream>
#include <stdexcept> #include <stdexcept>
namespace ngraph namespace ngraph
{ {
class conststring class ConstString
{ {
public: public:
template <size_t SIZE> template <size_t SIZE>
constexpr conststring(const char (&p)[SIZE]) constexpr ConstString(const char (&p)[SIZE])
: _string(p) : m_string(p)
, _size(SIZE) , m_size(SIZE)
{ {
} }
constexpr char operator[](size_t i) const 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 const char* get_ptr(size_t offset) const { return &m_string[offset]; }
constexpr size_t size() const { return _size; } constexpr size_t size() const { return m_size; }
private: private:
const char* _string; const char* m_string;
size_t _size; 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) return offset == 0 ? s.get_ptr(0) : (s[offset] == ch ? s.get_ptr(offset + 1)
: find_last(s, offset - 1, ch)); : 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); 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 enum class LOG_TYPE
{ {
_LOG_TYPE_ERROR, _LOG_TYPE_ERROR,
...@@ -62,20 +64,24 @@ namespace ngraph ...@@ -62,20 +64,24 @@ namespace ngraph
_LOG_TYPE_DEBUG, _LOG_TYPE_DEBUG,
}; };
class log_helper class LogHelper
{ {
public: public:
log_helper(LOG_TYPE, const char* file, int line, const char* func); LogHelper(LOG_TYPE,
~log_helper(); 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: 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: public:
static void set_log_path(const std::string& path); static void set_log_path(const std::string& path);
...@@ -86,37 +92,41 @@ namespace ngraph ...@@ -86,37 +92,41 @@ namespace ngraph
static void log_item(const std::string& s); static void log_item(const std::string& s);
static void process_event(const std::string& s); static void process_event(const std::string& s);
static void thread_entry(void* param); static void thread_entry(void* param);
static std::string log_path; static std::string m_log_path;
static std::deque<std::string> queue; static std::deque<std::string> m_queue;
}; };
extern std::ostream& get_nil_stream(); extern std::ostream& get_nil_stream();
void default_logger_handler_func(const std::string& s);
#define NGRAPH_ERR \ #define NGRAPH_ERR \
ngraph::log_helper(ngraph::LOG_TYPE::_LOG_TYPE_ERROR, \ ngraph::LogHelper(ngraph::LOG_TYPE::_LOG_TYPE_ERROR, \
ngraph::get_file_name(__FILE__), \ ngraph::get_file_name(__FILE__), \
__LINE__, \ __LINE__, \
__PRETTY_FUNCTION__) \ default_logger_handler_func) \
.stream() .stream()
#define NGRAPH_WARN \ #define NGRAPH_WARN \
ngraph::log_helper(ngraph::LOG_TYPE::_LOG_TYPE_WARNING, \ ngraph::LogHelper(ngraph::LOG_TYPE::_LOG_TYPE_WARNING, \
ngraph::get_file_name(__FILE__), \ ngraph::get_file_name(__FILE__), \
__LINE__, \ __LINE__, \
__PRETTY_FUNCTION__) \ default_logger_handler_func) \
.stream() .stream()
#define NGRAPH_INFO \ #define NGRAPH_INFO \
ngraph::log_helper(ngraph::LOG_TYPE::_LOG_TYPE_INFO, \ ngraph::LogHelper(ngraph::LOG_TYPE::_LOG_TYPE_INFO, \
ngraph::get_file_name(__FILE__), \ ngraph::get_file_name(__FILE__), \
__LINE__, \ __LINE__, \
__PRETTY_FUNCTION__) \ default_logger_handler_func) \
.stream() .stream()
#ifdef NGRAPH_DEBUG_ENABLE #ifdef NGRAPH_DEBUG_ENABLE
#define NGRAPH_DEBUG \ #define NGRAPH_DEBUG \
ngraph::log_helper(ngraph::LOG_TYPE::_LOG_TYPE_DEBUG, \ ngraph::LogHelper(ngraph::LOG_TYPE::_LOG_TYPE_DEBUG, \
ngraph::get_file_name(__FILE__), \ ngraph::get_file_name(__FILE__), \
__LINE__, \ __LINE__, \
__PRETTY_FUNCTION__) \ default_logger_handler_func) \
.stream() .stream()
#else #else
#define NGRAPH_DEBUG ngraph::get_nil_stream() #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