9 #include "quill/core/Attributes.h" 10 #include "quill/core/Common.h" 11 #include "quill/core/LogLevel.h" 12 #include "quill/core/LoggerBase.h" 13 #include "quill/core/PatternFormatterOptions.h" 14 #include "quill/core/Spinlock.h" 20 #include <initializer_list> 23 #include <string_view> 48 QUILL_NODISCARD
LoggerBase* get_logger(std::string
const& logger_name)
const 51 LoggerBase* logger = _find_logger(logger_name);
56 QUILL_NODISCARD std::vector<LoggerBase*> get_all_loggers()
const 60 std::vector<LoggerBase*> loggers;
62 for (
auto const& elem : _loggers)
65 if (elem->is_valid_logger())
67 loggers.push_back(elem.get());
75 QUILL_NODISCARD
LoggerBase* get_valid_logger(std::string_view exclude_logger_substr = {})
const 80 for (
auto const& elem : _loggers)
83 if (elem->is_valid_logger())
86 if (exclude_logger_substr.empty() ||
87 elem->get_logger_name().find(exclude_logger_substr) == std::string::npos)
99 QUILL_NODISCARD
size_t get_number_of_loggers()
const noexcept
102 return _loggers.size();
108 template <
typename TCallback>
113 for (
auto const& elem : _loggers)
126 template <
typename TLogger>
127 LoggerBase* create_or_get_logger(std::string
const& logger_name, std::vector<std::shared_ptr<Sink>> sinks,
133 LoggerBase* logger_ptr = _find_logger(logger_name);
138 std::unique_ptr<LoggerBase> new_logger{
139 new TLogger{logger_name,
static_cast<std::vector<std::shared_ptr<Sink>
>&&>(sinks),
140 pattern_formatter_options, clock_source, user_clock}};
142 _insert_logger(
static_cast<std::unique_ptr<LoggerBase>&&
>(new_logger));
147 logger_ptr = _find_logger(logger_name);
149 if (logger_ptr && _env_log_level)
161 template <
typename TLogger>
166 return get_logger(logger_name);
169 return create_or_get_logger<TLogger>(logger_name, source_logger->_sinks, source_logger->_pattern_formatter_options,
170 source_logger->_clock_source, source_logger->_user_clock);
177 _has_invalidated_loggers.store(
true, std::memory_order_release);
181 template <
typename TCheckQueuesEmpty>
182 QUILL_NODISCARD std::vector<std::string> cleanup_invalidated_loggers(TCheckQueuesEmpty check_queues_empty)
184 std::vector<std::string> removed_loggers;
186 if (_has_invalidated_loggers.load(std::memory_order_acquire))
188 _has_invalidated_loggers.store(
false, std::memory_order_release);
191 for (
auto it = _loggers.begin(); it != _loggers.end();)
193 if (!it->get()->is_valid_logger())
196 if (!check_queues_empty())
200 _has_invalidated_loggers.store(
true, std::memory_order_release);
204 removed_loggers.push_back(it->get()->get_logger_name());
205 it = _loggers.erase(it);
215 return removed_loggers;
219 QUILL_NODISCARD
bool has_invalidated_loggers()
const noexcept
221 return _has_invalidated_loggers.load(std::memory_order_acquire);
224 QUILL_ATTRIBUTE_COLD
void parse_log_level_from_env()
226 constexpr
char const* field =
"QUILL_LOG_LEVEL";
228 std::string log_level;
230 #if defined(_MSC_VER) 233 bool const ok = ::getenv_s(&len, buf,
sizeof(buf), field) == 0;
238 #else // revert to getenv 239 char* buf = ::getenv(field);
246 if (!log_level.empty())
248 _env_log_level = std::make_unique<LogLevel>(loglevel_from_string(log_level));
258 void _insert_logger(std::unique_ptr<LoggerBase> logger)
260 auto search_it = std::lower_bound(_loggers.begin(), _loggers.end(), logger->get_logger_name(),
261 [](std::unique_ptr<LoggerBase>
const& a, std::string
const& b)
262 {
return a->get_logger_name() < b; });
264 _loggers.insert(search_it,
static_cast<std::unique_ptr<LoggerBase>&&
>(logger));
268 QUILL_NODISCARD
LoggerBase* _find_logger(std::string
const& target)
const noexcept
270 auto search_it = std::lower_bound(_loggers.begin(), _loggers.end(), target,
271 [](std::unique_ptr<LoggerBase>
const& a, std::string
const& b)
272 {
return a->get_logger_name() < b; });
274 return (search_it != std::end(_loggers) && search_it->get()->get_logger_name() == target)
280 std::vector<std::unique_ptr<LoggerBase>> _loggers;
281 std::unique_ptr<LogLevel> _env_log_level;
283 std::atomic<bool> _has_invalidated_loggers{
false};
Base class for sinks.
Definition: Sink.h:40
QUILL_NODISCARD bool is_valid_logger() const noexcept
Checks if the logger is valid.
Definition: LoggerBase.h:111
void for_each_logger(TCallback cb) const
For backend use only.
Definition: LoggerManager.h:109
Setups a signal handler to handle fatal signals.
Definition: BackendManager.h:24
Definition: Spinlock.h:18
Definition: LoggerBase.h:36
void set_log_level(LogLevel new_log_level)
Set the log level of the logger.
Definition: LoggerBase.h:128
Definition: Spinlock.h:58
Base class that provides a timestamp for log statements based on a user-provided clock source...
Definition: UserClockSource.h:25
Definition: LoggerManager.h:34
void mark_invalid()
This function sets the logger's validity flag to false, indicating that the logger is no longer valid...
Definition: LoggerBase.h:105