MySQL 9.1.0
Source Code Documentation
ut0log.h
Go to the documentation of this file.
1/* Copyright (c) 2021, 2024, Oracle and/or its affiliates.
2
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License, version 2.0,
5 as published by the Free Software Foundation.
6
7 This program is designed to work with certain software (including
8 but not limited to OpenSSL) that is licensed under separate terms,
9 as designated in a particular file or component or in included license
10 documentation. The authors of MySQL hereby grant you an additional
11 permission to link the program and your derivative works with the
12 separately licensed software that they have either included with
13 the program or referenced in the documentation.
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, version 2.0, 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/** @file include/ut0log.h Logging facilities. */
26
27#ifndef ut0log_h
28#define ut0log_h
29
31#include "mysql/my_loglevel.h"
32#include "mysqld_error.h"
33#include "ut0core.h"
34
35/** Get the format string for the logger.
36@param[in] errcode The error code from share/errmsg-*.txt
37@return the message string or nullptr */
38const char *srv_get_server_errmsgs(int errcode);
39
40namespace ib {
41
42/** The class logger is the base class of all the error log related classes.
43It contains a std::ostringstream object. The main purpose of this class is
44to forward operator<< to the underlying std::ostringstream object. Do not
45use this class directly, instead use one of the derived classes. */
46class logger {
47 public:
48 /** Destructor */
49 virtual ~logger();
50
51#ifndef UNIV_NO_ERR_MSGS
52
53 /** Format an error message.
54 @param[in] err Error code from errmsg-*.txt.
55 @param[in] args Variable length argument list */
56 template <class... Args>
57 logger &log(int err, Args &&...args) {
58 ut_a(m_err == ER_IB_MSG_0);
59
60 m_err = err;
61
62 m_oss << msg(err, std::forward<Args>(args)...);
63
64 return (*this);
65 }
66
67#endif /* !UNIV_NO_ERR_MSGS */
68
69 template <typename T>
70 logger &operator<<(const T &rhs) {
71 m_oss << rhs;
72 return (*this);
73 }
74
75 /** Write the given buffer to the internal string stream object.
76 @param[in] buf the buffer contents to log.
77 @param[in] count the length of the buffer buf.
78 @return the output stream into which buffer was written. */
79 std::ostream &write(const char *buf, std::streamsize count) {
80 return (m_oss.write(buf, count));
81 }
82
83 /** Write the given buffer to the internal string stream object.
84 @param[in] buf the buffer contents to log
85 @param[in] count the length of the buffer buf.
86 @return the output stream into which buffer was written. */
87 std::ostream &write(const unsigned char *buf, std::streamsize count) {
88 return (m_oss.write(reinterpret_cast<const char *>(buf), count));
89 }
90
91 public:
92 /** For converting the message into a string. */
94
95#ifndef UNIV_NO_ERR_MSGS
96 /** Error code in errmsg-*.txt */
97 int m_err{};
98
99 /** Error logging level. */
101#endif /* !UNIV_NO_ERR_MSGS */
102
103#ifdef UNIV_HOTBACKUP
104 /** For MEB trace infrastructure. */
105 int m_trace_level{};
106#endif /* UNIV_HOTBACKUP */
107
108 protected:
109#ifndef UNIV_NO_ERR_MSGS
110 /** Format an error message.
111 @param[in] err Error code from errmsg-*.txt.
112 @param[in] args Variable length argument list */
113 template <class... Args>
114 static std::string msg(int err, Args &&...args) {
115 const char *fmt = srv_get_server_errmsgs(err);
116
117 int ret;
118 char buf[LOG_BUFF_MAX];
119#ifdef UNIV_DEBUG
120 if (get_first_format(fmt) != nullptr) {
121 if (!verify_fmt_match(fmt, std::forward<Args>(args)...)) {
122 fprintf(stderr, "The format '%s' does not match arguments\n", fmt);
123 ut_error;
124 }
125 }
126#endif
127 ret = snprintf(buf, sizeof(buf), fmt, std::forward<Args>(args)...);
128
129 std::string str;
130
131 if (ret > 0 && (size_t)ret < sizeof(buf)) {
132 str.append(buf);
133 }
134
135 return (str);
136 }
137
138 protected:
139 /** Uses LogEvent to report the log entry, using provided message
140 @param[in] msg message to be logged
141 */
142 void log_event(std::string msg);
143
144 /** Constructor.
145 @param[in] level Logging level
146 @param[in] err Error message code. */
147 logger(loglevel level, int err) : m_err(err), m_level(level) {
148 /* Note: Dummy argument to avoid the warning:
149
150 "format not a string literal and no format arguments"
151 "[-Wformat-security]"
152
153 The warning only kicks in if the call is of the form:
154
155 snprintf(buf, sizeof(buf), str);
156 */
157
158 m_oss << msg(err, "");
159 }
160
161 /** Constructor.
162 @param[in] level Logging level
163 @param[in] err Error message code.
164 @param[in] args Variable length argument list */
165 template <class... Args>
166 explicit logger(loglevel level, int err, Args &&...args)
167 : m_err(err), m_level(level) {
168 m_oss << msg(err, std::forward<Args>(args)...);
169 }
170
171 /** Constructor
172 @param[in] level Log error level */
173 explicit logger(loglevel level) : m_err(ER_IB_MSG_0), m_level(level) {}
174
175#endif /* !UNIV_NO_ERR_MSGS */
176};
177
178/** The class info is used to emit informational log messages. It is to be
179used similar to std::cout. But the log messages will be emitted only when
180the dtor is called. The preferred usage of this class is to make use of
181unnamed temporaries as follows:
182
183info() << "The server started successfully.";
184
185In the above usage, the temporary object will be destroyed at the end of the
186statement and hence the log message will be emitted at the end of the
187statement. If a named object is created, then the log message will be emitted
188only when it goes out of scope or destroyed. */
189class info : public logger {
190 public:
191#ifndef UNIV_NO_ERR_MSGS
192
193 /** Default constructor uses ER_IB_MSG_0 */
195
196 /** Constructor.
197 @param[in] err Error code from errmsg-*.txt.
198 @param[in] args Variable length argument list */
199 template <class... Args>
200 explicit info(int err, Args &&...args)
201 : logger(INFORMATION_LEVEL, err, std::forward<Args>(args)...) {}
202#else
203 /** Destructor */
204 ~info() override;
205#endif /* !UNIV_NO_ERR_MSGS */
206};
207
208/** The class warn is used to emit warnings. Refer to the documentation of
209class info for further details. */
210class warn : public logger {
211 public:
212#ifndef UNIV_NO_ERR_MSGS
213 /** Default constructor uses ER_IB_MSG_0 */
215
216 /** Constructor.
217 @param[in] err Error code from errmsg-*.txt.
218 @param[in] args Variable length argument list */
219 template <class... Args>
220 explicit warn(int err, Args &&...args)
221 : logger(WARNING_LEVEL, err, std::forward<Args>(args)...) {}
222
223#else
224 /** Destructor */
225 ~warn() override;
226#endif /* !UNIV_NO_ERR_MSGS */
227};
228
229/** The class error is used to emit error messages. Refer to the
230documentation of class info for further details. */
231class error : public logger {
232 public:
233#ifndef UNIV_NO_ERR_MSGS
234 /** Default constructor uses ER_IB_MSG_0 */
236
237 /** Constructor.
238 @param[in] err Error code from errmsg-*.txt.
239 @param[in] args Variable length argument list */
240 template <class... Args>
241 explicit error(int err, Args &&...args)
242 : logger(ERROR_LEVEL, err, std::forward<Args>(args)...) {}
243
244#else
245 /** Destructor */
246 ~error() override;
247#endif /* !UNIV_NO_ERR_MSGS */
248};
249
250/** The class fatal is used to emit an error message and stop the server
251by crashing it. Use this class when MySQL server needs to be stopped
252immediately. Refer to the documentation of class info for usage details. */
253class fatal : public logger {
254 public:
255#ifndef UNIV_NO_ERR_MSGS
256 /** Default constructor uses ER_IB_MSG_0
257 @param[in] location Location that creates the fatal message.
258*/
259 fatal(ut::Location location) : logger(ERROR_LEVEL), m_location(location) {}
260
261 /** Constructor.
262 @param[in] location Location that creates the fatal message.
263 @param[in] err Error code from errmsg-*.txt.
264 @param[in] args Variable length argument list */
265 template <class... Args>
266 explicit fatal(ut::Location location, int err, Args &&...args)
267 : logger(ERROR_LEVEL, err, std::forward<Args>(args)...),
268 m_location(location) {}
269#else
270 /** Constructor
271 @param[in] location Location that creates the fatal message.
272 */
273 fatal(ut::Location location) : m_location(location) {}
274#endif /* !UNIV_NO_ERR_MSGS */
275
276 /** Destructor. */
277 ~fatal() override;
278
279 private:
280 /** Location of the original caller to report to assertion failure */
282};
283
284/** Emit an error message if the given predicate is true, otherwise emit a
285warning message */
286class error_or_warn : public logger {
287 public:
288#ifndef UNIV_NO_ERR_MSGS
289
290 /** Default constructor uses ER_IB_MSG_0
291 @param[in] pred True if it's a warning. */
293
294 /** Constructor.
295 @param[in] pred True if it's a warning.
296 @param[in] err Error code from errmsg-*.txt.
297 @param[in] args Variable length argument list */
298 template <class... Args>
299 explicit error_or_warn(bool pred, int err, Args &&...args)
301 std::forward<Args>(args)...) {}
302
303#endif /* !UNIV_NO_ERR_MSGS */
304};
305
306/** Emit a fatal message if the given predicate is true, otherwise emit a
307error message. */
308class fatal_or_error : public logger {
309 public:
310#ifndef UNIV_NO_ERR_MSGS
311 /** Default constructor uses ER_IB_MSG_0
312 @param[in] fatal true if it's a fatal message
313 @param[in] location Location that creates the fatal */
315 : logger(ERROR_LEVEL), m_fatal(fatal), m_location(location) {}
316
317 /** Constructor.
318 @param[in] fatal true if it's a fatal message
319 @param[in] location Location that creates the fatal
320 @param[in] err Error code from errmsg-*.txt.
321 @param[in] args Variable length argument list */
322 template <class... Args>
323 explicit fatal_or_error(bool fatal, ut::Location location, int err,
324 Args &&...args)
325 : logger(ERROR_LEVEL, err, std::forward<Args>(args)...),
326 m_fatal(fatal),
327 m_location(location) {}
328
329 /** Destructor */
330 ~fatal_or_error() override;
331#else
332 /** Constructor
333 @param[in] location Location that creates the fatal */
334 fatal_or_error(bool fatal, ut::Location location)
335 : m_fatal(fatal), m_location(location) {}
336
337 /** Destructor */
338 ~fatal_or_error() override;
339
340#endif /* !UNIV_NO_ERR_MSGS */
341 private:
342 /** If true then assert after printing an error message. */
343 const bool m_fatal;
344 /** Location of the original caller to report to assertion failure */
346};
347
348#ifdef UNIV_HOTBACKUP
349/** The class trace is used to emit informational log messages. only when
350trace level is set in the MEB code */
351class trace_1 : public logger {
352 public:
353#ifndef UNIV_NO_ERR_MSGS
354 /** Default constructor uses ER_IB_MSG_0 */
355 trace_1() : logger(INFORMATION_LEVEL) { m_trace_level = 1; }
356
357 /** Constructor.
358 @param[in] err Error code from errmsg-*.txt.
359 @param[in] args Variable length argument list */
360 template <class... Args>
361 explicit trace_1(int err, Args &&...args)
362 : logger(INFORMATION_LEVEL, err, std::forward<Args>(args)...) {
363 m_trace_level = 1;
364 }
365
366#else
367 /** Constructor */
368 trace_1();
369#endif /* !UNIV_NO_ERR_MSGS */
370};
371
372/** The class trace_2 is used to emit informational log messages only when
373trace level 2 is set in the MEB code */
374class trace_2 : public logger {
375 public:
376#ifndef UNIV_NO_ERR_MSGS
377 /** Default constructor uses ER_IB_MSG_0 */
378 trace_2() : logger(INFORMATION_LEVEL) { m_trace_level = 2; }
379
380 /** Constructor.
381 @param[in] err Error code from errmsg-*.txt.
382 @param[in] args Variable length argument list */
383 template <class... Args>
384 explicit trace_2(int err, Args &&...args)
385 : logger(INFORMATION_LEVEL, err, std::forward<Args>(args)...) {
386 m_trace_level = 2;
387 }
388#else
389 /** Destructor. */
390 trace_2();
391#endif /* !UNIV_NO_ERR_MSGS */
392};
393
394/** The class trace_3 is used to emit informational log messages only when
395trace level 3 is set in the MEB code */
396class trace_3 : public logger {
397 public:
398#ifndef UNIV_NO_ERR_MSGS
399 /** Default constructor uses ER_IB_MSG_0 */
400 trace_3() : logger(INFORMATION_LEVEL) { m_trace_level = 3; }
401
402 /** Constructor.
403 @param[in] err Error code from errmsg-*.txt.
404 @param[in] args Variable length argument list */
405 template <class... Args>
406 explicit trace_3(int err, Args &&...args)
407 : logger(INFORMATION_LEVEL, err, std::forward<Args>(args)...) {
408 m_trace_level = 3;
409 }
410
411#else
412 /** Destructor. */
413 trace_3();
414#endif /* !UNIV_NO_ERR_MSGS */
415};
416#endif /* UNIV_HOTBACKUP */
417
418/* Convenience functions that ease the usage of logging facilities throughout
419 the code.
420
421 Logging facilities are designed such so that they differentiate between the
422 case when UNIV_NO_ERR_MSGS is defined and when it is not. In particular, end
423 user code must take into account when code is built with UNIV_NO_ERR_MSGS
424 because not the same set of ib::logger constructors will be available in such
425 setting. Design of the logging facility therefore imposes that every possible
426 usage of it in the end user code will result with sprinkling the #ifdefs all
427 around.
428
429 So, what these convenience wrappers do is that they provide somewhat better
430 alternative to the following code, which without the wrapper look like:
431 #ifdef UNIV_NO_ERR_MSGS
432 ib::info();
433 #else
434 ib::info(ER_IB_MSG_1158);
435 #endif
436 << "Some message";
437
438 Same applies for any other ib:: logging facility, e.g.:
439 #ifdef UNIV_NO_ERR_MSGS
440 ib::fatal(UT_LOCATION_HERE)
441 #else
442 ib::fatal(UT_LOCATION_HERE, ER_IB_MSG_1157)
443 #endif
444 << "Some message";
445
446 With the convenience wrapper these two usages become:
447 log_info(ER_IB_MSG_1158) << "Some message";
448 log_fatal(UT_LOCATION_HERE, ER_IB_MSG_1157) << "Some message";
449*/
450
451static inline auto log_info() { return ib::info(); }
452static inline auto log_warn() { return ib::warn(); }
453static inline auto log_error() { return ib::error(); }
454static inline auto log_fatal(ut::Location location) {
455 return ib::fatal(location);
456}
457static inline auto log_error_or_warn(bool pred) {
458#ifdef UNIV_NO_ERR_MSGS
459 return ib::error_or_warn();
460#else
461 return ib::error_or_warn(pred);
462#endif
463}
464static inline auto log_fatal_or_error(bool fatal, ut::Location location) {
465 return ib::fatal_or_error(fatal, location);
466}
467
468template <typename... Args>
469static inline auto log_info(int err, Args &&...args) {
470#ifdef UNIV_NO_ERR_MSGS
471 return log_info();
472#else
473 return ib::info(err, std::forward<Args>(args)...);
474#endif
475}
476template <typename... Args>
477static inline auto log_warn(int err, Args &&...args) {
478#ifdef UNIV_NO_ERR_MSGS
479 return log_warn();
480#else
481 return ib::warn(err, std::forward<Args>(args)...);
482#endif
483}
484template <typename... Args>
485static inline auto log_error(int err, Args &&...args) {
486#ifdef UNIV_NO_ERR_MSGS
487 return log_error();
488#else
489 return ib::error(err, std::forward<Args>(args)...);
490#endif
491}
492template <typename... Args>
493static inline auto log_fatal(ut::Location location, int err, Args &&...args) {
494#ifdef UNIV_NO_ERR_MSGS
495 return log_fatal(location);
496#else
497 return ib::fatal(location, err, std::forward<Args>(args)...);
498#endif
499}
500template <typename... Args>
501static inline auto log_error_or_warn(bool pred, int err, Args &&...args) {
502#ifdef UNIV_NO_ERR_MSGS
503 return log_error_or_warn(pred);
504#else
505 return ib::error_or_warn(pred, err, std::forward<Args>(args)...);
506#endif
507}
508template <typename... Args>
509static inline auto log_fatal_or_error(bool fatal, ut::Location location,
510 int err, Args &&...args) {
511#ifdef UNIV_NO_ERR_MSGS
512 return log_fatal_or_error(fatal, location);
513#else
514 return ib::fatal_or_error(fatal, location, err, std::forward<Args>(args)...);
515#endif
516}
517
518#ifdef UNIV_HOTBACKUP
519static inline auto log_trace_1() { return ib::trace_1(); }
520static inline auto log_trace_2() { return ib::trace_2(); }
521static inline auto log_trace_3() { return ib::trace_3(); }
522
523template <typename... Args>
524static inline auto log_trace_1(int err, Args &&...args) {
525#ifdef UNIV_NO_ERR_MSGS
526 return log_trace_1();
527#else
528 return ib::trace_1(err, std::forward<Args>(args)...);
529#endif
530}
531template <typename... Args>
532static inline auto log_trace_2(int err, Args &&...args) {
533#ifdef UNIV_NO_ERR_MSGS
534 return log_trace_2();
535#else
536 return ib::trace_2(err, std::forward<Args>(args)...);
537#endif
538}
539template <typename... Args>
540static inline auto log_trace_3(int err, Args &&...args) {
541#ifdef UNIV_NO_ERR_MSGS
542 return log_trace_3();
543#else
544 return ib::trace_3(err, std::forward<Args>(args)...);
545#endif
546}
547#endif /* UNIV_HOTBACKUP */
548
549} // namespace ib
550
551#endif
Emit an error message if the given predicate is true, otherwise emit a warning message.
Definition: ut0log.h:286
error_or_warn(bool pred)
Default constructor uses ER_IB_MSG_0.
Definition: ut0log.h:292
error_or_warn(bool pred, int err, Args &&...args)
Constructor.
Definition: ut0log.h:299
The class error is used to emit error messages.
Definition: ut0log.h:231
error()
Default constructor uses ER_IB_MSG_0.
Definition: ut0log.h:235
error(int err, Args &&...args)
Constructor.
Definition: ut0log.h:241
Emit a fatal message if the given predicate is true, otherwise emit a error message.
Definition: ut0log.h:308
ut::Location m_location
Location of the original caller to report to assertion failure.
Definition: ut0log.h:345
fatal_or_error(bool fatal, ut::Location location)
Default constructor uses ER_IB_MSG_0.
Definition: ut0log.h:314
fatal_or_error(bool fatal, ut::Location location, int err, Args &&...args)
Constructor.
Definition: ut0log.h:323
const bool m_fatal
If true then assert after printing an error message.
Definition: ut0log.h:343
~fatal_or_error() override
Destructor.
Definition: ut0ut.cc:533
The class fatal is used to emit an error message and stop the server by crashing it.
Definition: ut0log.h:253
~fatal() override
Destructor.
Definition: ut0ut.cc:525
fatal(ut::Location location)
Default constructor uses ER_IB_MSG_0.
Definition: ut0log.h:259
ut::Location m_location
Location of the original caller to report to assertion failure.
Definition: ut0log.h:281
fatal(ut::Location location, int err, Args &&...args)
Constructor.
Definition: ut0log.h:266
The class info is used to emit informational log messages.
Definition: ut0log.h:189
info()
Default constructor uses ER_IB_MSG_0.
Definition: ut0log.h:194
info(int err, Args &&...args)
Constructor.
Definition: ut0log.h:200
The class logger is the base class of all the error log related classes.
Definition: ut0log.h:46
std::ostringstream m_oss
For converting the message into a string.
Definition: ut0log.h:93
std::ostream & write(const unsigned char *buf, std::streamsize count)
Write the given buffer to the internal string stream object.
Definition: ut0log.h:87
static std::string msg(int err, Args &&...args)
Format an error message.
Definition: ut0log.h:114
std::ostream & write(const char *buf, std::streamsize count)
Write the given buffer to the internal string stream object.
Definition: ut0log.h:79
void log_event(std::string msg)
Uses LogEvent to report the log entry, using provided message.
Definition: ut0ut.cc:508
logger(loglevel level)
Constructor.
Definition: ut0log.h:173
loglevel m_level
Error logging level.
Definition: ut0log.h:100
virtual ~logger()
Destructor.
Definition: ut0ut.cc:516
logger & log(int err, Args &&...args)
Format an error message.
Definition: ut0log.h:57
logger(loglevel level, int err, Args &&...args)
Constructor.
Definition: ut0log.h:166
int m_err
Error code in errmsg-*.txt.
Definition: ut0log.h:97
logger(loglevel level, int err)
Constructor.
Definition: ut0log.h:147
logger & operator<<(const T &rhs)
Definition: ut0log.h:70
The class warn is used to emit warnings.
Definition: ut0log.h:210
warn(int err, Args &&...args)
Constructor.
Definition: ut0log.h:220
warn()
Default constructor uses ER_IB_MSG_0.
Definition: ut0log.h:214
#define LOG_BUFF_MAX
advisory.
Definition: log_shared.h:233
Definition of the global "loglevel" enumeration.
loglevel
Definition: my_loglevel.h:41
@ WARNING_LEVEL
Definition: my_loglevel.h:44
@ ERROR_LEVEL
Definition: my_loglevel.h:43
@ INFORMATION_LEVEL
Definition: my_loglevel.h:45
static int count
Definition: myisam_ftdump.cc:45
std::string str(const mysqlrouter::ConfigGenerator::Options::Endpoint &ep)
Definition: config_generator.cc:1105
Definition: buf0block_hint.cc:30
Definition: ha_prototypes.h:342
static bool verify_fmt_match(const char *fmt)
Verifies that the fmt format string does not require any arguments.
Definition: ut0core.h:95
static auto log_error_or_warn(bool pred)
Definition: ut0log.h:457
static const char * get_first_format(const char *fmt)
Finds the first format specifier in fmt format string.
Definition: ut0core.h:83
static auto log_fatal(ut::Location location)
Definition: ut0log.h:454
static auto log_fatal_or_error(bool fatal, ut::Location location)
Definition: ut0log.h:464
static auto log_warn()
Definition: ut0log.h:452
static auto log_info()
Definition: ut0log.h:451
static auto log_error()
Definition: ut0log.h:453
static Value err()
Create a Value object that represents an error condition.
Definition: json_binary.cc:908
Definition: gcs_xcom_synode.h:64
static Logger logger
The "top-level" logger used when no connection context is given.
Definition: test_trace_plugin.cc:296
std::basic_ostringstream< char, std::char_traits< char >, ut::allocator< char > > ostringstream
Specialization of basic_ostringstream which uses ut::allocator.
Definition: ut0new.h:2872
Definition: ut0core.h:36
#define ut_error
Abort execution.
Definition: ut0dbg.h:101
#define ut_a(EXPR)
Abort execution if EXPR does not evaluate to nonzero.
Definition: ut0dbg.h:93
const char * srv_get_server_errmsgs(int errcode)
Get the format string for the logger.
Definition: srv0srv.cc:3271