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