MySQL 8.0.37
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 * Get default log level
221 *
222 * Fetches default log level set in the configuration file
223 *
224 * @param config Configuration items from configuration file
225 * @param raw_mode true if the default level should be for the raw mode, false
226 * otherwise
227 *
228 * @throws std::invalid_argument if [logger].level in configuration is invalid
229 */
230HARNESS_EXPORT
231LogLevel get_default_log_level(const Config &config, bool raw_mode = false);
232
233/**
234 * Get default log filename
235 *
236 * Fetches default log filename set in the configuration file
237 *
238 * @param config Configuration items from configuration file
239 */
240HARNESS_EXPORT
241std::string get_default_log_filename(const Config &config);
242
243/**
244 * Attach handler to all loggers
245 *
246 * @param registry Registry object, typically managed by DIM
247 * @param name Logger id (log domain it services)
248 */
249HARNESS_EXPORT
250void attach_handler_to_all_loggers(Registry &registry, std::string name);
251
252/**
253 * Set log levels for all the loggers to specified value
254 *
255 * @param registry Registry object, typically managed by DIM
256 * @param level Log level for logger
257 */
258HARNESS_EXPORT
259void set_log_level_for_all_loggers(Registry &registry, LogLevel level);
260
261/**
262 * Set log levels for all handlers to specified value
263 *
264 * @param registry Registry object, typically managed by DIM
265 * @param level Log level for logger
266 */
267HARNESS_EXPORT
268void set_log_level_for_all_handlers(const Registry &registry, LogLevel level);
269
270/**
271 * Converts string with log timestamp precision description to
272 * LogTimestampPrecision type.
273 *
274 * @param name string with log timestamp precision description
275 *
276 * @throws std::invalid_argument if log timestamp precision string is invalid
277 */
278HARNESS_EXPORT
280
281/**
282 * Get default timestamp precision
283 *
284 * Fetches default timestamp precision for logfiles
285 *
286 * @param config Configuration items from configuration file
287 */
288HARNESS_EXPORT
290
291/**
292 * Set timestamp precision for all the loggers
293 *
294 * @param registry Registry object, typically managed by DIM
295 * @param precision Precision of timestamps
296 */
297HARNESS_EXPORT
298void set_timestamp_precision_for_all_loggers(Registry &registry,
299 LogTimestampPrecision precision);
300
301/**
302 * Clear registry
303 *
304 * Removes all Loggers and removes all references to Handlers (they're held
305 * as shared pointers, which may mean they will also be deleted)
306 *
307 * @param registry Registry object, typically managed by DIM
308 */
309HARNESS_EXPORT
310void clear_registry(Registry &registry);
311
312/**
313 * Initialize logging facility
314 *
315 * Initializes logging facility by creating and registering a logger for each
316 * given module. Loggers will have their log level set to the log level passed
317 * as a parameter.
318 *
319 * @note Loggers will not have any handlers attached, this needs to be done
320 * separately (see `create_main_log_handler()`)
321 *
322 * @param registry Registry object, typically managed by DIM
323 * @param level The log level of the logger
324 * @param modules List of plugin names loaded
325 * @param main_app_log_domain Log domain (logger id) to be used as the main
326 * program logger. This logger must exist, because
327 * log_*() functions might fail
328 * @throws std::logic_error
329 */
330HARNESS_EXPORT
331void create_module_loggers(Registry &registry, const LogLevel level,
332 const std::list<std::string> &modules,
333 const std::string &main_app_log_domain);
334
335/*
336 * Creates a logger and registers it in the Registry.
337 *
338 * Register a logger for a given name and given log level.
339 *
340 * @param registry Registry object, typically managed by DIM
341 * @param log_level The log level of the logger
342 * @param logger_name The name under which the logger is registered
343 *
344 * @throws std::logic_error
345 */
346HARNESS_EXPORT
347void create_logger(Registry &registry, const LogLevel level,
348 const std::string &logger_name);
349
350/**
351 * Initialize logfile handler
352 *
353 * Initializes handler which will handle application's log. This handler
354 * will be attached to all currently-registered loggers.
355 * If `logging_folder` is provided, handler will log messages to logfile; its
356 * path and filename will be derived from `program` and `logging_folder`
357 * parameters.
358 * If `logging_folder` is empty, handler will log messages to console, unless
359 * `use_os_log` is set to true, in which case it will log to system logger
360 * instead (i.e. Syslog, Windows Eventlog, etc. Currently, only Windows
361 * Eventlog is supported).
362 *
363 * @param registry Registry object, typically managed by DIM
364 * @param program Name of the main program (Router)
365 * @param logging_folder logging_folder provided in configuration file
366 * @param format_messages If set to true, log messages will be formatted
367 * (prefixed with log level, timestamp, etc) before logging
368 * @param use_os_log If true, use system logger instead of STDERR (currently,
369 * only Windows Eventlog is supported)
370 *
371 * @throws std::runtime_error if opening log file or OS log fails
372 */
373HARNESS_EXPORT
374void create_main_log_handler(Registry &registry, const std::string &program,
375 const std::string &logging_folder,
376 bool format_messages, bool use_os_log = false);
377
378////////////////////////////////////////////////////////////////////////////////
379//
380// These functions are simple proxies that can be used by logger plugins
381// to register their logging services. Note that they can only be called after
382// logging facility has been initialized; but by the time the plugins are
383// loaded, logging facility is already operational, so this is fine for plugin
384// use.
385//
386////////////////////////////////////////////////////////////////////////////////
387
388/** Set log level for all registered loggers. */
389HARNESS_EXPORT
391
392/** Set log level for all registered handlers. */
393HARNESS_EXPORT
395
396/** Set timestamp precision for all registered loggers. */
397HARNESS_EXPORT
399
400/**
401 * Register handler for all plugins.
402 *
403 * This will register a handler for all plugins that have been
404 * registered with the logging subsystem (normally all plugins that
405 * have been loaded by `Loader`).
406 *
407 * @param name The name under which handler is registered
408 * @param handler Shared pointer to dynamically allocated handler.
409 *
410 * For example, to register a custom handler from a plugin, you would
411 * do the following:
412 *
413 * @code
414 * void init() {
415 * ...
416 * register_handler(std::make_shared<MyHandler>(...));
417 * ...
418 * }
419 * @endcode
420 */
421HARNESS_EXPORT
422void register_handler(std::string name, std::shared_ptr<Handler> handler);
423
424/**
425 * Unregister a handler.
426 *
427 * This will unregister a previously registered handler.
428 *
429 * @param name name of registered handler.
430 */
431HARNESS_EXPORT
432void unregister_handler(std::string name);
433
434/**
435 * Returns pointer to the default logger sink stream.
436 */
437HARNESS_EXPORT
438std::ostream *get_default_logger_stream();
439
440} // namespace logging
441
442} // namespace mysql_harness
443
444#endif /* MYSQL_HARNESS_LOGGER_REGISTRY_INCLUDED */
The handler class is the interface for dynamically loadable storage engines.
Definition: handler.h:4413
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.
HARNESS_EXPORT LogTimestampPrecision log_timestamp_precision_from_string(std::string name)
Converts string with log timestamp precision description to LogTimestampPrecision type.
Definition: registry.cc:418
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:260
HARNESS_EXPORT LogLevel log_level_from_string(std::string name)
Converts string with log level description to LogLevel type.
Definition: registry.cc:352
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:267
HARNESS_EXPORT void register_handler(std::string name, std::shared_ptr< Handler > handler)
Register handler for all plugins.
Definition: registry.cc:470
HARNESS_EXPORT std::string get_default_log_filename(const Config &config)
Get default log filename.
Definition: registry.cc:396
HARNESS_EXPORT void clear_registry(Registry &registry)
Clear registry.
Definition: registry.cc:276
HARNESS_EXPORT LogLevel get_default_log_level(const Config &config, bool raw_mode=false)
Get default log level.
Definition: registry.cc:376
HARNESS_EXPORT void create_logger(Registry &registry, const LogLevel level, const std::string &logger_name)
Definition: registry.cc:334
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:288
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:252
HARNESS_EXPORT void unregister_handler(std::string name)
Unregister a handler.
Definition: registry.cc:477
HARNESS_EXPORT LogTimestampPrecision get_default_timestamp_precision(const Config &config)
Get default timestamp precision.
Definition: registry.cc:440
HARNESS_EXPORT std::ostream * get_default_logger_stream()
Returns pointer to the default logger sink stream.
Definition: registry.cc:286
LogTimestampPrecision
Log timestamp precision values.
Definition: logging.h:161
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:339
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:242
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:33