returned fast_oss with optimizations
This commit is contained in:
		@@ -2,11 +2,13 @@
 | 
			
		||||
 | 
			
		||||
#include <chrono>
 | 
			
		||||
 | 
			
		||||
namespace c11log {
 | 
			
		||||
namespace c11log
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
typedef std::chrono::system_clock log_clock;
 | 
			
		||||
 | 
			
		||||
namespace level {
 | 
			
		||||
namespace level
 | 
			
		||||
{
 | 
			
		||||
typedef enum {
 | 
			
		||||
    DEBUG,
 | 
			
		||||
    INFO,
 | 
			
		||||
 
 | 
			
		||||
@@ -10,11 +10,14 @@
 | 
			
		||||
#include <mutex>
 | 
			
		||||
#include <condition_variable>
 | 
			
		||||
 | 
			
		||||
namespace c11log {
 | 
			
		||||
namespace details {
 | 
			
		||||
namespace c11log
 | 
			
		||||
{
 | 
			
		||||
namespace details
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
class blocking_queue {
 | 
			
		||||
class blocking_queue
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    using queue_t = std::queue<T>;
 | 
			
		||||
    using size_type = typename queue_t::size_type;
 | 
			
		||||
 
 | 
			
		||||
@@ -5,10 +5,13 @@
 | 
			
		||||
#include <memory>
 | 
			
		||||
#include <mutex>
 | 
			
		||||
 | 
			
		||||
namespace c11log {
 | 
			
		||||
namespace c11log
 | 
			
		||||
{
 | 
			
		||||
class logger;
 | 
			
		||||
namespace details {
 | 
			
		||||
class factory {
 | 
			
		||||
namespace details
 | 
			
		||||
{
 | 
			
		||||
class factory
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    typedef std::shared_ptr<c11log::logger>  logger_ptr;
 | 
			
		||||
    typedef std::unordered_map<std::string, logger_ptr> logger_map;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,27 +1,29 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
// Fast ostringstream like supprt which return its string by ref and nothing more
 | 
			
		||||
 | 
			
		||||
#include<streambuf>
 | 
			
		||||
#include<string>
 | 
			
		||||
namespace c11log {
 | 
			
		||||
namespace details {
 | 
			
		||||
 | 
			
		||||
class str_devicebuf:public std::streambuf {
 | 
			
		||||
namespace c11log
 | 
			
		||||
{
 | 
			
		||||
namespace details
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
class str_devicebuf:public std::streambuf
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    str_devicebuf() = default;
 | 
			
		||||
    ~str_devicebuf() = default;
 | 
			
		||||
    str_devicebuf(const str_devicebuf& other):std::streambuf(),_str(other._str) {}
 | 
			
		||||
 | 
			
		||||
    str_devicebuf(str_devicebuf&& other) :std::streambuf(), _str(std::move(other._str)) {
 | 
			
		||||
        other._str.clear();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    str_devicebuf(const str_devicebuf& other) = delete;
 | 
			
		||||
    str_devicebuf(str_devicebuf&& other) = delete;
 | 
			
		||||
    str_devicebuf& operator=(const str_devicebuf&) = delete;
 | 
			
		||||
    str_devicebuf& operator=(str_devicebuf&&) = delete;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    const std::string& str_ref() const {
 | 
			
		||||
        return _str;
 | 
			
		||||
        std::ostringstream oss;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void clear() {
 | 
			
		||||
@@ -47,29 +49,22 @@ private:
 | 
			
		||||
    std::string _str;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class fast_oss:public std::ostream {
 | 
			
		||||
class fast_oss:public std::ostream
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    fast_oss():std::ostream(&_dev) {}
 | 
			
		||||
    ~fast_oss() = default;
 | 
			
		||||
 | 
			
		||||
    fast_oss(const fast_oss& other) :std::basic_ios<char>(), std::ostream(&_dev), _dev(other._dev) {}
 | 
			
		||||
 | 
			
		||||
    fast_oss(fast_oss&& other) :std::basic_ios<char>(), std::ostream(&_dev), _dev(std::move(other._dev)) {}
 | 
			
		||||
 | 
			
		||||
    fast_oss(const fast_oss& other) = delete;
 | 
			
		||||
    fast_oss(fast_oss&& other) = delete;
 | 
			
		||||
    fast_oss& operator=(const fast_oss& other) = delete;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    const std::string& str_ref() const {
 | 
			
		||||
        return _dev.str_ref();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const std::string str() const {
 | 
			
		||||
        return _dev.str_ref();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void clear() {
 | 
			
		||||
        _dev.clear();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    str_devicebuf _dev;
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -3,9 +3,12 @@
 | 
			
		||||
#include <iostream>
 | 
			
		||||
// Flush to file every X writes..
 | 
			
		||||
 | 
			
		||||
namespace c11log {
 | 
			
		||||
namespace details {
 | 
			
		||||
class file_flush_helper {
 | 
			
		||||
namespace c11log
 | 
			
		||||
{
 | 
			
		||||
namespace details
 | 
			
		||||
{
 | 
			
		||||
class file_flush_helper
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    explicit file_flush_helper(const std::chrono::milliseconds &flush_every): _flush_every(flush_every), _last_flush() {};
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -2,13 +2,17 @@
 | 
			
		||||
 | 
			
		||||
#include "../common_types.h"
 | 
			
		||||
#include "../logger.h"
 | 
			
		||||
#include "fast_oss.h"
 | 
			
		||||
#include <iostream>
 | 
			
		||||
 | 
			
		||||
namespace c11log {
 | 
			
		||||
namespace c11log
 | 
			
		||||
{
 | 
			
		||||
class logger;
 | 
			
		||||
namespace details {
 | 
			
		||||
namespace details
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
class line_logger {
 | 
			
		||||
class line_logger
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    line_logger(logger* callback_logger, level::level_enum msg_level, bool enabled):
 | 
			
		||||
        _callback_logger(callback_logger),
 | 
			
		||||
@@ -25,7 +29,7 @@ public:
 | 
			
		||||
 | 
			
		||||
    line_logger(line_logger&& other) :
 | 
			
		||||
        _callback_logger(other._callback_logger),
 | 
			
		||||
        _oss(std::move(other._oss)),
 | 
			
		||||
        _oss(),
 | 
			
		||||
        _level(other._level) {
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
@@ -36,7 +40,7 @@ public:
 | 
			
		||||
    ~line_logger() {
 | 
			
		||||
        if (_enabled) {
 | 
			
		||||
            _oss << '\n';
 | 
			
		||||
            _callback_logger->_log_it(_oss.str(), _level);
 | 
			
		||||
            _callback_logger->_log_it(_oss.str_ref(), _level);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -50,7 +54,8 @@ public:
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    logger* _callback_logger;
 | 
			
		||||
    std::ostringstream _oss;
 | 
			
		||||
    //std::ostringstream _oss;
 | 
			
		||||
    details::fast_oss _oss;
 | 
			
		||||
    level::level_enum _level;
 | 
			
		||||
    bool _enabled;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -3,9 +3,12 @@
 | 
			
		||||
#include<cstdio>
 | 
			
		||||
#include<ctime>
 | 
			
		||||
 | 
			
		||||
namespace c11log {
 | 
			
		||||
namespace details {
 | 
			
		||||
namespace os {
 | 
			
		||||
namespace c11log
 | 
			
		||||
{
 | 
			
		||||
namespace details
 | 
			
		||||
{
 | 
			
		||||
namespace os
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
inline std::tm localtime(const std::time_t &time_tt)
 | 
			
		||||
{
 | 
			
		||||
 
 | 
			
		||||
@@ -10,15 +10,18 @@
 | 
			
		||||
#include "common_types.h"
 | 
			
		||||
#include "details/os.h"
 | 
			
		||||
 | 
			
		||||
namespace c11log {
 | 
			
		||||
namespace formatters {
 | 
			
		||||
namespace c11log
 | 
			
		||||
{
 | 
			
		||||
namespace formatters
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
typedef std::function<std::string(const std::string& logger_name, const std::string&, level::level_enum, const c11log::log_clock::time_point&)> format_fn;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
std::string to_hex(const unsigned char* buf, std::size_t size);
 | 
			
		||||
 | 
			
		||||
class formatter {
 | 
			
		||||
class formatter
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    formatter() {}
 | 
			
		||||
    virtual ~formatter() {}
 | 
			
		||||
@@ -26,7 +29,8 @@ public:
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class default_formatter: public formatter {
 | 
			
		||||
class default_formatter: public formatter
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    // Format: [2013-12-29 01:04:42.900] [logger_name:Info] Message body
 | 
			
		||||
    void format_header(const std::string& logger_name, level::level_enum level, const log_clock::time_point& tp, std::ostream& dest) override {
 | 
			
		||||
@@ -55,8 +59,7 @@ inline void c11log::formatters::default_formatter::_format_time(const log_clock:
 | 
			
		||||
 | 
			
		||||
    auto tm_now = details::os::localtime(log_clock::to_time_t(tp));
 | 
			
		||||
    using namespace c11log::details::os;
 | 
			
		||||
    if(last_tm != tm_now)
 | 
			
		||||
    {
 | 
			
		||||
    if(last_tm != tm_now) {
 | 
			
		||||
#ifdef _MSC_VER
 | 
			
		||||
        ::sprintf_s
 | 
			
		||||
#else
 | 
			
		||||
 
 | 
			
		||||
@@ -12,15 +12,18 @@
 | 
			
		||||
#include "sinks/base_sink.h"
 | 
			
		||||
#include "details/factory.h"
 | 
			
		||||
 | 
			
		||||
namespace c11log {
 | 
			
		||||
namespace c11log
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
namespace details {
 | 
			
		||||
namespace details
 | 
			
		||||
{
 | 
			
		||||
class line_logger;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class logger {
 | 
			
		||||
class logger
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    typedef std::shared_ptr<sinks::base_sink>  sink_ptr_t;
 | 
			
		||||
@@ -30,8 +33,7 @@ public:
 | 
			
		||||
        _logger_name(name),
 | 
			
		||||
        _formatter(new formatters::default_formatter()),
 | 
			
		||||
        _sinks(),
 | 
			
		||||
        _mutex()
 | 
			
		||||
    {
 | 
			
		||||
        _mutex() {
 | 
			
		||||
        //Seems that vs2013 doesnt support atomic member initialization in ctor, so its done here
 | 
			
		||||
        _atomic_level = level::INFO;
 | 
			
		||||
    }
 | 
			
		||||
@@ -72,13 +74,9 @@ private:
 | 
			
		||||
 | 
			
		||||
logger& get_logger(const std::string& name);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// Logger inline impl
 | 
			
		||||
//
 | 
			
		||||
 
 | 
			
		||||
@@ -8,10 +8,13 @@
 | 
			
		||||
#include "../logger.h"
 | 
			
		||||
#include "../details/blocking_queue.h"
 | 
			
		||||
 | 
			
		||||
namespace c11log {
 | 
			
		||||
namespace sinks {
 | 
			
		||||
namespace c11log
 | 
			
		||||
{
 | 
			
		||||
namespace sinks
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
class async_sink : public base_sink {
 | 
			
		||||
class async_sink : public base_sink
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    using size_type = c11log::details::blocking_queue<std::string>::size_type;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -6,9 +6,12 @@
 | 
			
		||||
#include "../formatter.h"
 | 
			
		||||
#include "../common_types.h"
 | 
			
		||||
 | 
			
		||||
namespace c11log {
 | 
			
		||||
namespace sinks {
 | 
			
		||||
class base_sink {
 | 
			
		||||
namespace c11log
 | 
			
		||||
{
 | 
			
		||||
namespace sinks
 | 
			
		||||
{
 | 
			
		||||
class base_sink
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    base_sink() = default;
 | 
			
		||||
    base_sink(level::level_enum l):_level(l) {
 | 
			
		||||
@@ -33,7 +36,8 @@ protected:
 | 
			
		||||
    std::atomic<int> _level {level::INFO};
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class null_sink:public base_sink {
 | 
			
		||||
class null_sink:public base_sink
 | 
			
		||||
{
 | 
			
		||||
protected:
 | 
			
		||||
    void _sink_it(const std::string& ) override {
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -6,13 +6,16 @@
 | 
			
		||||
#include "base_sink.h"
 | 
			
		||||
#include "../details/flush_helper.h"
 | 
			
		||||
 | 
			
		||||
namespace c11log {
 | 
			
		||||
namespace sinks {
 | 
			
		||||
namespace c11log
 | 
			
		||||
{
 | 
			
		||||
namespace sinks
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
* Trivial file sink with single file as target
 | 
			
		||||
*/
 | 
			
		||||
class simple_file_sink : public base_sink {
 | 
			
		||||
class simple_file_sink : public base_sink
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    explicit simple_file_sink(const std::string &filename,
 | 
			
		||||
                              const std::string& extension,
 | 
			
		||||
@@ -36,7 +39,8 @@ private:
 | 
			
		||||
/*
 | 
			
		||||
 * Thread safe, size limited file sink
 | 
			
		||||
*/
 | 
			
		||||
class rotating_file_sink : public base_sink {
 | 
			
		||||
class rotating_file_sink : public base_sink
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    rotating_file_sink(const std::string &base_filename, const std::string &extension,
 | 
			
		||||
                       size_t max_size, size_t max_files,
 | 
			
		||||
@@ -104,7 +108,8 @@ private:
 | 
			
		||||
/*
 | 
			
		||||
 * Thread safe file sink that closes the log file at midnight and opens new one
 | 
			
		||||
 */
 | 
			
		||||
class daily_file_sink:public base_sink {
 | 
			
		||||
class daily_file_sink:public base_sink
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    explicit daily_file_sink(const std::string& base_filename,
 | 
			
		||||
                             const std::string& extension,
 | 
			
		||||
@@ -140,14 +145,14 @@ private:
 | 
			
		||||
        return system_clock::time_point(midnight + hours(24));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	//Create filename for the form basename.YYYY-MM-DD.extension
 | 
			
		||||
    //Create filename for the form basename.YYYY-MM-DD.extension
 | 
			
		||||
    static std::string _calc_filename(const std::string& basename, const std::string& extension) {
 | 
			
		||||
        std::tm tm = c11log::details::os::localtime();		
 | 
			
		||||
		std::ostringstream oss;
 | 
			
		||||
		oss << basename << '.';
 | 
			
		||||
		oss << tm.tm_year + 1900 << '-' << std::setw(2) << std::setfill('0') << tm.tm_mon + 1 << '-' << tm.tm_mday;
 | 
			
		||||
		oss << '.' << extension;
 | 
			
		||||
		return oss.str();
 | 
			
		||||
        std::tm tm = c11log::details::os::localtime();
 | 
			
		||||
        std::ostringstream oss;
 | 
			
		||||
        oss << basename << '.';
 | 
			
		||||
        oss << tm.tm_year + 1900 << '-' << std::setw(2) << std::setfill('0') << tm.tm_mon + 1 << '-' << tm.tm_mday;
 | 
			
		||||
        oss << '.' << extension;
 | 
			
		||||
        return oss.str();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    std::string _base_filename;
 | 
			
		||||
 
 | 
			
		||||
@@ -6,23 +6,26 @@
 | 
			
		||||
 | 
			
		||||
#include "base_sink.h"
 | 
			
		||||
 | 
			
		||||
namespace c11log {
 | 
			
		||||
namespace sinks {
 | 
			
		||||
class ostream_sink: public base_sink {
 | 
			
		||||
namespace c11log
 | 
			
		||||
{
 | 
			
		||||
namespace sinks
 | 
			
		||||
{
 | 
			
		||||
class ostream_sink: public base_sink
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    explicit ostream_sink(std::ostream& os):_ostream(os) {}
 | 
			
		||||
	ostream_sink(const ostream_sink&) = delete;
 | 
			
		||||
	ostream_sink& operator=(const ostream_sink&) = delete;
 | 
			
		||||
    ostream_sink(const ostream_sink&) = delete;
 | 
			
		||||
    ostream_sink& operator=(const ostream_sink&) = delete;
 | 
			
		||||
    virtual ~ostream_sink() = default;
 | 
			
		||||
 | 
			
		||||
protected:
 | 
			
		||||
    virtual void _sink_it(const std::string& msg) override {
 | 
			
		||||
		std::lock_guard<std::mutex> lock(_mutex);
 | 
			
		||||
        std::lock_guard<std::mutex> lock(_mutex);
 | 
			
		||||
        _ostream << msg;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    std::ostream& _ostream;
 | 
			
		||||
	std::mutex _mutex;
 | 
			
		||||
    std::mutex _mutex;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user