Commit e2aeb64d authored by Avijit's avatar Avijit Committed by GitHub

Merge pull request #36 from NervanaSystems/bob/log2

add log aggregator
parents f256e75d 34e5bb9d
......@@ -20,6 +20,7 @@ set (SRC
strides.cpp
tree.cpp
util.cpp
log.cpp
transformers/axes.cpp
transformers/exop.cpp
......
/*
Copyright 2016 Nervana Systems Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include <chrono>
#include <iomanip>
#include <iostream>
#include <ctime>
#include <thread>
#include <mutex>
#include <condition_variable>
#include "log.hpp"
using namespace std;
namespace nervana
{
class thread_starter;
}
string nervana::logger::log_path;
deque<string> nervana::logger::queue;
static mutex queue_mutex;
static condition_variable queue_condition;
static unique_ptr<thread> queue_thread;
static bool active = false;
class nervana::thread_starter
{
public:
thread_starter() { nervana::logger::start(); }
virtual ~thread_starter() { nervana::logger::stop(); }
};
static nervana::thread_starter _starter;
void nervana::logger::set_log_path(const string& path)
{
log_path = path;
}
void nervana::logger::start()
{
active = true;
queue_thread = unique_ptr<thread>(new thread(&thread_entry, nullptr));
}
void nervana::logger::stop()
{
{
unique_lock<std::mutex> lk(queue_mutex);
active = false;
queue_condition.notify_one();
}
queue_thread->join();
}
void nervana::logger::process_event(const string& s)
{
cout << s << "\n";
}
void nervana::logger::thread_entry(void* param)
{
unique_lock<std::mutex> lk(queue_mutex);
while (active)
{
queue_condition.wait(lk);
while (!queue.empty())
{
process_event(queue.front());
queue.pop_front();
}
}
}
void nervana::logger::log_item(const string& s)
{
unique_lock<std::mutex> lk(queue_mutex);
queue.push_back(s);
queue_condition.notify_one();
}
nervana::log_helper::log_helper(LOG_TYPE type, const char* file, int line, const char* 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;
}
std::time_t tt = chrono::system_clock::to_time_t(chrono::system_clock::now());
auto tm = std::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 << " ";
_stream << file;
_stream << " " << line;
// _stream << " " << func;
_stream << "\t";
}
nervana::log_helper::~log_helper()
{
cout << _stream.str() << endl;
// logger::log_item(_stream.str());
}
/*
Copyright 2016 Nervana Systems Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#pragma once
#include <sstream>
#include <stdexcept>
#include <deque>
namespace nervana
{
class conststring
{
public:
template <size_t SIZE>
constexpr conststring(const char (&p)[SIZE])
: _string(p)
, _size(SIZE)
{
}
constexpr char operator[](size_t i) const
{
return i < _size ? _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; }
private:
const char* _string;
size_t _size;
};
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)
{
return find_last(s, s.size() - 1, ch);
}
constexpr const char* get_file_name(conststring s) { return find_last(s, '/'); }
enum class LOG_TYPE
{
_LOG_TYPE_ERROR,
_LOG_TYPE_WARNING,
_LOG_TYPE_INFO,
};
class log_helper
{
public:
log_helper(LOG_TYPE, const char* file, int line, const char* func);
~log_helper();
std::ostream& stream() { return _stream; }
private:
std::stringstream _stream;
};
class logger
{
friend class log_helper;
public:
static void set_log_path(const std::string& path);
static void start();
static void stop();
private:
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;
};
#define ERR \
nervana::log_helper(nervana::LOG_TYPE::_LOG_TYPE_ERROR, \
nervana::get_file_name(__FILE__), \
__LINE__, \
__PRETTY_FUNCTION__) \
.stream()
#define WARN \
nervana::log_helper(nervana::LOG_TYPE::_LOG_TYPE_WARNING, \
nervana::get_file_name(__FILE__), \
__LINE__, \
__PRETTY_FUNCTION__) \
.stream()
#define INFO \
nervana::log_helper(nervana::LOG_TYPE::_LOG_TYPE_INFO, \
nervana::get_file_name(__FILE__), \
__LINE__, \
__PRETTY_FUNCTION__) \
.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