1. Added test

2. Fixes
This commit is contained in:
gabi
2014-01-25 15:52:10 +02:00
parent 3e88d785c0
commit df56bb775a
13 changed files with 326 additions and 151 deletions

View File

@@ -1,55 +1,98 @@
#pragma once
#include <mutex>
#include <queue>
#include <thread>
#include <iostream>
#include "../logger.h"
#include <thread>
#include <chrono>
#include <mutex>
#include <atomic>
#include "base_sink.h"
#include "../logger.h"
#include "../details/blocking_queue.h"
namespace c11log {
namespace sinks {
class async_sink : base_sink {
enum class fullq_policy {
BLOCK=0,
DROP_MSG
};
class async_sink : public base_sink {
public:
async_sink(std::size_t max_queue_size, fullq_policy q_policy) :_fullq_policy(q_policy), _back_thread(&_thread_loop)
{
}
protected:
void _sink_it(const std::string& msg) override
{
_msgs_mutex.unlock();
_msgs.push(msg);
}
void _thread_loop()
{
while (_active) {
_msgs_mutex.lock();
std::string &msg = _msgs.front();
_msgs.pop();
_msgs_mutex.unlock();
std::cout << "Popped: " << msg << std::endl;
}
}
private:
c11log::logger::sinks_vector_t _sinks;
fullq_policy _fullq_policy;
std::queue<std::string> _msgs;
std::thread _back_thread;
bool _active = true;
std::mutex _msgs_mutex;
using size_type = c11log::details::blocking_queue<std::string>::size_type;
explicit async_sink(const std::size_t max_queue_size, const std::chrono::seconds& timeout = std::chrono::seconds::max());
~async_sink();
void add_sink(logger::sink_ptr_t sink);
void remove_sink(logger::sink_ptr_t sink_ptr);
protected:
void sink_it_(const std::string& msg) override;
void thread_loop_();
private:
c11log::logger::sinks_vector_t sinks_;
bool active_ = true;
const std::chrono::seconds timeout_;
c11log::details::blocking_queue<std::string> q_;
std::thread back_thread_;
void shutdown_();
};
}
}
void c11log::sinks::async_sink::_sink_it(const std::string& msg)
{
//
// async_sink inline impl
//
inline c11log::sinks::async_sink::async_sink(const std::size_t max_queue_size, const std::chrono::seconds& timeout)
:q_(max_queue_size),
timeout_(timeout),
back_thread_(&async_sink::thread_loop_, this)
{}
inline c11log::sinks::async_sink::~async_sink()
{
shutdown_();
}
inline void c11log::sinks::async_sink::sink_it_(const std::string& msg)
{
q_.push(msg, timeout_);
}
inline void c11log::sinks::async_sink::thread_loop_()
{
std::string msg;
while (active_)
{
if (q_.pop(msg, timeout_))
{
std::lock_guard<std::mutex> lock(mutex_);
for (auto &sink : sinks_)
{
if (active_)
sink->log(msg, _level);
else
break;
}
}
}
}
inline void c11log::sinks::async_sink::add_sink(logger::sink_ptr_t sink)
{
std::lock_guard<std::mutex> lock(mutex_);
sinks_.push_back(sink);
}
inline void c11log::sinks::async_sink::remove_sink(logger::sink_ptr_t sink_ptr)
{
std::lock_guard<std::mutex> lock(mutex_);
sinks_.erase(std::remove(sinks_.begin(), sinks_.end(), sink_ptr), sinks_.end());
}
inline void c11log::sinks::async_sink::shutdown_()
{
{
std::lock_guard<std::mutex> lock(mutex_);
active_ = false;
}
q_.clear();
back_thread_.join();
}
}

View File

@@ -1,4 +1,5 @@
#pragma once
#include<string>
#include<memory>
#include<mutex>
@@ -10,40 +11,38 @@ namespace c11log {
namespace sinks {
class base_sink {
public:
base_sink()
{}
base_sink() = default;
base_sink(level::level_enum l):_level(l)
{};
virtual ~base_sink()
{};
virtual ~base_sink() = default;
base_sink(const base_sink&) = delete;
base_sink& operator=(const base_sink&) = delete;
void log(const std::string &msg, level::level_enum level)
{
if (level >= _level) {
std::lock_guard<std::mutex> lock(_mutex);
std::lock_guard<std::mutex> lock(mutex_);
if (level >= _level)
_sink_it(msg);
sink_it_(msg);
}
};
void set_level(level::level_enum level)
{
std::lock_guard<std::mutex> lock(_mutex);
std::lock_guard<std::mutex> lock(mutex_);
_level = level;
}
protected:
virtual void _sink_it(const std::string& msg) = 0;
virtual void sink_it_(const std::string& msg) = 0;
level::level_enum _level = level::INFO;
std::mutex _mutex;
std::mutex mutex_;
};
class null_sink:public base_sink {
protected:
void _sink_it(const std::string& msg) override
void sink_it_(const std::string& msg) override
{}
};
}

View File

@@ -1,4 +1,5 @@
#pragma once
#include <fstream>
#include <iomanip>
@@ -22,7 +23,7 @@ public:
_ofstream.open(oss.str(), std::ofstream::app);
}
protected:
void _sink_it(const std::string& msg) override
void sink_it_(const std::string& msg) override
{
_ofstream << msg;
_ofstream.flush();
@@ -43,7 +44,7 @@ public:
virtual ~rotating_file_sink_base()
{}
protected:
virtual void _sink_it(const std::string& msg) override
virtual void sink_it_(const std::string& msg) override
{
if (_should_rotate())
_rotate();
@@ -69,10 +70,10 @@ public:
}
protected:
virtual void _sink_it(const std::string& msg) override
virtual void sink_it_(const std::string& msg) override
{
_current_size += msg.length();
rotating_file_sink_base::_sink_it(msg);
rotating_file_sink_base::sink_it_(msg);
}
bool _should_rotate() const override

View File

@@ -1,41 +1,38 @@
#pragma once
#include <iostream>
#include "base_sink.h"
namespace c11log
{
namespace sinks
namespace sinks
{
class ostream_sink: public base_sink
{
public:
ostream_sink(std::ostream& os):_ostream(os) {}
virtual ~ostream_sink() = default;
protected:
virtual void sink_it_(const std::string& msg) override
{
class ostream_sink:public base_sink
{
public:
ostream_sink(std::ostream& os):_ostream(os)
{}
virtual ~ostream_sink()
{}
protected:
virtual void _sink_it(const std::string& msg)
{
_ostream << msg;
}
std::ostream& _ostream;
};
class stdout_sink:public ostream_sink
{
public:
stdout_sink():ostream_sink(std::cout)
{}
};
class stderr_sink:public ostream_sink
{
public:
stderr_sink():ostream_sink(std::cerr)
{}
};
_ostream << msg;
}
std::ostream& _ostream;
};
class stdout_sink:public ostream_sink
{
public:
stdout_sink():ostream_sink(std::cout) {}
};
class stderr_sink:public ostream_sink
{
public:
stderr_sink():ostream_sink(std::cerr) {}
};
}
}