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