Coverage Report

Created: 2026-10-28 06:29

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/spdlog/include/spdlog/details/registry.h
Line
Count
Source
1
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
2
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
3
4
#pragma once
5
6
// Loggers registry of unique name->logger pointer
7
// An attempt to create a logger with an already existing name will result with spdlog_ex exception.
8
// If user requests a non existing logger, nullptr will be returned
9
// This class is thread safe
10
11
#include <spdlog/common.h>
12
#include <spdlog/details/periodic_worker.h>
13
14
#include <chrono>
15
#include <functional>
16
#include <memory>
17
#include <mutex>
18
#include <string>
19
#include <unordered_map>
20
21
SPDLOG_NAMESPACE_BEGIN
22
class logger;
23
24
namespace details {
25
class thread_pool;
26
27
class SPDLOG_API registry {
28
public:
29
    using log_levels = std::unordered_map<std::string, level::level_enum>;
30
    registry(const registry &) = delete;
31
    registry &operator=(const registry &) = delete;
32
33
    void register_logger(std::shared_ptr<logger> new_logger);
34
    void register_or_replace(std::shared_ptr<logger> new_logger);
35
    void initialize_logger(std::shared_ptr<logger> new_logger);
36
    std::shared_ptr<logger> get(const std::string &logger_name);
37
    std::shared_ptr<logger> default_logger();
38
39
    // Return raw ptr to the default logger.
40
    // To be used directly by the spdlog default api (e.g. spdlog::info)
41
    // This make the default API faster, but cannot be used concurrently with set_default_logger().
42
    // e.g do not call set_default_logger() from one thread while calling spdlog::info() from
43
    // another.
44
    logger *get_default_raw();
45
46
    // set default logger and add it to the registry if not registered already.
47
    // default logger is stored in default_logger_ (for faster retrieval) and in the loggers_ map.
48
    // Note: Make sure to unregister it when no longer needed or before calling again with a new
49
    // logger.
50
    void set_default_logger(std::shared_ptr<logger> new_default_logger);
51
52
    void set_tp(std::shared_ptr<thread_pool> tp);
53
54
    std::shared_ptr<thread_pool> get_tp();
55
56
    // Set global formatter. Each sink in each logger will get a clone of this object
57
    void set_formatter(std::unique_ptr<formatter> formatter);
58
59
    void enable_backtrace(size_t n_messages);
60
61
    void disable_backtrace();
62
63
    void set_level(level::level_enum log_level);
64
65
    void flush_on(level::level_enum log_level);
66
67
    template <typename Rep, typename Period>
68
    void flush_every(std::chrono::duration<Rep, Period> interval) {
69
        std::lock_guard<std::mutex> lock(flusher_mutex_);
70
        auto clbk = [this]() { this->flush_all(); };
71
        periodic_flusher_ = details::make_unique<periodic_worker>(clbk, interval);
72
    }
73
74
0
    std::unique_ptr<periodic_worker> &get_flusher() {
75
0
        std::lock_guard<std::mutex> lock(flusher_mutex_);
76
0
        return periodic_flusher_;
77
0
    }
78
79
    void set_error_handler(err_handler handler);
80
81
    void apply_all(const std::function<void(const std::shared_ptr<logger>)> &fun);
82
83
    void flush_all();
84
85
    void drop(const std::string &logger_name);
86
87
    void drop_all();
88
89
    // clean all resources and threads started by the registry
90
    void shutdown();
91
92
    std::recursive_mutex &tp_mutex();
93
94
    void set_automatic_registration(bool automatic_registration);
95
96
    // set levels for all existing/future loggers. global_level can be null if should not set.
97
    void set_levels(log_levels levels, level::level_enum *global_level);
98
99
    static registry &instance();
100
101
    void apply_logger_env_levels(std::shared_ptr<logger> new_logger);
102
103
private:
104
    registry();
105
    ~registry();
106
107
    void throw_if_exists_(const std::string &logger_name);
108
    void register_logger_(std::shared_ptr<logger> new_logger);
109
    void register_or_replace_(std::shared_ptr<logger> new_logger);
110
    bool set_level_from_cfg_(logger *logger);
111
    std::mutex logger_map_mutex_, flusher_mutex_;
112
    std::recursive_mutex tp_mutex_;
113
    std::unordered_map<std::string, std::shared_ptr<logger>> loggers_;
114
    log_levels log_levels_;
115
    std::unique_ptr<formatter> formatter_;
116
    level::level_enum global_log_level_ = level::info;
117
    level::level_enum flush_level_ = level::off;
118
    err_handler err_handler_;
119
    std::shared_ptr<thread_pool> tp_;
120
    std::unique_ptr<periodic_worker> periodic_flusher_;
121
    std::shared_ptr<logger> default_logger_;
122
    bool automatic_registration_ = true;
123
    size_t backtrace_n_messages_ = 0;
124
};
125
126
}  // namespace details
127
SPDLOG_NAMESPACE_END
128
129
#ifdef SPDLOG_HEADER_ONLY
130
#include "registry-inl.h"
131
#endif