source: trunk/GDE/SINA/builddir/include/spdlog/details/registry.h

Last change on this file was 19170, checked in by westram, 2 years ago
  • sina source
    • unpack + remove tarball
    • no longer ignore sina builddir.
File size: 7.9 KB
Line 
1//
2// Copyright(c) 2015 Gabi Melman.
3// Distributed under the MIT License (http://opensource.org/licenses/MIT)
4//
5
6#pragma once
7
8// Loggers registy of unique name->logger pointer
9// An attempt to create a logger with an already existing name will be ignored
10// If user requests a non existing logger, nullptr will be returned
11// This class is thread safe
12
13#include "spdlog/common.h"
14#include "spdlog/details/periodic_worker.h"
15#include "spdlog/logger.h"
16
17#ifndef SPDLOG_DISABLE_DEFAULT_LOGGER
18// support for the default stdout color logger
19#ifdef _WIN32
20#include "spdlog/sinks/wincolor_sink.h"
21#else
22#include "spdlog/sinks/ansicolor_sink.h"
23#endif
24#endif // SPDLOG_DISABLE_DEFAULT_LOGGER
25
26#include <chrono>
27#include <functional>
28#include <memory>
29#include <string>
30#include <unordered_map>
31
32namespace spdlog {
33namespace details {
34class thread_pool;
35
36class registry
37{
38public:
39    registry(const registry &) = delete;
40    registry &operator=(const registry &) = delete;
41
42    void register_logger(std::shared_ptr<logger> new_logger)
43    {
44        std::lock_guard<std::mutex> lock(logger_map_mutex_);
45        register_logger_(std::move(new_logger));
46    }
47
48    void initialize_logger(std::shared_ptr<logger> new_logger)
49    {
50        std::lock_guard<std::mutex> lock(logger_map_mutex_);
51        new_logger->set_formatter(formatter_->clone());
52
53        if (err_handler_)
54        {
55            new_logger->set_error_handler(err_handler_);
56        }
57
58        new_logger->set_level(level_);
59        new_logger->flush_on(flush_level_);
60
61        if (automatic_registration_)
62        {
63            register_logger_(std::move(new_logger));
64        }
65    }
66
67    std::shared_ptr<logger> get(const std::string &logger_name)
68    {
69        std::lock_guard<std::mutex> lock(logger_map_mutex_);
70        auto found = loggers_.find(logger_name);
71        return found == loggers_.end() ? nullptr : found->second;
72    }
73
74    std::shared_ptr<logger> default_logger()
75    {
76        std::lock_guard<std::mutex> lock(logger_map_mutex_);
77        return default_logger_;
78    }
79
80    // Return raw ptr to the default logger.
81    // To be used directly by the spdlog default api (e.g. spdlog::info)
82    // This make the default API faster, but cannot be used concurrently with set_default_logger().
83    // e.g do not call set_default_logger() from one thread while calling spdlog::info() from another.
84    logger *get_default_raw()
85    {
86        return default_logger_.get();
87    }
88
89    // set default logger.
90    // default logger is stored in default_logger_ (for faster retrieval) and in the loggers_ map.
91    void set_default_logger(std::shared_ptr<logger> new_default_logger)
92    {
93        std::lock_guard<std::mutex> lock(logger_map_mutex_);
94        // remove previous default logger from the map
95        if (default_logger_ != nullptr)
96        {
97            loggers_.erase(default_logger_->name());
98        }
99        if (new_default_logger != nullptr)
100        {
101            loggers_[new_default_logger->name()] = new_default_logger;
102        }
103        default_logger_ = std::move(new_default_logger);
104    }
105
106    void set_tp(std::shared_ptr<thread_pool> tp)
107    {
108        std::lock_guard<std::recursive_mutex> lock(tp_mutex_);
109        tp_ = std::move(tp);
110    }
111
112    std::shared_ptr<thread_pool> get_tp()
113    {
114        std::lock_guard<std::recursive_mutex> lock(tp_mutex_);
115        return tp_;
116    }
117
118    // Set global formatter. Each sink in each logger will get a clone of this object
119    void set_formatter(std::unique_ptr<formatter> formatter)
120    {
121        std::lock_guard<std::mutex> lock(logger_map_mutex_);
122        formatter_ = std::move(formatter);
123        for (auto &l : loggers_)
124        {
125            l.second->set_formatter(formatter_->clone());
126        }
127    }
128
129    void set_level(level::level_enum log_level)
130    {
131        std::lock_guard<std::mutex> lock(logger_map_mutex_);
132        for (auto &l : loggers_)
133        {
134            l.second->set_level(log_level);
135        }
136        level_ = log_level;
137    }
138
139    void flush_on(level::level_enum log_level)
140    {
141        std::lock_guard<std::mutex> lock(logger_map_mutex_);
142        for (auto &l : loggers_)
143        {
144            l.second->flush_on(log_level);
145        }
146        flush_level_ = log_level;
147    }
148
149    void flush_every(std::chrono::seconds interval)
150    {
151        std::lock_guard<std::mutex> lock(flusher_mutex_);
152        std::function<void()> clbk = std::bind(&registry::flush_all, this);
153        periodic_flusher_ = details::make_unique<periodic_worker>(clbk, interval);
154    }
155
156    void set_error_handler(log_err_handler handler)
157    {
158        std::lock_guard<std::mutex> lock(logger_map_mutex_);
159        for (auto &l : loggers_)
160        {
161            l.second->set_error_handler(handler);
162        }
163        err_handler_ = handler;
164    }
165
166    void apply_all(const std::function<void(const std::shared_ptr<logger>)> &fun)
167    {
168        std::lock_guard<std::mutex> lock(logger_map_mutex_);
169        for (auto &l : loggers_)
170        {
171            fun(l.second);
172        }
173    }
174
175    void flush_all()
176    {
177        std::lock_guard<std::mutex> lock(logger_map_mutex_);
178        for (auto &l : loggers_)
179        {
180            l.second->flush();
181        }
182    }
183
184    void drop(const std::string &logger_name)
185    {
186        std::lock_guard<std::mutex> lock(logger_map_mutex_);
187        loggers_.erase(logger_name);
188        if (default_logger_ && default_logger_->name() == logger_name)
189        {
190            default_logger_.reset();
191        }
192    }
193
194    void drop_all()
195    {
196        std::lock_guard<std::mutex> lock(logger_map_mutex_);
197        loggers_.clear();
198        default_logger_.reset();
199    }
200
201    // clean all resources and threads started by the registry
202    void shutdown()
203    {
204        {
205            std::lock_guard<std::mutex> lock(flusher_mutex_);
206            periodic_flusher_.reset();
207        }
208
209        drop_all();
210
211        {
212            std::lock_guard<std::recursive_mutex> lock(tp_mutex_);
213            tp_.reset();
214        }
215    }
216
217    std::recursive_mutex &tp_mutex()
218    {
219        return tp_mutex_;
220    }
221
222    void set_automatic_registration(bool automatic_regsistration)
223    {
224        std::lock_guard<std::mutex> lock(logger_map_mutex_);
225        automatic_registration_ = automatic_regsistration;
226    }
227
228    static registry &instance()
229    {
230        static registry s_instance;
231        return s_instance;
232    }
233
234private:
235    registry()
236        : formatter_(new pattern_formatter())
237    {
238
239#ifndef SPDLOG_DISABLE_DEFAULT_LOGGER
240        // create default logger (ansicolor_stdout_sink_mt or wincolor_stdout_sink_mt in windows).
241#ifdef _WIN32
242        auto color_sink = std::make_shared<sinks::wincolor_stdout_sink_mt>();
243#else
244        auto color_sink = std::make_shared<sinks::ansicolor_stdout_sink_mt>();
245#endif
246
247        const char *default_logger_name = "";
248        default_logger_ = std::make_shared<spdlog::logger>(default_logger_name, std::move(color_sink));
249        loggers_[default_logger_name] = default_logger_;
250
251#endif // SPDLOG_DISABLE_DEFAULT_LOGGER
252    }
253
254    ~registry() = default;
255
256    void throw_if_exists_(const std::string &logger_name)
257    {
258        if (loggers_.find(logger_name) != loggers_.end())
259        {
260            throw spdlog_ex("logger with name '" + logger_name + "' already exists");
261        }
262    }
263
264    void register_logger_(std::shared_ptr<logger> new_logger)
265    {
266        auto logger_name = new_logger->name();
267        throw_if_exists_(logger_name);
268        loggers_[logger_name] = std::move(new_logger);
269    }
270
271    std::mutex logger_map_mutex_, flusher_mutex_;
272    std::recursive_mutex tp_mutex_;
273    std::unordered_map<std::string, std::shared_ptr<logger>> loggers_;
274    std::unique_ptr<formatter> formatter_;
275    level::level_enum level_ = spdlog::logger::default_level();
276    level::level_enum flush_level_ = level::off;
277    log_err_handler err_handler_;
278    std::shared_ptr<thread_pool> tp_;
279    std::unique_ptr<periodic_worker> periodic_flusher_;
280    std::shared_ptr<logger> default_logger_;
281    bool automatic_registration_ = true;
282};
283
284} // namespace details
285} // namespace spdlog
Note: See TracBrowser for help on using the repository browser.