22
33#include < algorithm>
44#include < chrono>
5+ #include < filesystem>
56#include < iomanip>
67#include < iostream>
78#include < ranges>
@@ -11,17 +12,21 @@ namespace odr {
1112
1213namespace {
1314
14- class NullLogger : public Logger {
15+ class NullLogger final : public Logger {
1516public:
16- [[nodiscard]] bool will_log (LogLevel) const override { return false ; }
17+ [[nodiscard]] bool will_log (LogLevel) const final { return false ; }
1718
1819 void log_impl (LogLevel, const std::string &,
19- const std::source_location &) override {
20+ const std::source_location &) final {
21+ // Do nothing
22+ }
23+
24+ void flush () final {
2025 // Do nothing
2126 }
2227};
2328
24- class StdioLogger : public Logger {
29+ class StdioLogger final : public Logger {
2530public:
2631 StdioLogger (std::string name, LogLevel level, LogFormat format,
2732 std::unique_ptr<std::ostream> output)
@@ -32,23 +37,27 @@ class StdioLogger : public Logger {
3237 }
3338 }
3439
35- [[nodiscard]] bool will_log (LogLevel level) const override {
40+ ~StdioLogger () final { flush (); }
41+
42+ [[nodiscard]] bool will_log (LogLevel level) const final {
3643 return level >= m_level;
3744 }
3845
3946 void log_impl (LogLevel level, const std::string &message,
40- const std::source_location &location) override {
41- *m_output << format (level, message, location, m_format) << std::endl ;
47+ const std::source_location &location) final {
48+ *m_output << format (m_name, level, message, location, m_format) << " \n " ;
4249 }
4350
51+ void flush () final { m_output->flush (); }
52+
4453private:
4554 std::string m_name;
4655 LogLevel m_level;
4756 LogFormat m_format;
4857 std::unique_ptr<std::ostream> m_output;
4958};
5059
51- class TeeLogger : public Logger {
60+ class TeeLogger final : public Logger {
5261public:
5362 explicit TeeLogger (const std::vector<std::shared_ptr<Logger>> &loggers)
5463 : m_loggers(loggers) {
@@ -57,19 +66,30 @@ class TeeLogger : public Logger {
5766 }
5867 }
5968
60- [[nodiscard]] bool will_log (LogLevel level) const override {
69+ ~TeeLogger () final { flush (); }
70+
71+ [[nodiscard]] bool will_log (LogLevel level) const final {
6172 return std::ranges::any_of (m_loggers, [level](const auto &logger) {
6273 return logger->will_log (level);
6374 });
6475 }
6576
6677 void log_impl (LogLevel level, const std::string &message,
67- const std::source_location &location) override {
78+ const std::source_location &location) final {
6879 for (const auto &logger : m_loggers) {
80+ if (!logger->will_log (level)) {
81+ continue ;
82+ }
6983 logger->log (level, message, location);
7084 }
7185 }
7286
87+ void flush () final {
88+ for (const auto &logger : m_loggers) {
89+ logger->flush ();
90+ }
91+ }
92+
7393private:
7494 std::vector<std::shared_ptr<Logger>> m_loggers;
7595};
@@ -112,7 +132,8 @@ Logger::create_tee(const std::vector<std::shared_ptr<Logger>> &loggers) {
112132 return std::make_unique<TeeLogger>(loggers);
113133}
114134
115- std::string Logger::format (LogLevel level, const std::string &message,
135+ std::string Logger::format (const std::string &name, LogLevel level,
136+ const std::string &message,
116137 const std::source_location &location,
117138 const LogFormat &format) {
118139 std::stringstream ss;
@@ -131,21 +152,21 @@ std::string Logger::format(LogLevel level, const std::string &message,
131152 level_ss << std::string (
132153 std::max<std::size_t >(0 , format.level_width - level_ss.str ().size ()),
133154 ' ' );
134- ss << level_ss.str ();
155+ ss << level_ss.str () << " " ;
135156 }
136157
137158 if (format.name_width > 0 ) {
138- std::string name = location.function_name ();
139159 std::stringstream name_ss;
140160 name_ss << name.substr (0 , format.name_width );
141161 name_ss << std::string (
142162 std::max<std::size_t >(0 , format.name_width - name_ss.str ().size ()),
143163 ' ' );
144- ss << name_ss.str ();
164+ ss << name_ss.str () << " " ;
145165 }
146166
147167 if (format.location_width > 0 ) {
148- std::string file_name = location.file_name ();
168+ std::string file_name =
169+ std::filesystem::path (location.file_name ()).filename ().string ();
149170 std::string line_number = std::to_string (location.line ());
150171 std::stringstream location_ss;
151172 if (file_name.size () + 1 + line_number.size () > format.location_width ) {
@@ -163,7 +184,7 @@ std::string Logger::format(LogLevel level, const std::string &message,
163184 std::max<std::size_t >(0 ,
164185 format.location_width - location_ss.str ().size ()),
165186 ' ' );
166- ss << location_ss.str ();
187+ ss << location_ss.str () << " " ;
167188 }
168189
169190 ss << message;
0 commit comments