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