Merge pull request #2165 from seker/v1.x_file_event_handlers
add file event handlers
This commit is contained in:
		@@ -120,7 +120,22 @@ void basic_example()
 | 
			
		||||
void rotating_example()
 | 
			
		||||
{
 | 
			
		||||
    // Create a file rotating logger with 5mb size max and 3 rotated files.
 | 
			
		||||
    auto rotating_logger = spdlog::rotating_logger_mt("some_logger_name", "logs/rotating.txt", 1048576 * 5, 3);
 | 
			
		||||
    spdlog::file_event_handlers_t file_event_handlers;
 | 
			
		||||
        file_event_handlers.after_open = [](spdlog::filename_t filename, std::FILE* fstream)
 | 
			
		||||
    {
 | 
			
		||||
        fputs("OPEN!\r\n", fstream);
 | 
			
		||||
        spdlog::info("basic_example() : file_event_handlers.after_open      : {}", filename.c_str());
 | 
			
		||||
    };
 | 
			
		||||
    file_event_handlers.before_close = [](spdlog::filename_t filename, std::FILE* fstream)
 | 
			
		||||
    {
 | 
			
		||||
        fputs("CLOSE!\r\n", fstream);
 | 
			
		||||
        spdlog::info("basic_example() : file_event_handlers.before_close    : {}", filename.c_str());
 | 
			
		||||
    };
 | 
			
		||||
    file_event_handlers.after_close = [](spdlog::filename_t filename)
 | 
			
		||||
    {
 | 
			
		||||
        spdlog::info("basic_example() : file_event_handlers.after_close     : {}", filename.c_str());
 | 
			
		||||
    };
 | 
			
		||||
    auto rotating_logger = spdlog::rotating_logger_mt("some_logger_name", "logs/rotating.txt", 1048576 * 5, 3, false, file_event_handlers);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#include "spdlog/sinks/daily_file_sink.h"
 | 
			
		||||
 
 | 
			
		||||
@@ -14,6 +14,7 @@
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <type_traits>
 | 
			
		||||
#include <functional>
 | 
			
		||||
#include <cstdio>
 | 
			
		||||
 | 
			
		||||
#ifdef SPDLOG_COMPILED_LIB
 | 
			
		||||
#    undef SPDLOG_HEADER_ONLY
 | 
			
		||||
@@ -255,6 +256,13 @@ struct source_loc
 | 
			
		||||
    const char *funcname{nullptr};
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
typedef struct 
 | 
			
		||||
{
 | 
			
		||||
    std::function<void(const filename_t &filename, std::FILE *file_stream)> after_open;
 | 
			
		||||
    std::function<void(const filename_t &filename, std::FILE *file_stream)> before_close;
 | 
			
		||||
    std::function<void(const filename_t &filename)> after_close;
 | 
			
		||||
} file_event_handlers_t;
 | 
			
		||||
 | 
			
		||||
namespace details {
 | 
			
		||||
// make_unique support for pre c++14
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -20,6 +20,10 @@
 | 
			
		||||
namespace spdlog {
 | 
			
		||||
namespace details {
 | 
			
		||||
 | 
			
		||||
SPDLOG_INLINE file_helper::file_helper(const file_event_handlers_t& event_handlers)
 | 
			
		||||
    : event_handlers_(event_handlers)
 | 
			
		||||
{}
 | 
			
		||||
 | 
			
		||||
SPDLOG_INLINE file_helper::~file_helper()
 | 
			
		||||
{
 | 
			
		||||
    close();
 | 
			
		||||
@@ -52,6 +56,10 @@ SPDLOG_INLINE void file_helper::open(const filename_t &fname, bool truncate)
 | 
			
		||||
        }
 | 
			
		||||
        if (!os::fopen_s(&fd_, fname, mode))
 | 
			
		||||
        {
 | 
			
		||||
            if (event_handlers_.after_open)
 | 
			
		||||
            {
 | 
			
		||||
                event_handlers_.after_open(filename_, fd_);
 | 
			
		||||
            }
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -79,8 +87,18 @@ SPDLOG_INLINE void file_helper::close()
 | 
			
		||||
{
 | 
			
		||||
    if (fd_ != nullptr)
 | 
			
		||||
    {
 | 
			
		||||
        if (event_handlers_.before_close)
 | 
			
		||||
        {
 | 
			
		||||
            event_handlers_.before_close(filename_, fd_);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        std::fclose(fd_);
 | 
			
		||||
        fd_ = nullptr;
 | 
			
		||||
 | 
			
		||||
        if (event_handlers_.after_close)
 | 
			
		||||
        {
 | 
			
		||||
            event_handlers_.after_close(filename_);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -16,7 +16,8 @@ namespace details {
 | 
			
		||||
class SPDLOG_API file_helper
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    explicit file_helper() = default;
 | 
			
		||||
    file_helper() = default;
 | 
			
		||||
    explicit file_helper(const file_event_handlers_t& event_handlers);
 | 
			
		||||
 | 
			
		||||
    file_helper(const file_helper &) = delete;
 | 
			
		||||
    file_helper &operator=(const file_helper &) = delete;
 | 
			
		||||
@@ -50,6 +51,7 @@ private:
 | 
			
		||||
    const unsigned int open_interval_ = 10;
 | 
			
		||||
    std::FILE *fd_{nullptr};
 | 
			
		||||
    filename_t filename_;
 | 
			
		||||
    file_event_handlers_t event_handlers_{nullptr, nullptr, nullptr};
 | 
			
		||||
};
 | 
			
		||||
} // namespace details
 | 
			
		||||
} // namespace spdlog
 | 
			
		||||
 
 | 
			
		||||
@@ -14,7 +14,8 @@ namespace spdlog {
 | 
			
		||||
namespace sinks {
 | 
			
		||||
 | 
			
		||||
template<typename Mutex>
 | 
			
		||||
SPDLOG_INLINE basic_file_sink<Mutex>::basic_file_sink(const filename_t &filename, bool truncate)
 | 
			
		||||
SPDLOG_INLINE basic_file_sink<Mutex>::basic_file_sink(const filename_t &filename, bool truncate, const file_event_handlers_t& event_handlers)
 | 
			
		||||
    : file_helper_{event_handlers}
 | 
			
		||||
{
 | 
			
		||||
    file_helper_.open(filename, truncate);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -20,7 +20,7 @@ template<typename Mutex>
 | 
			
		||||
class basic_file_sink final : public base_sink<Mutex>
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    explicit basic_file_sink(const filename_t &filename, bool truncate = false);
 | 
			
		||||
    explicit basic_file_sink(const filename_t &filename, bool truncate = false, const file_event_handlers_t& event_handlers = {nullptr, nullptr, nullptr});
 | 
			
		||||
    const filename_t &filename() const;
 | 
			
		||||
 | 
			
		||||
protected:
 | 
			
		||||
@@ -40,15 +40,15 @@ using basic_file_sink_st = basic_file_sink<details::null_mutex>;
 | 
			
		||||
// factory functions
 | 
			
		||||
//
 | 
			
		||||
template<typename Factory = spdlog::synchronous_factory>
 | 
			
		||||
inline std::shared_ptr<logger> basic_logger_mt(const std::string &logger_name, const filename_t &filename, bool truncate = false)
 | 
			
		||||
inline std::shared_ptr<logger> basic_logger_mt(const std::string &logger_name, const filename_t &filename, bool truncate = false, const file_event_handlers_t& event_handlers = {nullptr, nullptr, nullptr})
 | 
			
		||||
{
 | 
			
		||||
    return Factory::template create<sinks::basic_file_sink_mt>(logger_name, filename, truncate);
 | 
			
		||||
    return Factory::template create<sinks::basic_file_sink_mt>(logger_name, filename, truncate, event_handlers);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename Factory = spdlog::synchronous_factory>
 | 
			
		||||
inline std::shared_ptr<logger> basic_logger_st(const std::string &logger_name, const filename_t &filename, bool truncate = false)
 | 
			
		||||
inline std::shared_ptr<logger> basic_logger_st(const std::string &logger_name, const filename_t &filename, bool truncate = false, const file_event_handlers_t& event_handlers = {nullptr, nullptr, nullptr})
 | 
			
		||||
{
 | 
			
		||||
    return Factory::template create<sinks::basic_file_sink_st>(logger_name, filename, truncate);
 | 
			
		||||
    return Factory::template create<sinks::basic_file_sink_st>(logger_name, filename, truncate, event_handlers);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // namespace spdlog
 | 
			
		||||
 
 | 
			
		||||
@@ -68,10 +68,11 @@ class daily_file_sink final : public base_sink<Mutex>
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    // create daily file sink which rotates on given time
 | 
			
		||||
    daily_file_sink(filename_t base_filename, int rotation_hour, int rotation_minute, bool truncate = false, uint16_t max_files = 0)
 | 
			
		||||
    daily_file_sink(filename_t base_filename, int rotation_hour, int rotation_minute, bool truncate = false, uint16_t max_files = 0, const file_event_handlers_t& event_handlers = {nullptr, nullptr, nullptr})
 | 
			
		||||
        : base_filename_(std::move(base_filename))
 | 
			
		||||
        , rotation_h_(rotation_hour)
 | 
			
		||||
        , rotation_m_(rotation_minute)
 | 
			
		||||
        , file_helper_{event_handlers}
 | 
			
		||||
        , truncate_(truncate)
 | 
			
		||||
        , max_files_(max_files)
 | 
			
		||||
        , filenames_q_()
 | 
			
		||||
@@ -214,29 +215,29 @@ using daily_file_format_sink_st = daily_file_sink<details::null_mutex, daily_fil
 | 
			
		||||
//
 | 
			
		||||
template<typename Factory = spdlog::synchronous_factory>
 | 
			
		||||
inline std::shared_ptr<logger> daily_logger_mt(
 | 
			
		||||
    const std::string &logger_name, const filename_t &filename, int hour = 0, int minute = 0, bool truncate = false, uint16_t max_files = 0)
 | 
			
		||||
    const std::string &logger_name, const filename_t &filename, int hour = 0, int minute = 0, bool truncate = false, uint16_t max_files = 0, const file_event_handlers_t& event_handlers = {nullptr, nullptr, nullptr})
 | 
			
		||||
{
 | 
			
		||||
    return Factory::template create<sinks::daily_file_sink_mt>(logger_name, filename, hour, minute, truncate, max_files);
 | 
			
		||||
    return Factory::template create<sinks::daily_file_sink_mt>(logger_name, filename, hour, minute, truncate, max_files, event_handlers);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename Factory = spdlog::synchronous_factory>
 | 
			
		||||
inline std::shared_ptr<logger> daily_logger_format_mt(
 | 
			
		||||
    const std::string &logger_name, const filename_t &filename, int hour = 0, int minute = 0, bool truncate = false, uint16_t max_files = 0)
 | 
			
		||||
    const std::string &logger_name, const filename_t &filename, int hour = 0, int minute = 0, bool truncate = false, uint16_t max_files = 0, const file_event_handlers_t& event_handlers = {nullptr, nullptr, nullptr})
 | 
			
		||||
{
 | 
			
		||||
    return Factory::template create<sinks::daily_file_format_sink_mt>(logger_name, filename, hour, minute, truncate, max_files);
 | 
			
		||||
    return Factory::template create<sinks::daily_file_format_sink_mt>(logger_name, filename, hour, minute, truncate, max_files, event_handlers);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename Factory = spdlog::synchronous_factory>
 | 
			
		||||
inline std::shared_ptr<logger> daily_logger_st(
 | 
			
		||||
    const std::string &logger_name, const filename_t &filename, int hour = 0, int minute = 0, bool truncate = false, uint16_t max_files = 0)
 | 
			
		||||
    const std::string &logger_name, const filename_t &filename, int hour = 0, int minute = 0, bool truncate = false, uint16_t max_files = 0, const file_event_handlers_t& event_handlers = {nullptr, nullptr, nullptr})
 | 
			
		||||
{
 | 
			
		||||
    return Factory::template create<sinks::daily_file_sink_st>(logger_name, filename, hour, minute, truncate, max_files);
 | 
			
		||||
    return Factory::template create<sinks::daily_file_sink_st>(logger_name, filename, hour, minute, truncate, max_files, event_handlers);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename Factory = spdlog::synchronous_factory>
 | 
			
		||||
inline std::shared_ptr<logger> daily_logger_format_st(
 | 
			
		||||
    const std::string &logger_name, const filename_t &filename, int hour = 0, int minute = 0, bool truncate = false, uint16_t max_files = 0)
 | 
			
		||||
    const std::string &logger_name, const filename_t &filename, int hour = 0, int minute = 0, bool truncate = false, uint16_t max_files = 0, const file_event_handlers_t& event_handlers = {nullptr, nullptr, nullptr})
 | 
			
		||||
{
 | 
			
		||||
    return Factory::template create<sinks::daily_file_format_sink_st>(logger_name, filename, hour, minute, truncate, max_files);
 | 
			
		||||
    return Factory::template create<sinks::daily_file_format_sink_st>(logger_name, filename, hour, minute, truncate, max_files, event_handlers);
 | 
			
		||||
}
 | 
			
		||||
} // namespace spdlog
 | 
			
		||||
 
 | 
			
		||||
@@ -46,8 +46,9 @@ class hourly_file_sink final : public base_sink<Mutex>
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    // create hourly file sink which rotates on given time
 | 
			
		||||
    hourly_file_sink(filename_t base_filename, bool truncate = false, uint16_t max_files = 0)
 | 
			
		||||
    hourly_file_sink(filename_t base_filename, bool truncate = false, uint16_t max_files = 0, const file_event_handlers_t& event_handlers = {nullptr, nullptr, nullptr})
 | 
			
		||||
        : base_filename_(std::move(base_filename))
 | 
			
		||||
        , file_helper_{event_handlers}
 | 
			
		||||
        , truncate_(truncate)
 | 
			
		||||
        , max_files_(max_files)
 | 
			
		||||
        , filenames_q_()
 | 
			
		||||
@@ -180,15 +181,15 @@ using hourly_file_sink_st = hourly_file_sink<details::null_mutex>;
 | 
			
		||||
//
 | 
			
		||||
template<typename Factory = spdlog::synchronous_factory>
 | 
			
		||||
inline std::shared_ptr<logger> hourly_logger_mt(
 | 
			
		||||
    const std::string &logger_name, const filename_t &filename, bool truncate = false, uint16_t max_files = 0)
 | 
			
		||||
    const std::string &logger_name, const filename_t &filename, bool truncate = false, uint16_t max_files = 0, const file_event_handlers_t& event_handlers = {nullptr, nullptr, nullptr})
 | 
			
		||||
{
 | 
			
		||||
    return Factory::template create<sinks::hourly_file_sink_mt>(logger_name, filename, truncate, max_files);
 | 
			
		||||
    return Factory::template create<sinks::hourly_file_sink_mt>(logger_name, filename, truncate, max_files, event_handlers);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename Factory = spdlog::synchronous_factory>
 | 
			
		||||
inline std::shared_ptr<logger> hourly_logger_st(
 | 
			
		||||
    const std::string &logger_name, const filename_t &filename, bool truncate = false, uint16_t max_files = 0)
 | 
			
		||||
    const std::string &logger_name, const filename_t &filename, bool truncate = false, uint16_t max_files = 0, const file_event_handlers_t& event_handlers = {nullptr, nullptr, nullptr})
 | 
			
		||||
{
 | 
			
		||||
    return Factory::template create<sinks::hourly_file_sink_st>(logger_name, filename, truncate, max_files);
 | 
			
		||||
    return Factory::template create<sinks::hourly_file_sink_st>(logger_name, filename, truncate, max_files, event_handlers);
 | 
			
		||||
}
 | 
			
		||||
} // namespace spdlog
 | 
			
		||||
 
 | 
			
		||||
@@ -25,10 +25,11 @@ namespace sinks {
 | 
			
		||||
 | 
			
		||||
template<typename Mutex>
 | 
			
		||||
SPDLOG_INLINE rotating_file_sink<Mutex>::rotating_file_sink(
 | 
			
		||||
    filename_t base_filename, std::size_t max_size, std::size_t max_files, bool rotate_on_open)
 | 
			
		||||
    filename_t base_filename, std::size_t max_size, std::size_t max_files, bool rotate_on_open, const file_event_handlers_t& event_handlers)
 | 
			
		||||
    : base_filename_(std::move(base_filename))
 | 
			
		||||
    , max_size_(max_size)
 | 
			
		||||
    , max_files_(max_files)
 | 
			
		||||
    , file_helper_{event_handlers}
 | 
			
		||||
{
 | 
			
		||||
    file_helper_.open(calc_filename(base_filename_, 0));
 | 
			
		||||
    current_size_ = file_helper_.size(); // expensive. called only once
 | 
			
		||||
 
 | 
			
		||||
@@ -22,7 +22,7 @@ template<typename Mutex>
 | 
			
		||||
class rotating_file_sink final : public base_sink<Mutex>
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    rotating_file_sink(filename_t base_filename, std::size_t max_size, std::size_t max_files, bool rotate_on_open = false);
 | 
			
		||||
    rotating_file_sink(filename_t base_filename, std::size_t max_size, std::size_t max_files, bool rotate_on_open = false, const file_event_handlers_t& event_handlers = {nullptr, nullptr, nullptr});
 | 
			
		||||
    static filename_t calc_filename(const filename_t &filename, std::size_t index);
 | 
			
		||||
    filename_t filename();
 | 
			
		||||
 | 
			
		||||
@@ -60,16 +60,16 @@ using rotating_file_sink_st = rotating_file_sink<details::null_mutex>;
 | 
			
		||||
 | 
			
		||||
template<typename Factory = spdlog::synchronous_factory>
 | 
			
		||||
inline std::shared_ptr<logger> rotating_logger_mt(
 | 
			
		||||
    const std::string &logger_name, const filename_t &filename, size_t max_file_size, size_t max_files, bool rotate_on_open = false)
 | 
			
		||||
    const std::string &logger_name, const filename_t &filename, size_t max_file_size, size_t max_files, bool rotate_on_open = false, const file_event_handlers_t& event_handlers = {nullptr, nullptr, nullptr})
 | 
			
		||||
{
 | 
			
		||||
    return Factory::template create<sinks::rotating_file_sink_mt>(logger_name, filename, max_file_size, max_files, rotate_on_open);
 | 
			
		||||
    return Factory::template create<sinks::rotating_file_sink_mt>(logger_name, filename, max_file_size, max_files, rotate_on_open, event_handlers);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename Factory = spdlog::synchronous_factory>
 | 
			
		||||
inline std::shared_ptr<logger> rotating_logger_st(
 | 
			
		||||
    const std::string &logger_name, const filename_t &filename, size_t max_file_size, size_t max_files, bool rotate_on_open = false)
 | 
			
		||||
    const std::string &logger_name, const filename_t &filename, size_t max_file_size, size_t max_files, bool rotate_on_open = false, const file_event_handlers_t& event_handlers = {nullptr, nullptr, nullptr})
 | 
			
		||||
{
 | 
			
		||||
    return Factory::template create<sinks::rotating_file_sink_st>(logger_name, filename, max_file_size, max_files, rotate_on_open);
 | 
			
		||||
    return Factory::template create<sinks::rotating_file_sink_st>(logger_name, filename, max_file_size, max_files, rotate_on_open, event_handlers);
 | 
			
		||||
}
 | 
			
		||||
} // namespace spdlog
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user