customized rotation filename
This commit is contained in:
parent
24dde318fe
commit
da9da9c9e7
@ -13,6 +13,7 @@
|
||||
#include <spdlog/details/null_mutex.h>
|
||||
#include <spdlog/fmt/fmt.h>
|
||||
|
||||
#include <cassert>
|
||||
#include <cerrno>
|
||||
#include <chrono>
|
||||
#include <ctime>
|
||||
@ -41,7 +42,7 @@ SPDLOG_INLINE rotating_file_sink<Mutex>::rotating_file_sink(
|
||||
if (max_files > 200000) {
|
||||
throw_spdlog_ex("rotating sink constructor: max_files arg cannot exceed 200000");
|
||||
}
|
||||
file_helper_.open(calc_filename(base_filename_, 0));
|
||||
file_helper_.open(get_filename_for_rotation_(base_filename_, 0));
|
||||
current_size_ = file_helper_.size(); // expensive. called only once
|
||||
if (rotate_on_open && current_size_ > 0) {
|
||||
rotate_();
|
||||
@ -49,6 +50,20 @@ SPDLOG_INLINE rotating_file_sink<Mutex>::rotating_file_sink(
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Mutex>
|
||||
SPDLOG_INLINE void rotating_file_sink<Mutex>::set_rotate_filename_format(std::function<filename_t(const filename_t &filename, std::size_t index)> rotation_file_format) {
|
||||
assert(!rotation_file_format_);
|
||||
rotation_file_format_ = std::move(rotation_file_format);
|
||||
}
|
||||
|
||||
template <typename Mutex>
|
||||
SPDLOG_INLINE filename_t rotating_file_sink<Mutex>::get_filename_for_rotation_(const filename_t &filename, std::size_t index) {
|
||||
if (rotation_file_format_) {
|
||||
return rotation_file_format_(filename, index);
|
||||
}
|
||||
return calc_filename(filename, index);
|
||||
}
|
||||
|
||||
// calc filename according to index and file extension if exists.
|
||||
// e.g. calc_filename("logs/mylog.txt, 3) => "logs/mylog.3.txt".
|
||||
template <typename Mutex>
|
||||
@ -112,11 +127,11 @@ SPDLOG_INLINE void rotating_file_sink<Mutex>::rotate_() {
|
||||
|
||||
file_helper_.close();
|
||||
for (auto i = max_files_; i > 0; --i) {
|
||||
filename_t src = calc_filename(base_filename_, i - 1);
|
||||
filename_t src = get_filename_for_rotation_(base_filename_, i - 1);
|
||||
if (!path_exists(src)) {
|
||||
continue;
|
||||
}
|
||||
filename_t target = calc_filename(base_filename_, i);
|
||||
filename_t target = get_filename_for_rotation_(base_filename_, i);
|
||||
|
||||
if (!rename_file_(src, target)) {
|
||||
// if failed try again after a small delay.
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include <spdlog/sinks/base_sink.h>
|
||||
|
||||
#include <chrono>
|
||||
#include <functional>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
|
||||
@ -26,10 +27,17 @@ public:
|
||||
std::size_t max_files,
|
||||
bool rotate_on_open = false,
|
||||
const file_event_handlers &event_handlers = {});
|
||||
// Default function to get rotation filename by base filename and rotation file index.
|
||||
static filename_t calc_filename(const filename_t &filename, std::size_t index);
|
||||
filename_t filename();
|
||||
void rotate_now();
|
||||
|
||||
// Set the file format for rotation files.
|
||||
// NOTE:
|
||||
// 1. The format function is supposed to be called only once, otherwise check failure.
|
||||
// 2. If [index] is 0, [filename] is expected to return.
|
||||
void set_rotate_filename_format(std::function<filename_t(const filename_t &filename, std::size_t index)> rotation_file_format);
|
||||
|
||||
protected:
|
||||
void sink_it_(const details::log_msg &msg) override;
|
||||
void flush_() override;
|
||||
@ -46,11 +54,15 @@ private:
|
||||
// return true on success, false otherwise.
|
||||
bool rename_file_(const filename_t &src_filename, const filename_t &target_filename);
|
||||
|
||||
// A wrapper around rotation filename format function(s).
|
||||
filename_t get_filename_for_rotation_(const filename_t &filename, std::size_t index);
|
||||
|
||||
filename_t base_filename_;
|
||||
std::size_t max_size_;
|
||||
std::size_t max_files_;
|
||||
std::size_t current_size_;
|
||||
details::file_helper file_helper_;
|
||||
std::function<filename_t(const filename_t &filename, std::size_t index)> rotation_file_format_;
|
||||
};
|
||||
|
||||
using rotating_file_sink_mt = rotating_file_sink<std::mutex>;
|
||||
|
@ -141,3 +141,30 @@ TEST_CASE("rotating_file_logger4", "[rotating_logger]") {
|
||||
REQUIRE(get_filesize(ROTATING_LOG) > 0);
|
||||
REQUIRE(get_filesize(ROTATING_LOG ".1") > 0);
|
||||
}
|
||||
|
||||
// Test customized rotation filename.
|
||||
TEST_CASE("rotating_file_logger5", "[rotating_logger]") {
|
||||
prepare_logdir();
|
||||
size_t max_size = 1024 * 10;
|
||||
spdlog::filename_t basename = SPDLOG_FILENAME_T(ROTATING_LOG);
|
||||
auto sink = std::make_shared<spdlog::sinks::rotating_file_sink_st>(basename, max_size, 2);
|
||||
sink->set_rotate_filename_format([](const spdlog::filename_t &filename, std::size_t index) {
|
||||
if (index == 0u) {
|
||||
return filename;
|
||||
}
|
||||
const auto old_fname = spdlog::sinks::rotating_file_sink_st::calc_filename(filename, index);
|
||||
return old_fname + ".test_suffix";
|
||||
});
|
||||
auto logger = std::make_shared<spdlog::logger>("rotating_sink_logger", sink);
|
||||
|
||||
logger->info("Test message - pre-rotation");
|
||||
logger->flush();
|
||||
|
||||
sink->rotate_now();
|
||||
|
||||
logger->info("Test message - post-rotation");
|
||||
logger->flush();
|
||||
|
||||
REQUIRE(get_filesize(ROTATING_LOG) > 0);
|
||||
REQUIRE(get_filesize(ROTATING_LOG ".1.test_suffix") > 0);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user