From 4c2729419f3d3a937a0dfde42b836c4758b10253 Mon Sep 17 00:00:00 2001 From: Oded Date: Mon, 4 May 2020 08:16:39 -0700 Subject: [PATCH] spdlog: rotating_file_sink: Set log files ownership Add option to pass user id (uid) and group id (gid) when creating rotating log files. When creating and rotating files set the ownership to the given uid and gid. Default values are -1 which will not change the ownership. Signed-off-by: Oded --- include/spdlog/sinks/rotating_file_sink-inl.h | 25 ++++++++++++++++--- include/spdlog/sinks/rotating_file_sink.h | 11 +++++--- 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/include/spdlog/sinks/rotating_file_sink-inl.h b/include/spdlog/sinks/rotating_file_sink-inl.h index d715ebf3..ba2999e9 100644 --- a/include/spdlog/sinks/rotating_file_sink-inl.h +++ b/include/spdlog/sinks/rotating_file_sink-inl.h @@ -25,14 +25,20 @@ namespace sinks { template SPDLOG_INLINE rotating_file_sink::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, uid_t uid, gid_t gid) : base_filename_(std::move(base_filename)) , max_size_(max_size) , max_files_(max_files) + , uid_ (uid) + , gid_ (gid) { file_helper_.open(calc_filename(base_filename_, 0)); + current_size_ = file_helper_.size(); // expensive. called only once - if (rotate_on_open && current_size_ > 0) + + set_file_ownership(calc_filename(base_filename_, 0)); + + if (rotate_on_open && current_size_ > 0) { rotate_(); } @@ -110,11 +116,16 @@ SPDLOG_INLINE void rotating_file_sink::rotate_() { file_helper_.reopen(true); // truncate the log file anyway to prevent it to grow beyond its limit! current_size_ = 0; - throw_spdlog_ex("rotating_file_sink: failed renaming " + filename_to_str(src) + " to " + filename_to_str(target), errno); + auto last_error = errno; + set_file_ownership(calc_filename(base_filename_, 0)); + throw_spdlog_ex("rotating_file_sink: failed renaming " + filename_to_str(src) + " to " + filename_to_str(target), last_error); } } + + set_file_ownership(target); } file_helper_.reopen(true); + set_file_ownership(calc_filename(base_filename_, 0)); } // delete the target if exists, and rename the src file to target @@ -126,6 +137,14 @@ SPDLOG_INLINE bool rotating_file_sink::rename_file_(const filename_t &src (void)details::os::remove(target_filename); return details::os::rename(src_filename, target_filename) == 0; } +template +SPDLOG_INLINE void rotating_file_sink::set_file_ownership(filename_t filename) +{ + if (chown(filename.data(), uid_, gid_) < 0) { + throw spdlog_ex( + "set_file_ownership: failed changing file ownership " + details::os::filename_to_str(filename), errno); + } +} } // namespace sinks } // namespace spdlog diff --git a/include/spdlog/sinks/rotating_file_sink.h b/include/spdlog/sinks/rotating_file_sink.h index e1e85a7d..db506c4a 100644 --- a/include/spdlog/sinks/rotating_file_sink.h +++ b/include/spdlog/sinks/rotating_file_sink.h @@ -3,6 +3,7 @@ #pragma once +#include #include #include #include @@ -22,7 +23,7 @@ template class rotating_file_sink final : public base_sink { 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, uid_t uid = -1, gid_t gid = -1); static filename_t calc_filename(const filename_t &filename, std::size_t index); filename_t filename(); @@ -42,11 +43,15 @@ private: // return true on success, false otherwise. bool rename_file_(const filename_t &src_filename, const filename_t &target_filename); + void set_file_ownership(filename_t filename); + filename_t base_filename_; std::size_t max_size_; std::size_t max_files_; std::size_t current_size_; details::file_helper file_helper_; + uid_t uid_; + gid_t gid_; }; using rotating_file_sink_mt = rotating_file_sink; @@ -60,9 +65,9 @@ using rotating_file_sink_st = rotating_file_sink; template inline std::shared_ptr 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, uid_t uid = -1, gid_t gid = -1) { - return Factory::template create(logger_name, filename, max_file_size, max_files, rotate_on_open); + return Factory::template create(logger_name, filename, max_file_size, max_files, rotate_on_open, uid, gid); } template