MySQL 8.0.30
Source Code Documentation
registry.h
Go to the documentation of this file.
1/*
2 Copyright (c) 2016, 2022, Oracle and/or its affiliates.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License, version 2.0,
6 as published by the Free Software Foundation.
7
8 This program is also distributed with certain software (including
9 but not limited to OpenSSL) that is licensed under separate terms,
10 as designated in a particular file or component or in included license
11 documentation. The authors of MySQL hereby grant you an additional
12 permission to link the program and your derivative works with the
13 separately licensed software that they have included with MySQL.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23*/
24
25#ifndef MYSQL_HARNESS_LOGGER_REGISTRY_INCLUDED
26#define MYSQL_HARNESS_LOGGER_REGISTRY_INCLUDED
27
28#include "harness_export.h"
33
34#include <atomic>
35#include <map>
36#include <mutex>
37#include <stdexcept>
38#include <string>
39
40namespace mysql_harness {
41
42namespace logging {
43
44class Handler;
45
46class HARNESS_EXPORT Registry {
47 public:
48 const static std::map<std::string, LogLevel> kLogLevels;
49 const static std::map<std::string, LogTimestampPrecision>
51
52 Registry() = default;
53 Registry(const Registry &) = delete;
54 Registry &operator=(const Registry &) = delete;
55
56 ~Registry() = default;
57
58 //----[ logger CRUD
59 //]-----------------------------------------------------------
60
61 /**
62 * Create a logger in the internal registry
63 *
64 * @param name Logger id (log domain it services)
65 * @param level Log level for logger
66 *
67 * @throws std::logic_error if there is a logger already registered with given
68 * module name
69 */
70 void create_logger(const std::string &name,
72
73 /**
74 * Remove a named logger from the internal registry
75 *
76 * @param name Logger id (log domain it services)
77 *
78 * @throws std::logic_error if there is no logger registered with given
79 * module name
80 */
81 void remove_logger(const std::string &name);
82
83 /**
84 * Return logger for particular module
85 *
86 * The reason why this function returns by value is thread-safety.
87 *
88 * @param name Logger id (log domain it services)
89 *
90 * @throws std::logic_error if no logger is registered for given module name
91 */
92 Logger get_logger(const std::string &name) const;
93
94 /**
95 * Return logger for particular module.
96 *
97 * if it doesn't exist, get the default logger.
98 *
99 * @param name Logger id (log domain it services)
100 * @param default_name name of the default logger
101 *
102 * @throws std::logic_error if neither logger is registered for given module
103 * name
104 */
105 Logger get_logger_or_default(const std::string &name,
106 const std::string &default_name) const;
107
108 /**
109 * Update logger for particular module
110 *
111 * This function provides a thread-safe way of updating the Logger object in
112 * the registry.
113 *
114 * @param name Logger id (log domain it services)
115 * @param logger Logger object
116 *
117 * @throws std::logic_error if no logger is registered for given module name
118 */
119 void update_logger(const std::string &name, const Logger &logger);
120
121 /**
122 * Get the logger names (id's) from the internal registry
123 */
124 std::set<std::string> get_logger_names() const;
125
126 //----[ handler CRUD
127 //]----------------------------------------------------------
128
129 /**
130 * Add a handler to the internal registry
131 *
132 * @param name Handler id
133 * @param handler Shared pointer to handler
134 *
135 * @throws std::logic_error if there is a handler already registered with
136 * given module name
137 */
138 void add_handler(std::string name, std::shared_ptr<Handler> handler);
139
140 /**
141 * Remove handler from the internal registry
142 *
143 * @param name Handler id
144 *
145 * @throws std::logic_error if no handler is registered for given name
146 */
147 void remove_handler(std::string name);
148
149 /**
150 * Return handler in the internal registry
151 *
152 * @param name Handler id
153 *
154 * @throws std::logic_error if no handler is registered for given name
155 */
156 std::shared_ptr<Handler> get_handler(const std::string &name) const;
157
158 /**
159 * Get the handler names from the internal registry
160 */
161 std::set<std::string> get_handler_names() const;
162
163 /**
164 * Check if a log-level is handled by at least one handler.
165 *
166 * @returns if at least one handler handles the log-level
167 * @retval true at least one handler
168 * @retval false log-level will be ignored.
169 */
170 bool is_handled(LogLevel level) const;
171
172 /**
173 * Flag that the registry has been initialized
174 *
175 * This method should be called after log initialization is complete to
176 * flag that logging facility is now available. Note that this is a
177 * convenience flag - it does not directly affect the operation of Registry.
178 * However, a logging function (i.e. log_message()) might want to query
179 * this flag when called and do whatever it deems appropriate.
180 */
181 void set_ready() noexcept { ready_ = true; }
182
183 /**
184 * Query if logging facility is ready to use
185 *
186 * The exact meaning of this flag is not defined here, see description in
187 * set_ready()
188 */
189 bool is_ready() const noexcept { return ready_; }
190
191 /**
192 * Force the flush (reopen) on all registered logger handlers, while moving
193 * old logger file to dst.
194 * @param dst destination filename for old log
195 */
196 void flush_all_loggers(const std::string dst = "");
197
198 private:
199 mutable std::mutex mtx_;
200 std::map<std::string, Logger> loggers_; // key = log domain
201 std::map<std::string, std::shared_ptr<Handler>>
202 handlers_; // key = handler id
203 std::atomic<bool> ready_{false};
204
205}; // class Registry
206
207////////////////////////////////////////////////////////////////////////////////
208//
209// high-level utility functions
210//
211////////////////////////////////////////////////////////////////////////////////
212/**
213 * Converts string with log level description to LogLevel type
214 *
215 * @param name string with log level description
216 *
217 * @throws std::invalid_argument if log level string is invalid
218 */
219HARNESS_EXPORT
221
222/**
223 * Get default log level
224 *
225 * Fetches default log level set in the configuration file
226 *
227 * @param config Configuration items from configuration file
228 * @param raw_mode true if the default level should be for the raw mode, false
229 * otherwise
230 *
231 * @throws std::invalid_argument if [logger].level in configuration is invalid
232 */
233HARNESS_EXPORT
234LogLevel get_default_log_level(const Config &config, bool raw_mode = false);
235
236/**
237 * Get default log filename
238 *
239 * Fetches default log filename set in the configuration file
240 *
241 * @param config Configuration items from configuration file
242 */
243HARNESS_EXPORT
244std::string get_default_log_filename(const Config &config);
245
246/**
247 * Attach handler to all loggers
248 *
249 * @param registry Registry object, typically managed by DIM
250 * @param name Logger id (log domain it services)
251 */
252HARNESS_EXPORT
253void attach_handler_to_all_loggers(Registry &registry, std::string name);
254
255/**
256 * Set log levels for all the loggers to specified value
257 *
258 * @param registry Registry object, typically managed by DIM
259 * @param level Log level for logger
260 */
261HARNESS_EXPORT
262void set_log_level_for_all_loggers(Registry &registry, LogLevel level);
263
264/**
265 * Set log levels for all handlers to specified value
266 *
267 * @param registry Registry object, typically managed by DIM
268 * @param level Log level for logger
269 */
270HARNESS_EXPORT
271void set_log_level_for_all_handlers(const Registry &registry, LogLevel level);
272
273/**
274 * Converts string with log timestamp precision description to
275 * LogTimestampPrecision type.
276 *
277 * @param name string with log timestamp precision description
278 *
279 * @throws std::invalid_argument if log timestamp precision string is invalid
280 */
281HARNESS_EXPORT
283
284/**
285 * Get default timestamp precision
286 *
287 * Fetches default timestamp precision for logfiles
288 *
289 * @param config Configuration items from configuration file
290 */
291HARNESS_EXPORT
293
294/**
295 * Set timestamp precision for all the loggers
296 *
297 * @param registry Registry object, typically managed by DIM
298 * @param precision Precision of timestamps
299 */
300HARNESS_EXPORT
301void set_timestamp_precision_for_all_loggers(Registry &registry,
302 LogTimestampPrecision precision);
303
304/**
305 * Clear registry
306 *
307 * Removes all Loggers and removes all references to Handlers (they're held
308 * as shared pointers, which may mean they will also be deleted)
309 *
310 * @param registry Registry object, typically managed by DIM
311 */
312HARNESS_EXPORT
313void clear_registry(Registry &registry);
314
315/**
316 * Initialize logging facility
317 *
318 * Initializes logging facility by creating and registering a logger for each
319 * given module. Loggers will have their log level set to the log level passed
320 * as a parameter.
321 *
322 * @note Loggers will not have any handlers attached, this needs to be done
323 * separately (see `create_main_log_handler()`)
324 *
325 * @param registry Registry object, typically managed by DIM
326 * @param level The log level of the logger
327 * @param modules List of plugin names loaded
328 * @param main_app_log_domain Log domain (logger id) to be used as the main
329 * program logger. This logger must exist, because
330 * log_*() functions might fail
331 * @throws std::logic_error
332 */
333HARNESS_EXPORT
334void create_module_loggers(Registry &registry, const LogLevel level,
335 const std::list<std::string> &modules,
336 const std::string &main_app_log_domain);
337
338/*
339 * Creates a logger and registers it in the Registry.
340 *
341 * Register a logger for a given name and given log level.
342 *
343 * @param registry Registry object, typically managed by DIM
344 * @param log_level The log level of the logger
345 * @param logger_name The name under which the logger is registered
346 *
347 * @throws std::logic_error
348 */
349HARNESS_EXPORT
350void create_logger(Registry &registry, const LogLevel level,
351 const std::string &logger_name);
352
353/**
354 * Initialize logfile handler
355 *
356 * Initializes handler which will handle application's log. This handler
357 * will be attached to all currently-registered loggers.
358 * If `logging_folder` is provided, handler will log messages to logfile; its
359 * path and filename will be derived from `program` and `logging_folder`
360 * parameters.
361 * If `logging_folder` is empty, handler will log messages to console, unless
362 * `use_os_log` is set to true, in which case it will log to system logger
363 * instead (i.e. Syslog, Windows Eventlog, etc. Currently, only Windows
364 * Eventlog is supported).
365 *
366 * @param registry Registry object, typically managed by DIM
367 * @param program Name of the main program (Router)
368 * @param logging_folder logging_folder provided in configuration file
369 * @param format_messages If set to true, log messages will be formatted
370 * (prefixed with log level, timestamp, etc) before logging
371 * @param use_os_log If true, use system logger instead of STDERR (currently,
372 * only Windows Eventlog is supported)
373 *
374 * @throws std::runtime_error if opening log file or OS log fails
375 */
376HARNESS_EXPORT
377void create_main_log_handler(Registry &registry, const std::string &program,
378 const std::string &logging_folder,
379 bool format_messages, bool use_os_log = false);
380
381////////////////////////////////////////////////////////////////////////////////
382//
383// These functions are simple proxies that can be used by logger plugins
384// to register their logging services. Note that they can only be called after
385// logging facility has been initialized; but by the time the plugins are
386// loaded, logging facility is already operational, so this is fine for plugin
387// use.
388//
389////////////////////////////////////////////////////////////////////////////////
390
391/** Set log level for all registered loggers. */
392HARNESS_EXPORT
394
395/** Set log level for all registered handlers. */
396HARNESS_EXPORT
398
399/** Set timestamp precision for all registered loggers. */
400HARNESS_EXPORT
402
403/**
404 * Register handler for all plugins.
405 *
406 * This will register a handler for all plugins that have been
407 * registered with the logging subsystem (normally all plugins that
408 * have been loaded by `Loader`).
409 *
410 * @param name The name under which handler is registered
411 * @param handler Shared pointer to dynamically allocated handler.
412 *
413 * For example, to register a custom handler from a plugin, you would
414 * do the following:
415 *
416 * @code
417 * void init() {
418 * ...
419 * register_handler(std::make_shared<MyHandler>(...));
420 * ...
421 * }
422 * @endcode
423 */
424HARNESS_EXPORT
425void register_handler(std::string name, std::shared_ptr<Handler> handler);
426
427/**
428 * Unregister a handler.
429 *
430 * This will unregister a previously registered handler.
431 *
432 * @param name name of registered handler.
433 */
434HARNESS_EXPORT
435void unregister_handler(std::string name);
436
437/**
438 * Returns pointer to the default logger sink stream.
439 */
440HARNESS_EXPORT
441std::ostream *get_default_logger_stream();
442
443} // namespace logging
444
445} // namespace mysql_harness
446
447#endif /* MYSQL_HARNESS_LOGGER_REGISTRY_INCLUDED */
The handler class is the interface for dynamically loadable storage engines.
Definition: handler.h:4290
Configuration.
Definition: config_parser.h:252
Logger class.
Definition: logger.h:48
Definition: registry.h:46
bool is_ready() const noexcept
Query if logging facility is ready to use.
Definition: registry.h:189
Registry(const Registry &)=delete
void set_ready() noexcept
Flag that the registry has been initialized.
Definition: registry.h:181
static const std::map< std::string, LogLevel > kLogLevels
Definition: registry.h:48
std::mutex mtx_
Definition: registry.h:199
std::map< std::string, Logger > loggers_
Definition: registry.h:200
static const std::map< std::string, LogTimestampPrecision > kLogTimestampPrecisions
Definition: registry.h:50
Registry & operator=(const Registry &)=delete
std::map< std::string, std::shared_ptr< Handler > > handlers_
Definition: registry.h:202
Logging interface for using and extending the logging subsystem.
HARNESS_EXPORT LogTimestampPrecision log_timestamp_precision_from_string(std::string name)
Converts string with log timestamp precision description to LogTimestampPrecision type.
Definition: registry.cc:402
HARNESS_EXPORT void set_log_level_for_all_handlers(const Registry &registry, LogLevel level)
Set log levels for all handlers to specified value.
Definition: registry.cc:248
HARNESS_EXPORT LogLevel log_level_from_string(std::string name)
Converts string with log level description to LogLevel type.
Definition: registry.cc:340
LogLevel
Log level values.
Definition: logging.h:95
HARNESS_EXPORT void set_timestamp_precision_for_all_loggers(Registry &registry, LogTimestampPrecision precision)
Set timestamp precision for all the loggers.
Definition: registry.cc:255
HARNESS_EXPORT void register_handler(std::string name, std::shared_ptr< Handler > handler)
Register handler for all plugins.
Definition: registry.cc:453
HARNESS_EXPORT std::string get_default_log_filename(const Config &config)
Get default log filename.
Definition: registry.cc:380
HARNESS_EXPORT void clear_registry(Registry &registry)
Clear registry.
Definition: registry.cc:264
HARNESS_EXPORT LogLevel get_default_log_level(const Config &config, bool raw_mode=false)
Get default log level.
Definition: registry.cc:360
HARNESS_EXPORT void create_logger(Registry &registry, const LogLevel level, const std::string &logger_name)
Definition: registry.cc:322
HARNESS_EXPORT void create_main_log_handler(Registry &registry, const std::string &program, const std::string &logging_folder, bool format_messages, bool use_os_log=false)
Initialize logfile handler.
Definition: registry.cc:276
HARNESS_EXPORT void set_log_level_for_all_loggers(Registry &registry, LogLevel level)
Set log levels for all the loggers to specified value.
Definition: registry.cc:240
HARNESS_EXPORT void unregister_handler(std::string name)
Unregister a handler.
Definition: registry.cc:460
HARNESS_EXPORT LogTimestampPrecision get_default_timestamp_precision(const Config &config)
Get default timestamp precision.
Definition: registry.cc:423
HARNESS_EXPORT std::ostream * get_default_logger_stream()
Returns pointer to the default logger sink stream.
Definition: registry.cc:274
LogTimestampPrecision
Log timestamp precision values.
Definition: logging.h:160
HARNESS_EXPORT void create_module_loggers(Registry &registry, const LogLevel level, const std::list< std::string > &modules, const std::string &main_app_log_domain)
Initialize logging facility.
Definition: registry.cc:327
HARNESS_EXPORT void set_timestamp_precison_for_all_loggers(LogTimestampPrecision precision)
Set timestamp precision for all registered loggers.
HARNESS_EXPORT void attach_handler_to_all_loggers(Registry &registry, std::string name)
Attach handler to all loggers.
Definition: registry.cc:230
Definition: common.h:41
static Logger logger
The "top-level" logger used when no connection context is given.
Definition: test_trace_plugin.cc:295
case opt name
Definition: sslopt-case.h:32