diff --git a/lib/include/srsran/srslog/srslog.h b/lib/include/srsran/srslog/srslog.h index b9af1f5bc..cab1ca125 100644 --- a/lib/include/srsran/srslog/srslog.h +++ b/lib/include/srsran/srslog/srslog.h @@ -179,10 +179,12 @@ sink& fetch_stderr_sink(const std::string& id = "stderr", /// Specifying a max_size value different to zero will make the sink create a /// new file each time the current file exceeds this value. The units of /// max_size are bytes. +/// Setting force_flush to true will flush the sink after every write. /// NOTE: Any '#' characters in the path will get removed. sink& fetch_file_sink(const std::string& path, - size_t max_size = 0, - std::unique_ptr f = get_default_log_formatter()); + size_t max_size = 0, + bool force_flush = false, + std::unique_ptr f = get_default_log_formatter()); /// Returns an instance of a sink that writes into syslog /// preamble: The string prepended to every message, If ident is "", the program name is used. diff --git a/lib/include/srsran/srslog/srslog_c.h b/lib/include/srsran/srslog/srslog_c.h index 4b55a5767..041615830 100644 --- a/lib/include/srsran/srslog/srslog_c.h +++ b/lib/include/srsran/srslog/srslog_c.h @@ -148,9 +148,10 @@ srslog_sink* srslog_fetch_stderr_sink(void); * Specifying a max_size value different to zero will make the sink create a * new file each time the current file exceeds this value. The units of * max_size are bytes. + * Setting force_flush to true will flush the sink after every write. * NOTE: Any '#' characters in the id will get removed. */ -srslog_sink* srslog_fetch_file_sink(const char* path, size_t max_size); +srslog_sink* srslog_fetch_file_sink(const char* path, size_t max_size, srslog_bool force_flush); #ifdef __cplusplus } diff --git a/lib/src/srslog/sinks/file_sink.h b/lib/src/srslog/sinks/file_sink.h index 5a15d9318..32a98926a 100644 --- a/lib/src/srslog/sinks/file_sink.h +++ b/lib/src/srslog/sinks/file_sink.h @@ -24,9 +24,10 @@ namespace srslog { class file_sink : public sink { public: - file_sink(std::string name, size_t max_size, std::unique_ptr f) : + file_sink(std::string name, size_t max_size, bool force_flush, std::unique_ptr f) : sink(std::move(f)), max_size((max_size == 0) ? 0 : std::max(max_size, 4 * 1024)), + force_flush(force_flush), base_filename(std::move(name)) {} @@ -53,6 +54,10 @@ public: return err_str; } + if (force_flush) { + flush(); + } + return handler.write(buffer); } @@ -88,6 +93,7 @@ private: private: const size_t max_size; + const bool force_flush; const std::string base_filename; file_utils::file handler; size_t current_size = 0; diff --git a/lib/src/srslog/srslog.cpp b/lib/src/srslog/srslog.cpp index 947cea375..f54979460 100644 --- a/lib/src/srslog/srslog.cpp +++ b/lib/src/srslog/srslog.cpp @@ -148,7 +148,10 @@ sink& srslog::fetch_stderr_sink(const std::string& id, std::unique_ptr f) +sink& srslog::fetch_file_sink(const std::string& path, + size_t max_size, + bool force_flush, + std::unique_ptr f) { assert(!path.empty() && "Empty path string"); @@ -161,7 +164,7 @@ sink& srslog::fetch_file_sink(const std::string& path, size_t max_size, std::uni auto& s = srslog_instance::get().get_sink_repo().emplace( std::piecewise_construct, std::forward_as_tuple(path), - std::forward_as_tuple(new file_sink(path, max_size, std::move(f)))); + std::forward_as_tuple(new file_sink(path, max_size, force_flush, std::move(f)))); return *s; } @@ -388,7 +391,8 @@ sink* srslog::create_file_sink(const std::string& path, size_t max_size) .get_sink_repo() .emplace(std::piecewise_construct, std::forward_as_tuple(path), - std::forward_as_tuple(new file_sink(path, max_size, std::unique_ptr(new text_formatter)))) + std::forward_as_tuple( + new file_sink(path, max_size, false, std::unique_ptr(new text_formatter)))) .get(); } diff --git a/lib/src/srslog/srslog_c.cpp b/lib/src/srslog/srslog_c.cpp index 3b6edbf0c..87554d6d1 100644 --- a/lib/src/srslog/srslog_c.cpp +++ b/lib/src/srslog/srslog_c.cpp @@ -181,7 +181,7 @@ srslog_sink* srslog_fetch_stderr_sink(void) return c_cast(&fetch_stderr_sink()); } -srslog_sink* srslog_fetch_file_sink(const char* path, size_t max_size) +srslog_sink* srslog_fetch_file_sink(const char* path, size_t max_size, srslog_bool force_flush) { - return c_cast(&fetch_file_sink(path, max_size)); + return c_cast(&fetch_file_sink(path, max_size, force_flush)); } diff --git a/lib/test/srslog/file_sink_test.cpp b/lib/test/srslog/file_sink_test.cpp index 39689e0af..822be9aa0 100644 --- a/lib/test/srslog/file_sink_test.cpp +++ b/lib/test/srslog/file_sink_test.cpp @@ -22,7 +22,7 @@ static constexpr char log_filename[] = "file_sink_test.log"; static bool when_data_is_written_to_file_then_contents_are_valid() { file_test_utils::scoped_file_deleter deleter(log_filename); - file_sink file(log_filename, 0, std::unique_ptr(new test_dummies::log_formatter_dummy)); + file_sink file(log_filename, 0, false, std::unique_ptr(new test_dummies::log_formatter_dummy)); std::vector entries; for (unsigned i = 0; i != 10; ++i) { @@ -45,7 +45,7 @@ class file_sink_subclass : public file_sink { public: file_sink_subclass(std::string name, size_t max_size) : - file_sink(std::move(name), max_size, std::unique_ptr(new test_dummies::log_formatter_dummy)) + file_sink(std::move(name), max_size, false, std::unique_ptr(new test_dummies::log_formatter_dummy)) {} uint32_t get_num_of_files() const { return get_file_index(); } diff --git a/srsenb/src/main.cc b/srsenb/src/main.cc index 79f036a3c..bdc743716 100644 --- a/srsenb/src/main.cc +++ b/srsenb/src/main.cc @@ -550,7 +550,7 @@ int main(int argc, char* argv[]) : srslog::fetch_file_sink(args.log.filename, fixup_log_file_maxsize(args.log.file_max_size))); // Alarms log channel creation. - srslog::sink& alarm_sink = srslog::fetch_file_sink(args.general.alarms_filename); + srslog::sink& alarm_sink = srslog::fetch_file_sink(args.general.alarms_filename, 0, true); srslog::log_channel& alarms_channel = srslog::fetch_log_channel("alarms", alarm_sink, {"ALRM", '\0', false}); alarms_channel.set_enabled(args.general.alarms_log_enable); @@ -573,7 +573,7 @@ int main(int argc, char* argv[]) // Set up the JSON log channel used by metrics and events. srslog::sink& json_sink = - srslog::fetch_file_sink(args.general.report_json_filename, 0, srslog::create_json_formatter()); + srslog::fetch_file_sink(args.general.report_json_filename, 0, false, srslog::create_json_formatter()); srslog::log_channel& json_channel = srslog::fetch_log_channel("JSON_channel", json_sink, {}); json_channel.set_enabled(args.general.report_json_enable); diff --git a/srsue/src/main.cc b/srsue/src/main.cc index 666ba2c6c..15a5a0c12 100644 --- a/srsue/src/main.cc +++ b/srsue/src/main.cc @@ -725,7 +725,7 @@ int main(int argc, char* argv[]) // Set up the JSON log channel used by metrics. srslog::sink& json_sink = - srslog::fetch_file_sink(args.general.metrics_json_filename, 0, srslog::create_json_formatter()); + srslog::fetch_file_sink(args.general.metrics_json_filename, 0, false, srslog::create_json_formatter()); srslog::log_channel& json_channel = srslog::fetch_log_channel("JSON_channel", json_sink, {}); json_channel.set_enabled(args.general.metrics_json_enable);