logger.h 4.09 KB
Newer Older
gab's avatar
gab committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161
#pragma once

#include<vector>
#include<memory>
#include<mutex>
#include<atomic>
#include <algorithm>

#include "level.h"
#include "sinks/base_sink.h"
#include "details/line_logger.h"
#include "details/factory.h"


namespace c11log {

class logger {
public:

    typedef std::shared_ptr<sinks::base_sink>  sink_ptr_t;
    typedef std::vector<sink_ptr_t> sinks_vector_t;

    explicit logger(const std::string& name) : _logger_name(name),
        _formatter(std::make_unique<formatters::default_formatter>())
    {
        _atomic_level.store(level::INFO);
    }

    ~logger()
    {
    };

    logger(const logger&) = delete;
    logger& operator=(const logger&) = delete;

    void set_name(const std::string& name);
    const std::string& get_name();
    void add_sink(sink_ptr_t sink_ptr);
    void remove_sink(sink_ptr_t sink_ptr);
    void set_formatter(std::unique_ptr<formatters::formatter> formatter);
    void set_level(c11log::level::level_enum level);
    c11log::level::level_enum get_level() const;
    bool should_log(c11log::level::level_enum level) const;

    details::line_logger log(level::level_enum level);
    details::line_logger debug();
    details::line_logger info();
    details::line_logger warn();
    details::line_logger error();
    details::line_logger fatal();

private:
    friend details::line_logger;


    std::string _logger_name = "";
    std::unique_ptr<c11log::formatters::formatter> _formatter;
    sinks_vector_t _sinks;
    std::mutex _mutex;
    std::atomic_int _atomic_level;

    void _log_it(const std::string& msg);

};

logger& get_logger(const std::string& name);
}

/*
Logger inline impl
*/

inline c11log::details::line_logger c11log::logger::log(c11log::level::level_enum msg_level)
{

    if (msg_level >= _atomic_level.load()) {
        std::lock_guard<std::mutex> lock(_mutex);
        return details::line_logger(this, msg_level);
    } else {
        return details::line_logger(nullptr);
    }

}

inline c11log::details::line_logger c11log::logger::debug()
{
    return log(c11log::level::DEBUG);
}
inline c11log::details::line_logger c11log::logger::info()
{
    return log(c11log::level::INFO);
}
inline c11log::details::line_logger c11log::logger::warn()
{
    return log(c11log::level::WARNING);
}
inline c11log::details::line_logger c11log::logger::error()
{
    return log(level::ERROR);
}
inline c11log::details::line_logger c11log::logger::fatal()
{
    return log(c11log::level::FATAL);
}

inline void c11log::logger::set_name(const std::string& name)
{
    std::lock_guard<std::mutex> lock(_mutex);
    _logger_name = name;
}

inline const std::string& c11log::logger::get_name()
{
    std::lock_guard<std::mutex> lock(_mutex);
    return _logger_name;
}

inline void c11log::logger::add_sink(sink_ptr_t sink_ptr)
{
    std::lock_guard<std::mutex> lock(_mutex);
    _sinks.push_back(sink_ptr);
}

inline void c11log::logger::remove_sink(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::logger::set_formatter(std::unique_ptr<formatters::formatter> formatter)
{
    std::lock_guard<std::mutex> lock(_mutex);
    _formatter = std::move(formatter);
}

inline void c11log::logger::set_level(c11log::level::level_enum level)
{
    _atomic_level.store(level);
}

inline c11log::level::level_enum c11log::logger::get_level() const
{
    return static_cast<c11log::level::level_enum>(_atomic_level.load());
}

inline bool c11log::logger::should_log(c11log::level::level_enum level) const
{
    return level >= _atomic_level.load();
}
inline void c11log::logger::_log_it(const std::string& msg)
{
    level::level_enum level = static_cast<level::level_enum>(_atomic_level.load());
    std::lock_guard<std::mutex> lock(_mutex);
    for (auto &sink : _sinks)
        sink->log(msg, level);
}

inline c11log::logger& c11log::get_logger(const std::string& name)
{
    return *(c11log::details::factory::instance().get_logger(name));
}