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