MySQL 8.4.0
Source Code Documentation
log_builtins.h
Go to the documentation of this file.
1/* Copyright (c) 2017, 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 This defines built-in functions for use by logging services.
26 These helpers are organized into a number of APIs grouping
27 related functionality.
28
29 For documentation of the individual functions, see log_builtins.cc
30*/
31
32#ifndef LOG_BUILTINS_H
33#define LOG_BUILTINS_H
34
40#if defined(MYSQL_DYNAMIC_PLUGIN)
42#endif
43#include <stdarg.h>
44#include <stdio.h>
45#include <string.h>
46
47#include <my_compiler.h>
48#if defined(MYSQL_SERVER) && !defined(MYSQL_DYNAMIC_PLUGIN)
49#include "sql/log.h"
50#endif
51
52/**
53 typedef for log-processing functions ("buffer this event",
54 "process this event", etc.)
55*/
56typedef bool (*log_line_processor)(log_line *ll);
57
58/**
59 Set the log-event processor.
60
61 When a log-event is submitted, a function is applied to that event.
62 That function usually either buffers the event for later processing,
63 or filters and logs the event.
64
65 That function can be set here.
66
67 @param llp A log-processor
68*/
70
71/**
72 Get current log-event processor.
73
74 When a log-event is submitted, a function is applied to that event.
75 That function usually either buffers the event for later processing,
76 or filters and logs the event.
77 log_line_process_hook_get() returns a pointer to that function.
78
79 @retval a pointer to a log-event processing function
80*/
82
83/**
84 Primitives for services to interact with the structured logger:
85 functions pertaining to log_line and log_item data
86*/
88/**
89 See whether a type is wellknown.
90
91 @param t log item type to examine
92
93 @retval LOG_ITEM_TYPE_NOT_FOUND: key not found
94 @retval >0: index in array of wellknowns
95*/
96DECLARE_METHOD(int, wellknown_by_type, (log_item_type t));
97
98/**
99 See whether a string is a wellknown field name.
100
101 @param key potential key starts here
102 @param length length of the string to examine
103
104 @retval LOG_ITEM_TYPE_RESERVED: reserved, but not "wellknown" key
105 @retval LOG_ITEM_TYPE_NOT_FOUND: key not found
106 @retval >0: index in array of wellknowns
107*/
108DECLARE_METHOD(int, wellknown_by_name, (const char *key, size_t length));
109
110/**
111 Accessor: from a record describing a wellknown key, get its type
112
113 @param idx index in array of wellknowns, see log_item_wellknown_by_...()
114
115 @retval the log item type for the wellknown key
116*/
117DECLARE_METHOD(log_item_type, wellknown_get_type, (uint idx));
118
119/**
120 Accessor: from a record describing a wellknown key, get its name
121
122 @param idx index in array of wellknowns, see log_item_wellknown_by_...()
123
124 @retval name (NTBS)
125*/
126DECLARE_METHOD(const char *, wellknown_get_name, (uint idx));
127
128/**
129 Sanity check an item.
130 Certain log sinks have very low requirements with regard to the data
131 they receive; they write keys as strings, and then data according to
132 the item's class (string, integer, or float), formatted to the sink's
133 standards (e.g. JSON, XML, ...).
134 Code that has higher requirements can use this check to see whether
135 the given item is of a known type (whether generic or wellknown),
136 whether the given type and class agree, and whether in case of a
137 well-known type, the given key is correct for that type.
138 If your code generates items that don't pass this check, you should
139 probably go meditate on it.
140
141 @param li the log_item to check
142
143 @retval LOG_ITEM_OK no problems
144 @retval LOG_ITEM_TYPE_NOT_FOUND unknown item type
145 @retval LOG_ITEM_CLASS_MISMATCH item_class derived from type isn't
146 what's set on the item
147 @retval LOG_ITEM_KEY_MISMATCH class not generic, so key should
148 match wellknown
149 @retval LOG_ITEM_STRING_NULL class is string, pointer is nullptr
150 @retval LOG_ITEM_KEY_NULL no key set (this is legal e.g. on aux
151 items of filter rules, but should not
152 occur in a log_line, i.e., log_sinks are
153 within their rights to discard such items)
154*/
155DECLARE_METHOD(int, item_inconsistent, (log_item * li));
156
157// helpers: predicates to find out about types and classes
158
159/**
160 Predicate used to determine whether a type is generic
161 (generic string, generic float, generic integer) rather
162 than a well-known type.
163
164 @param t log item type to examine
165
166 @retval true if generic type
167 @retval false if wellknown type
168*/
169DECLARE_METHOD(bool, item_generic_type, (log_item_type t));
170
171/**
172 Predicate used to determine whether a class is a string
173 class (C-string or Lex-string).
174
175 @param c log item class to examine
176
177 @retval true if of a string class
178 @retval false if not of a string class
179*/
180DECLARE_METHOD(bool, item_string_class, (log_item_class c));
181
182/**
183 Predicate used to determine whether a class is a numeric
184 class (integer or float).
185
186 @param c log item class to examine
187
188 @retval true if of a numeric class
189 @retval false if not of a numeric class
190*/
191DECLARE_METHOD(bool, item_numeric_class, (log_item_class c));
192
193/**
194 Set an integer value on a log_item.
195 Fails gracefully if no log_item_data is supplied, so it can safely
196 wrap log_line_item_set[_with_key]().
197
198 @param lid log_item_data struct to set the value on
199 @param i integer to set
200
201 @retval true lid was nullptr (possibly: OOM, could not set up log_item)
202 @retval false all's well
203*/
204DECLARE_METHOD(bool, item_set_int, (log_item_data * lid, longlong i));
205/**
206 Set a floating point value on a log_item.
207 Fails gracefully if no log_item_data is supplied, so it can safely
208 wrap log_line_item_set[_with_key]().
209
210 @param lid log_item_data struct to set the value on
211 @param f float to set
212
213 @retval true lid was nullptr (possibly: OOM, could not set up log_item)
214 @retval false all's well
215*/
216DECLARE_METHOD(bool, item_set_float, (log_item_data * lid, double f));
217
218/**
219 Set a string value on a log_item.
220 Fails gracefully if no log_item_data is supplied, so it can safely
221 wrap log_line_item_set[_with_key]().
222
223 @param lid log_item_data struct to set the value on
224 @param s pointer to string
225 @param s_len length of string
226
227 @retval true lid was nullptr (possibly: OOM, could not set up log_item)
228 @retval false all's well
229*/
230DECLARE_METHOD(bool, item_set_lexstring,
231 (log_item_data * lid, const char *s, size_t s_len));
232
233/**
234 Set a string value on a log_item.
235 Fails gracefully if no log_item_data is supplied, so it can safely
236 wrap log_line_item_set[_with_key]().
237
238 @param lid log_item_data struct to set the value on
239 @param s pointer to NTBS
240
241 @retval true lid was nullptr (possibly: OOM, could not set up log_item)
242 @retval false all's well
243*/
244DECLARE_METHOD(bool, item_set_cstring, (log_item_data * lid, const char *s));
245
246/**
247 Create new log item with key name "key", and allocation flags of
248 "alloc" (see enum_log_item_free).
249 Will return a pointer to the item's log_item_data struct for
250 convenience.
251 This is mostly interesting for filters and other services that create
252 items that are not part of a log_line; sources etc. that intend to
253 create an item for a log_line (the more common case) should usually
254 use the below line_item_set_with_key() which creates an item (like
255 this function does), but also correctly inserts it into a log_line.
256
257 @param li the log_item to work on
258 @param t the item-type
259 @param key the key to set on the item.
260 ignored for non-generic types (may pass nullptr for those)
261 see alloc
262 @param alloc LOG_ITEM_FREE_KEY if key was allocated by caller
263 LOG_ITEM_FREE_NONE if key was not allocated
264 Allocated keys will automatically free()d when the
265 log_item is.
266 The log_item's alloc flags will be set to the
267 submitted value; specifically, any pre-existing
268 value will be clobbered. It is therefore WRONG
269 a) to use this on a log_item that already has a key;
270 it should only be used on freshly init'd log_items;
271 b) to use this on a log_item that already has a
272 value (specifically, an allocated one); the correct
273 order is to init a log_item, then set up type and
274 key, and finally to set the value. If said value is
275 an allocated string, the log_item's alloc should be
276 bitwise or'd with LOG_ITEM_FREE_VALUE.
277
278 @retval a pointer to the log_item's log_data, for easy chaining:
279 log_item_set_with_key(...)->data_integer= 1;
280*/
281DECLARE_METHOD(log_item_data *, item_set_with_key,
282 (log_item * li, log_item_type t, const char *key, uint32 alloc));
283
284/**
285 As log_item_set_with_key(), except that the key is automatically
286 derived from the wellknown log_item_type t.
287
288 Create new log item with type "t".
289 Will return a pointer to the item's log_item_data struct for
290 convenience.
291 This is mostly interesting for filters and other services that create
292 items that are not part of a log_line; sources etc. that intend to
293 create an item for a log_line (the more common case) should usually
294 use the below line_item_set_with_key() which creates an item (like
295 this function does), but also correctly inserts it into a log_line.
296
297 The allocation of this item will be LOG_ITEM_FREE_NONE;
298 specifically, any pre-existing value will be clobbered.
299 It is therefore WRONG
300 a) to use this on a log_item that already has a key;
301 it should only be used on freshly init'd log_items;
302 b) to use this on a log_item that already has a
303 value (specifically, an allocated one); the correct
304 order is to init a log_item, then set up type and
305 key, and finally to set the value. If said value is
306 an allocated string, the log_item's alloc should be
307 bitwise or'd with LOG_ITEM_FREE_VALUE.
308
309 @param li the log_item to work on
310 @param t the item-type
311
312 @retval a pointer to the log_item's log_data, for easy chaining:
313 log_item_set_with_key(...)->data_integer= 1;
314*/
316
317/**
318 Create new log item in log line "ll", with key name "key", and
319 allocation flags of "alloc" (see enum_log_item_free).
320 On success, the number of registered items on the log line is increased,
321 the item's type is added to the log_line's "seen" property,
322 and a pointer to the item's log_item_data struct is returned for
323 convenience.
324
325 @param ll the log_line to work on
326 @param t the item-type
327 @param key the key to set on the item.
328 ignored for non-generic types (may pass nullptr for those)
329 see alloc
330 @param alloc LOG_ITEM_FREE_KEY if key was allocated by caller
331 LOG_ITEM_FREE_NONE if key was not allocated
332 Allocated keys will automatically free()d when the
333 log_item is.
334 The log_item's alloc flags will be set to the
335 submitted value; specifically, any pre-existing
336 value will be clobbered. It is therefore WRONG
337 a) to use this on a log_item that already has a key;
338 it should only be used on freshly init'd log_items;
339 b) to use this on a log_item that already has a
340 value (specifically, an allocated one); the correct
341 order is to init a log_item, then set up type and
342 key, and finally to set the value. If said value is
343 an allocated string, the log_item's alloc should be
344 bitwise or'd with LOG_ITEM_FREE_VALUE.
345
346 @retval a pointer to the log_item's log_data, for easy chaining:
347 log_line_item_set_with_key(...)->data_integer= 1;
348*/
349DECLARE_METHOD(log_item_data *, line_item_set_with_key,
350 (log_line * ll, log_item_type t, const char *key, uint32 alloc));
351
352/**
353 Create a new log item of well-known type "t" in log line "ll".
354 On success, the number of registered items on the log line is increased,
355 the item's type is added to the log_line's "seen" property,
356 and a pointer to the item's log_item_data struct is returned for
357 convenience.
358
359 The allocation of this item will be LOG_ITEM_FREE_NONE;
360 specifically, any pre-existing value will be clobbered.
361 It is therefore WRONG
362 a) to use this on a log_item that already has a key;
363 it should only be used on freshly init'd log_items;
364 b) to use this on a log_item that already has a
365 value (specifically, an allocated one); the correct
366 order is to init a log_item, then set up type and
367 key, and finally to set the value. If said value is
368 an allocated string, the log_item's alloc should be
369 bitwise or'd with LOG_ITEM_FREE_VALUE.
370
371 @param ll the log_line to work on
372 @param t the item-type
373
374 @retval a pointer to the log_item's log_data, for easy chaining:
375 log_line_item_set_with_key(...)->data_integer= 1;
376*/
377DECLARE_METHOD(log_item_data *, line_item_set,
379
380/**
381 Dynamically allocate and initialize a log_line.
382
383 @retval nullptr could not set up buffer (too small?)
384 @retval other address of the newly initialized log_line
385*/
386DECLARE_METHOD(log_line *, line_init, ());
387
388/**
389 Release a log_line allocated with line_init()
390
391 @param ll a log_line previously allocated with line_init()
392*/
393DECLARE_METHOD(void, line_exit, (log_line * ll));
394
395/**
396 How many items are currently set on the given log_line?
397
398 @param ll the log-line to examine
399
400 @retval the number of items set
401*/
402DECLARE_METHOD(int, line_item_count, (log_line * ll));
403
404/**
405 Test whether a given type is presumed present on the log line.
406
407 @param ll the log_line to examine
408 @param m the log_type to test for
409
410 @retval 0 not present
411 @retval !=0 present
412*/
413DECLARE_METHOD(log_item_type_mask, line_item_types_seen,
415
416/**
417 Get log-line's output buffer.
418 If the logger core provides this buffer, the log-service may use it
419 to assemble its output therein and implicitly return it to the core.
420 Participation is required for services that support populating
421 performance_schema.error_log, and optional for all others.
422
423 @param ll the log_line to examine
424
425 @retval nullptr success, an output buffer is available
426 @retval otherwise failure, no output buffer is available
427*/
428DECLARE_METHOD(log_item *, line_get_output_buffer, (log_line * ll));
429
430/**
431 Get an iterator for the items in a log_line.
432 For now, only one iterator may exist per log_line.
433
434 @param ll the log_line to examine
435
436 @retval a log_iter_iter, or nullptr on failure
437*/
438DECLARE_METHOD(log_item_iter *, line_item_iter_acquire, (log_line * ll));
439
440/**
441 Release an iterator for the items in a log_line.
442
443 @param it the iterator to release
444*/
445DECLARE_METHOD(void, line_item_iter_release, (log_item_iter * it));
446/**
447 Use the log_line iterator to get the first item from the set.
448
449 @param it the iterator to use
450
451 @retval pointer to the first log_item in the collection, or nullptr
452*/
453DECLARE_METHOD(log_item *, line_item_iter_first, (log_item_iter * it));
454
455/**
456 Use the log_line iterator to get the next item from the set.
457
458 @param it the iterator to use
459
460 @retval pointer to the next log_item in the collection, or nullptr
461*/
462DECLARE_METHOD(log_item *, line_item_iter_next, (log_item_iter * it));
463
464/**
465 Use the log_line iterator to get the current item from the set.
466
467 @param it the iterator to use
468
469 @retval pointer to the current log_item in the collection, or nullptr
470*/
471DECLARE_METHOD(log_item *, line_item_iter_current, (log_item_iter * it));
472
473/**
474 Complete, filter, and write submitted log items.
475
476 This expects a log_line collection of log-related key/value pairs,
477 e.g. from log_message().
478
479 Where missing, timestamp, priority, thread-ID (if any) and so forth
480 are added.
481
482 Log item source services, log item filters, and log item sinks are
483 then called; then all applicable resources are freed.
484
485 This interface is intended to facilitate the building of submission
486 interfaces other than the variadic message() one below. See the
487 example fluent C++ LogEvent() wrapper for an example of how to leverage
488 it.
489
490 @param ll key/value pairs describing info to log
491
492 @retval int number of fields in created log line
493*/
494DECLARE_METHOD(int, line_submit, (log_line * ll));
495
496/**
497 Submit a log-message for log "log_type".
498 Variadic convenience function for logging.
499
500 This fills in the array that is used by the filter and log-writer
501 services. Where missing, timestamp, priority, and thread-ID (if any)
502 are added. Log item source services, log item filters, and log item
503 writers are called.
504
505
506 The variadic list accepts a list of "assignments" of the form
507 - log_item_type, value, for well-known types, and
508 - log_item_type, key, value, for ad-hoc types (LOG_ITEM_GEN_*)
509
510 As its last item, the list should have
511 - an element of type LOG_ITEM_LOG_MESSAGE, containing a printf-style
512 format string, followed by all variables necessary to satisfy the
513 substitutions in that string
514
515 OR
516
517 - an element of type LOG_ITEM_LOG_LOOKUP, containing a MySQL error code,
518 which will be looked up in the list or regular error messages, followed
519 by all variables necessary to satisfy the substitutions in that string
520
521 OR
522
523 - an element of type LOG_ITEM_LOG_VERBATIM, containing a string that will
524 be used directly, with no % substitutions
525
526 see log_vmessage() for more information.
527*/
528DECLARE_METHOD(int, message, (int log_type, ...));
529
530/**
531 Escape \0 bytes, add \0 terminator. For log-writers and other sinks
532 that terminate in an API using C-strings.
533
534
535 @param li list_item to process
536
537 @retval -1 out of memory
538 @retval 0 success
539*/
540DECLARE_METHOD(int, sanitize, (log_item * li));
541
542/**
543 Return MySQL error message for a given error code.
544
545 @param mysql_errcode the error code the message for which to look up
546
547 @retval the message (a printf-style format string)
548*/
549DECLARE_METHOD(const char *, errmsg_by_errcode, (int mysql_errcode));
550
551/**
552 Return MySQL error code for a given error symbol.
553
554 @param sym the symbol to look up
555
556 @retval -1 failure
557 @retval >=0 the MySQL error code
558*/
559DECLARE_METHOD(longlong, errcode_by_errsymbol, (const char *sym));
560
561/**
562 Convenience function: Derive a log label ("error", "warning",
563 "information") from a severity.
564
565 @param prio the severity/prio in question
566
567 @return a label corresponding to that priority.
568 @retval "System" for prio of SYSTEM_LEVEL
569 @retval "Error" for prio of ERROR_LEVEL
570 @retval "Warning" for prio of WARNING_LEVEL
571 @retval "Note" for prio of INFORMATION_LEVEL
572*/
573DECLARE_METHOD(const char *, label_from_prio, (int prio));
574
575/**
576 Parse a ISO8601 timestamp and return the number of microseconds
577 since the epoch. Heeds +/- timezone info if present.
578
579 @see make_iso8601_timestamp()
580
581 @param timestamp an ASCII string containing an ISO8601 timestamp
582 @param len Length in bytes of the aforementioned string
583
584 @return microseconds since the epoch
585*/
586DECLARE_METHOD(ulonglong, parse_iso8601_timestamp,
587 (const char *timestamp, size_t len));
588
589/**
590 open an error log file
591
592 @param name_or_ext if beginning with '.':
593 @@global.log_error, except with this extension
594 otherwise:
595 use this as file name in the same location as
596 @@global.log_error
597
598 Value not contain folder separators!
599
600 @param[out] my_errstream an error log handle, or nullptr on failure
601
602 @returns LOG_SERVICE_SUCCESS success
603 @returns LOG_SERVICE_INVALID_ARGUMENT no my_errstream, or bad log name
604 @returns LOG_SERVICE_OUT_OF_MEMORY could not allocate file handle
605 @returns LOG_SERVICE_LOCK_ERROR couldn't lock lock
606 @returns LOG_SERVICE_UNABLE_TO_WRITE couldn't write to given location
607 @returns LOG_SERVICE_COULD_NOT_MAKE_LOG_NAME could not make log name
608*/
609DECLARE_METHOD(log_service_error, open_errstream,
610 (const char *name_or_ext, void **my_errstream));
611
612/**
613 write to an error log file previously opened with open_errstream()
614
615 @param my_errstream a handle describing the log file
616 @param buffer pointer to the string to write
617 @param length length of the string to write
618
619 @returns LOG_SERVICE_SUCCESS success
620 @returns otherwise failure
621*/
622DECLARE_METHOD(log_service_error, write_errstream,
623 (void *my_errstream, const char *buffer, size_t length));
624
625/**
626 are we writing to a dedicated errstream, or are we sharing it?
627
628 @param my_errstream a handle describing the log file
629
630 @retval 0 not dedicated (multiplexed, stderr, ...)
631 @retval 1 dedicated
632*/
633DECLARE_METHOD(int, dedicated_errstream, (void *my_errstream));
634
635/**
636 close an error log file previously opened with open_errstream()
637
638 @param my_stream a handle describing the log file
639
640 @returns LOG_SERVICE_SUCCESS on success
641*/
642DECLARE_METHOD(log_service_error, close_errstream, (void **my_errstream));
643
644/**
645 re-open an error log file
646 (primarily to facilitate flush/log-rotation)
647
648 If the new file can be opened, update the my_errstream descriptor to
649 use it and close the old file. Otherwise, keep using the old file.
650
651 @param name_or_ext if beginning with '.':
652 @@global.log_error, except with this extension
653 otherwise:
654 use this as file name in the same location as
655 @@global.log_error
656
657 Value may not contain folder separators!
658
659 In the general case, the caller will be a
660 log-writer, the log-writer will just pass
661 its preferred file extension, and the resulting
662 file name and path will therefore be the same
663 as for the original log file.
664
665 @param[in,out] my_errstream an error log handle
666
667 @returns LOG_SERVICE_INVALID_ARGUMENT, or the result of open_errstream()
668*/
669DECLARE_METHOD(log_service_error, reopen_errstream,
670 (const char *file, void **my_errstream));
671
673
674/**
675 String primitives for logging services.
676*/
677BEGIN_SERVICE_DEFINITION(log_builtins_string)
678// alloc (len+1) bytes
679DECLARE_METHOD(void *, malloc, (size_t len));
680// alloc (len+1) bytes, then copy len bytes from fm, and \0 terminate
681// like my_strndup(), and unlike strndup(), \0 in input won't end copying
682DECLARE_METHOD(char *, strndup, (const char *fm, size_t len));
683// free allocated memory
684DECLARE_METHOD(void, free, (void *ptr));
685
686// length of nul terminated byte string
687DECLARE_METHOD(size_t, length, (const char *s));
688// find char in string, from the left
689DECLARE_METHOD(char *, find_first, (const char *s, int c));
690// find char in string, from the right
691DECLARE_METHOD(char *, find_last, (const char *s, int c));
692
693// compare two NUL-terminated byte-strings
695 (const char *a, const char *b, size_t len,
696 bool case_insensitive));
697
698/**
699 Wrapper for std::snprintf()
700 Replace all % in format string with variables from list.
701 Do not use in new code; use std::snprintf() instead.
702
703 @param to buffer to write the result to
704 @param n size of that buffer
705 @param fmt format string
706 @param ap va_list with valuables for all substitutions in format string
707
708 @retval return value of snprintf
709*/
710DECLARE_METHOD(size_t, substitutev,
711 (char *to, size_t n, const char *fmt, va_list ap))
712MY_ATTRIBUTE((format(printf, 3, 0)));
713
714// replace all % in format string with variables from list (std::snprintf())
715DECLARE_METHOD(size_t, substitute, (char *to, size_t n, const char *fmt, ...))
716MY_ATTRIBUTE((format(printf, 3, 4)));
717
718END_SERVICE_DEFINITION(log_builtins_string)
719
720/**
721 Temporary primitives for logging services.
722*/
724// Are we shutting down yet? Windows EventLog needs to know.
725DECLARE_METHOD(size_t, notify_client,
726 (void *thd, uint severity, uint code, char *to, size_t n,
727 const char *format, ...))
728MY_ATTRIBUTE((format(printf, 6, 7)));
729END_SERVICE_DEFINITION(log_builtins_tmp)
730
731/**
732 Syslog/Eventlog functions for logging services.
733*/
734BEGIN_SERVICE_DEFINITION(log_builtins_syseventlog)
736 (const char *name, int option, int facility));
738 (enum loglevel level, const char *msg));
740END_SERVICE_DEFINITION(log_builtins_syseventlog)
741
742#ifdef __cplusplus
743
744#if !defined(LOG_H)
745
746extern SERVICE_TYPE(log_builtins) * log_bi;
747extern SERVICE_TYPE(log_builtins_string) * log_bs;
748
749#define log_line_init log_bi->line_init
750#define log_line_exit log_bi->line_exit
751#define log_line_item_set_with_key log_bi->line_item_set_with_key
752#define log_line_item_set log_bi->line_item_set
753#define log_line_item_types_seen log_bi->line_item_types_seen
754#define log_line_submit log_bi->line_submit
755#define log_set_int log_bi->item_set_int
756#define log_set_float log_bi->item_set_float
757#define log_set_lexstring log_bi->item_set_lexstring
758#define log_set_cstring log_bi->item_set_cstring
759#define log_malloc log_bs->malloc
760#define log_free log_bs->free
761#define log_msg log_bs->substitutev
762#define error_msg_by_errcode log_bi->errmsg_by_errcode
763#define error_code_by_errsymbol log_bi->errcode_by_errsymbol
764#else
765
766#include "sql/derror.h"
767
768#define log_malloc(s) my_malloc(0, (s), MYF(0))
769#define log_free my_free
770#define log_msg vsnprintf
771#define error_msg_by_errcode error_message_for_error_log
772#define error_code_by_errsymbol mysql_symbol_to_errno
773#define log_set_int log_item_set_int
774#define log_set_float log_item_set_float
775#define log_set_lexstring log_item_set_lexstring
776#define log_set_cstring log_item_set_cstring
777
778#endif // LOG_H
779
780#ifndef DISABLE_ERROR_LOGGING
781
782#if defined(LOG_COMPONENT_TAG)
783
784#define LogErr(severity, ecode, ...) \
785 LogEvent() \
786 .prio(severity) \
787 .errcode(ecode) \
788 .subsys(LOG_SUBSYSTEM_TAG) \
789 .component(LOG_COMPONENT_TAG) \
790 .source_line(__LINE__) \
791 .source_file(MY_BASENAME) \
792 .function(__FUNCTION__) \
793 .lookup(ecode, ##__VA_ARGS__)
794
795#define LogComponentErr(severity, ecode, ...) \
796 LogEvent() \
797 .prio(severity) \
798 .errcode(ecode) \
799 .subsys(LOG_SUBSYSTEM_TAG) \
800 .component("component:" LOG_COMPONENT_TAG) \
801 .source_line(__LINE__) \
802 .source_file(MY_BASENAME) \
803 .function(__FUNCTION__) \
804 .lookup_quoted(ecode, "Component " LOG_COMPONENT_TAG " reported", \
805 ##__VA_ARGS__)
806
807#define LogPluginErr(severity, ecode, ...) \
808 LogEvent() \
809 .prio(severity) \
810 .errcode(ecode) \
811 .subsys(LOG_SUBSYSTEM_TAG) \
812 .component("plugin:" LOG_COMPONENT_TAG) \
813 .source_line(__LINE__) \
814 .source_file(MY_BASENAME) \
815 .function(__FUNCTION__) \
816 .lookup_quoted(ecode, "Plugin " LOG_COMPONENT_TAG " reported", \
817 ##__VA_ARGS__)
818
819#define LogPluginErrV(severity, ecode, vl) \
820 LogEvent() \
821 .prio(severity) \
822 .errcode(ecode) \
823 .subsys(LOG_SUBSYSTEM_TAG) \
824 .component("plugin:" LOG_COMPONENT_TAG) \
825 .source_line(__LINE__) \
826 .source_file(MY_BASENAME) \
827 .function(__FUNCTION__) \
828 .lookup_quotedv(ecode, "Plugin " LOG_COMPONENT_TAG " reported", vl)
829
830#define LogPluginErrMsg(severity, ecode, ...) \
831 LogEvent() \
832 .prio(severity) \
833 .errcode(ecode) \
834 .subsys(LOG_SUBSYSTEM_TAG) \
835 .component("plugin:" LOG_COMPONENT_TAG) \
836 .source_line(__LINE__) \
837 .source_file(MY_BASENAME) \
838 .function(__FUNCTION__) \
839 .message_quoted("Plugin " LOG_COMPONENT_TAG " reported", ##__VA_ARGS__)
840
841#else
842
843#define LogErr(severity, ecode, ...) \
844 LogEvent() \
845 .prio(severity) \
846 .errcode(ecode) \
847 .subsys(LOG_SUBSYSTEM_TAG) \
848 .source_line(__LINE__) \
849 .source_file(MY_BASENAME) \
850 .function(__FUNCTION__) \
851 .lookup(ecode, ##__VA_ARGS__)
852
853#endif
854
855#else
856
857inline void dummy_log_message(longlong severity [[maybe_unused]],
858 longlong ecode [[maybe_unused]], ...) {
859 return;
860}
861
862#define LogErr(severity, ecode, ...) \
863 dummy_log_message(severity, ecode, ##__VA_ARGS__)
864
865#define LogPluginErr(severity, ecode, ...) \
866 dummy_log_message(severity, ecode, ##__VA_ARGS__)
867#define LogPluginErrV(severity, ecode, ...) \
868 dummy_log_message(severity, ecode, ##__VA_ARGS__)
869#define LogPluginErrMsg(severity, ecode, ...) \
870 dummy_log_message(severity, ecode, ##__VA_ARGS__)
871
872#endif // DISABLE_ERROR_LOGGING
873
874/**
875 Modular logger: fluid API. Server-internal. Lets you use safe and
876 expressive syntax, like so:
877
878 LogEvent(LOG_TYPE_ERROR).prio(INFORMATION_LEVEL).message("Meow! %d", 4711);
879*/
880
881class LogEvent {
882 private:
883 log_line *ll; // Temporary allocation to hold a log-event.
884 char *msg; // Temporary allocation to hold a message.
885 const char *msg_tag;
886 bool have_msg; // Was a message set in `msg` using set_message()?
887
888 /**
889 Set MySQL error-code if none has been set yet.
890
891 @param errcode the error code (not operating system errno!)
892
893 @retval true an error occurred, value not set (OOM?)
894 @retval false value was set without incident, or did not need to be set
895 */
897 if (ll == nullptr) return true;
898
902 }
903 return false; // already set, that's OK then
904 }
905
906 /**
907 Set the error message.
908
909 @param fmt format string. % substitution will be performed.
910 @param ap va_list of the arguments for % substitution.
911 */
912 void set_message(const char *fmt, va_list ap)
913 MY_ATTRIBUTE((format(printf, 2, 0)));
914
915 /**
916 Set the error message (by MySQL error code).
917 The actual message will be looked up using this errcode.
918 As the message is a printf-style format string, % substitution
919 will be performed.
920
921 @param errcode MySQL error code to fetch the message string for
922 @param ap va_list of the arguments for % substitution.
923 */
924 void set_message_by_errcode(longlong errcode, va_list ap);
925
926 public:
927 /**
928 Destructor automatically sends the event on.
929 It is auto-free()d after processing.
930 */
932 if (ll != nullptr) {
933 log_line_submit(this->ll);
935 /*
936 If a message was set on the LogEvent using set_message,
937 the message became part of a log_item on the log_line.
938 have_msg is true. The log_line's log_items were released
939 in log_line_submit(). Null `msg` here to prevent double-free.
940
941 On the other hand, if set_message() was not used, the
942 convenience buffer was never associated with the log_line,
943 and therefore wasn't freed when the log_line was submitted.
944 In that case, we'll leave the pointer intact for clean-up
945 further down.
946 */
947 if (have_msg) msg = nullptr;
948 }
949
950 /*
951 If set_message() attached the buffer `msg` to the log_line,
952 the allocation has either been freed in log_line_submit()
953 above, or it is now owned by someone who stole it using steal().
954 In either case, msg==nullptr and we do nothing here.
955 */
956 if (msg != nullptr) log_free(msg);
957 }
958
959 /**
960 "Full customization" constructor. Use one of the LogErr() macro
961 where possible; it's there to help you remember the minimum set
962 of particles and their data-types. Be prepared for stern looks
963 from your reviewers if you use this constructor except for external
964 (loadable) services that have no error messages registered with the
965 server, and therefore need to submit them free-form.
966 */
968 have_msg = false;
969 if ((ll = log_line_init()) != nullptr) {
970 if ((msg = (char *)log_malloc(LOG_BUFF_MAX)) == nullptr) {
972 ll = nullptr;
973 }
974 } else
975 msg = nullptr;
976 msg_tag = nullptr;
977 }
978
979 /**
980 Save the log-event allocated by LogEvent().
981
982 LogEvent() internally represents the log-event in a log_line
983 structure it allocates. steal() saves this pointer to the
984 method's argument. The pointer in the LogEvent() is then
985 cleared to prevent the destructor from freeing the log_line.
986 Freeing allocated memory is now the caller's responsibility:
987
988 log_line *ll;
989 LogEvent().prio(SYSTEM_LEVEL).message("Hi %s!", user).steal(&ll);
990
991 // Do some things with the event ...
992
993 log_line_item_free_all(ll);
994 log_line_exit(ll);
995
996 If a message was set, the message buffer pointed to by `msg`
997 becomes part of the log_line and is released on
998 log_line_item_free_all() (or equivalent).
999
1000 If no message was set, the message buffer is released when
1001 the LogEvent's destructor is called.
1002
1003 Note that verbatim() does NOT copy its argument to the
1004 LogEvent's internal allocation `msg`.
1005 Hence the life-cycle management of verbatim()'s argument
1006 would be up to the developer. When using steal(), using it
1007 with one of the set_message() wrappers is generally preferable:
1008
1009 LogEvent().message("%s", my_verbatim_string).steal(&ll);
1010
1011 @param save_to where to save the pointer to the log-event
1012 */
1013 void steal(log_line **save_to) {
1014 *save_to = ll;
1015 ll = nullptr;
1016 /*
1017 If the message was set, the allocation is now part of a log_item
1018 on the log_line. Thus, it is now owned by the called and will
1019 be released when they release the log_items on the log_line.
1020 In that case, we null our pointer to it so we won't double-free
1021 the allocation.
1022
1023 Conversely, if the buffer exists, but hasn't become part of
1024 the log_line through use of a set_message() wrapper, we'll hold
1025 on to the pointer so the empty buffer is released when we dest
1026 the LogEvent().
1027 */
1028 if (have_msg) msg = nullptr;
1029 }
1030
1031 /**
1032 Set log type.
1033
1034 @param val the log type (LOG_TYPE_ERROR)
1035
1036 @retval the LogEvent, for easy fluent-style chaining.
1037 */
1040 return *this;
1041 }
1042
1043 /**
1044 Append a numeric error code
1045
1046 @param val the MySQL error code (not operating system errno!).
1047
1048 @retval the LogEvent, for easy fluent-style chaining.
1049 */
1052 return *this;
1053 }
1054
1055 /**
1056 Append a (string) error symbol
1057
1058 @param val error symbol. NTBS.
1059
1060 @retval the LogEvent, for easy fluent-style chaining.
1061 */
1062 LogEvent &errsymbol(const char *val) {
1064 return *this;
1065 }
1066
1067 /**
1068 Append a (string) SQL state
1069
1070 @param val the SQLstate. NTBS.
1071
1072 @retval the LogEvent, for easy fluent-style chaining.
1073 */
1074 LogEvent &sqlstate(const char *val) {
1076 return *this;
1077 }
1078
1079 /**
1080 Append a numeric (operating system, as opposed to MySQL) error number.
1081
1082 @param val the operating system errno.
1083
1084 @retval the LogEvent, for easy fluent-style chaining.
1085 */
1088 return *this;
1089 }
1090
1091 /**
1092 Append a textual (operating system, as opposed to MySQL) error message,
1093 vulgo, strerror()
1094
1095 @param val the error message returned by the operating system. NTBS.
1096
1097 @retval the LogEvent, for easy fluent-style chaining.
1098 */
1099 LogEvent &os_errmsg(const char *val) {
1101 return *this;
1102 }
1103
1104 /**
1105 Which source file was the problem detected in?
1106
1107 @param val the source file's name. NTBS.
1108
1109 @retval the LogEvent, for easy fluent-style chaining.
1110 */
1111 LogEvent &source_file(const char *val) {
1113 return *this;
1114 }
1115
1116 /**
1117 Which line in the source file was the problem detected on?
1118
1119 @param val the line number.
1120
1121 @retval the LogEvent, for easy fluent-style chaining.
1122 */
1125 return *this;
1126 }
1127
1128 /**
1129 Which function in the source was the problem detected in?
1130
1131 @param val the function's name. NTBS.
1132
1133 @retval the LogEvent, for easy fluent-style chaining.
1134 */
1135 LogEvent &function(const char *val) {
1137 return *this;
1138 }
1139
1140 /**
1141 Which subsystem in the source was the problem detected in?
1142 ("Repl"/"InnoDB"/"Server")
1143
1144 @param val the subsystem. NTBS.
1145
1146 @retval the LogEvent, for easy fluent-style chaining.
1147 */
1148 LogEvent &subsys(const char *val) {
1149 if (val != nullptr)
1151 return *this;
1152 }
1153
1154 /**
1155 Which component in the source was the problem detected in?
1156 This should be the same string that is given to the
1157 component/service framework.
1158
1159 @param val the component. NTBS.
1160
1161 @retval the LogEvent, for easy fluent-style chaining.
1162 */
1163 LogEvent &component(const char *val) {
1164 if (val != nullptr)
1166 return *this;
1167 }
1168
1169 /**
1170 What user were we working for at the time of the issue?
1171
1172 @param val the user part (of "user@host"). LEX_CSTRING.
1173
1174 @retval the LogEvent, for easy fluent-style chaining.
1175 */
1178 val.length);
1179 return *this;
1180 }
1181
1182 /**
1183 What user were we working for at the time of the issue?
1184
1185 @param val the user part (of "user@host"). NTBS.
1186
1187 @retval the LogEvent, for easy fluent-style chaining.
1188 */
1189 LogEvent &user(const char *val) {
1191 return *this;
1192 }
1193
1194 /**
1195 Whose session did the issue appear in?
1196
1197 @param val the host part (of "user@host"). LEX_CSTRING.
1198
1199 @retval the LogEvent, for easy fluent-style chaining.
1200 */
1203 val.length);
1204 return *this;
1205 }
1206
1207 /**
1208 Whose session did the issue appear in?
1209
1210 @param val the host part (of "user@host"). NTBS.
1211
1212 @retval the LogEvent, for easy fluent-style chaining.
1213 */
1214 LogEvent &host(const char *val) {
1216 return *this;
1217 }
1218
1219 /**
1220 What thread / "connection ID" was the issue detected in?
1221
1222 @param val the thread_ID of the session the issue appeared in
1223
1224 @retval the LogEvent, for easy fluent-style chaining.
1225 */
1228 return *this;
1229 }
1230
1231 /**
1232 What query apparently caused the issue?
1233
1234 @param val the query_ID of the offending query
1235
1236 @retval the LogEvent, for easy fluent-style chaining.
1237 */
1240 return *this;
1241 }
1242
1243 /**
1244 What table were we working on?
1245
1246 @param val the table's name/alias. NTBS.
1247
1248 @retval the LogEvent, for easy fluent-style chaining.
1249 */
1250 LogEvent &table_name(const char *val) {
1252 return *this;
1253 }
1254
1255 /**
1256 Set error message priority.
1257 Assign one of ERROR_LEVEL, WARNING_LEVEL, INFORMATION_LEVEL.
1258 log-writers and other sinks should use this value (rather
1259 than that of LOG_ITEM_LOG_EPRIO):
1260
1261 - file writers should use the value to determine
1262 what label to write (perhaps by submitting it to label_from_prio())
1263
1264 - sinks that submit the event data to a sub-system outside of
1265 the MySQL server (such as syslog, EventLog, systemd journal, etc.)
1266 should translate this value into a priority/log level understood
1267 by that target subsystem.
1268
1269 @param val The priority for this LogEvent.
1270
1271 @retval the LogEvent, for easy fluent-style chaining.
1272 */
1275 return *this;
1276 }
1277
1278 /**
1279 Set a label (usually "warning"/"error"/"information").
1280 Will be derived from prio if not set explicitly.
1281 Some log services may ignore custom labels.
1282
1283 @param val the (custom) label to set
1284
1285 @retval the LogEvent, for easy fluent-style chaining.
1286 */
1287 LogEvent &label(const char *val) {
1289 return *this;
1290 }
1291
1292 /**
1293 Add a message to the event, verbatim (i.e. with no % substitutions).
1294 This is an analog of message("%s", message); it can be used when
1295 message may contain user input or a message from another subsystem
1296 that could contain % that must not be interpreted as an invitation
1297 to do % substitutions.
1298
1299 If you use this in a context other than an external service that
1300 has no messages registered with the server, your reviewers will
1301 say unkind things about you. Use registered messages and their
1302 error codes wherever possible!
1303
1304 Combining verbatim() with steal() is discouraged as it burdens
1305 the developer with the life-cycle management of verbatim's
1306 argument. This is a result of verbatim() using its argument
1307 verbatim, rather than setting it up in the LogEvent's internal
1308 allocation `msg` using set_message(). Hence, the LogEvent has
1309 no copy of the message, which is an optimization for the
1310 common, non-steal() case.
1311
1312 @param msg_arg the message. % substitution will not happen.
1313
1314 @retval the LogEvent, for easy fluent-style chaining.
1315 */
1316 LogEvent &verbatim(const char *msg_arg) {
1318 return *this;
1319 }
1320
1321 /**
1322 Fill in a format string by substituting the % with the given
1323 arguments, then add the result as the event's message.
1324 This should be used very sparingly; use registered messages
1325 and their error codes wherever possible!
1326
1327 @param fmt message (treated as a printf-style format-string,
1328 so % substitution will happen)
1329 @param ap valist to satisfy any % in the message
1330
1331 @retval the LogEvent, for easy fluent-style chaining.
1332 */
1333 LogEvent &messagev(const char *fmt, va_list ap)
1334 MY_ATTRIBUTE((format(printf, 2, 0))) {
1335 set_message(fmt, ap);
1336 return *this;
1337 }
1338
1339 /**
1340 Fill in a format string by substituting the % with the given
1341 arguments, then add the result as the event's message.
1342
1343 If you use this in a context other than an external service that
1344 has no messages registered with the server, your reviewers will
1345 say unkind things about you. Use registered messages and their
1346 error codes wherever possible!
1347
1348 @param fmt message (treated as a printf-style format-string,
1349 so % substitution will happen)
1350 @param ... varargs to satisfy any % in the message
1351
1352 @retval the LogEvent, for easy fluent-style chaining.
1353 */
1354 LogEvent &message(const char *fmt, ...) MY_ATTRIBUTE((format(printf, 2, 3)));
1355
1356 /**
1357 Fill in a format string by substituting the % with the given
1358 arguments and tag, then add the result as the event's message.
1359
1360 @param tag Tag to prefix to message.
1361 @param fmt message (treated as a printf-style format-string,
1362 so % substitution will happen)
1363 @param ... varargs to satisfy any % in the message
1364
1365 @retval the LogEvent, for easy fluent-style chaining.
1366 */
1367 LogEvent &message_quoted(const char *tag, const char *fmt, ...)
1368 MY_ATTRIBUTE((format(printf, 3, 4))) {
1369 msg_tag = tag;
1370
1371 va_list args;
1372 va_start(args, fmt);
1373 set_message(fmt, args);
1374 va_end(args);
1375
1376 return *this;
1377 }
1378
1379 /**
1380 Find an error message by its MySQL error code.
1381 Substitute the % in that message with the given
1382 arguments, then add the result as the event's message.
1383
1384 @param errcode MySQL error code for the message in question,
1385 e.g. ER_STARTUP
1386 @param ... varargs to satisfy any % in the message
1387
1388 @retval the LogEvent, for easy fluent-style chaining.
1389 */
1391 va_list args;
1392 va_start(args, errcode);
1394 va_end(args);
1395
1396 return *this;
1397 }
1398
1399 /**
1400 Find an error message by its MySQL error code. Substitute the % in that
1401 message with the given arguments list, then add the result as the event's
1402 message.
1403
1404 @param errcode MySQL error code for the message in question,
1405 e.g. ER_STARTUP
1406 @param args varargs to satisfy any % in the message
1407
1408 @retval the LogEvent, for easy fluent-style chaining.
1409 */
1412
1413 return *this;
1414 }
1415
1416 LogEvent &lookup_quoted(longlong errcode, const char *tag, ...) {
1417 msg_tag = tag;
1418
1419 va_list args;
1420 va_start(args, tag);
1422 va_end(args);
1423
1424 return *this;
1425 }
1426
1427 LogEvent &lookup_quotedv(longlong errcode, const char *tag, va_list vl) {
1428 msg_tag = tag;
1430
1431 return *this;
1432 }
1433
1434 /**
1435 Add a ad hoc integer value with the given key.
1436
1437 @param key user-defined key (i.e. not wellknown). NTBS.
1438 @param val value.
1439
1440 @retval the LogEvent, for easy fluent-style chaining.
1441 */
1442 LogEvent &int_value(const char *key, longlong val) {
1445 val);
1446 return *this;
1447 }
1448
1449 /**
1450 Add a ad hoc (not "well-known") float value with the given key.
1451
1452 @param key user-defined key (i.e. not wellknown). NTBS.
1453 @param val value.
1454
1455 @retval the LogEvent, for easy fluent-style chaining.
1456 */
1457 LogEvent &float_value(const char *key, double val) {
1460 val);
1461 return *this;
1462 }
1463
1464 /**
1465 Add a ad hoc string value with the given key.
1466
1467 @param key user-defined key (i.e. not wellknown). NTBS.
1468 @param val value.
1469 @param len length in bytes of the value.
1470
1471 @retval the LogEvent, for easy fluent-style chaining.
1472 */
1473 LogEvent &string_value(const char *key, const char *val, size_t len) {
1477 val, len);
1478 return *this;
1479 }
1480
1481 /**
1482 Add a ad hoc string value with the given key.
1483
1484 @param key user-defined key (i.e. not wellknown). NTBS.
1485 @param val value. NTBS.
1486
1487 @retval the LogEvent, for easy fluent-style chaining.
1488 */
1489 LogEvent &string_value(const char *key, const char *val) {
1493 val);
1494 return *this;
1495 }
1496};
1497
1498inline void LogEvent::set_message_by_errcode(longlong errcode, va_list ap) {
1499 const char *fmt = error_msg_by_errcode((int)errcode);
1500
1501 if ((fmt == nullptr) || (*fmt == '\0')) fmt = "invalid error code";
1502
1504 set_message(fmt, ap);
1505}
1506
1507inline void LogEvent::set_message(const char *fmt, va_list ap) {
1508 if ((ll != nullptr) && (msg != nullptr)) {
1509 char buf[LOG_BUFF_MAX];
1510 if (msg_tag != nullptr) {
1511 snprintf(buf, LOG_BUFF_MAX, "%s: \'%s\'", msg_tag, fmt);
1512 fmt = buf;
1513 }
1514 size_t len = log_msg(msg, LOG_BUFF_MAX, fmt, ap);
1515 if (len >= LOG_BUFF_MAX) {
1516 const char ellipsis[] = " <...>";
1517 len = LOG_BUFF_MAX - 1;
1518 strcpy(&msg[LOG_BUFF_MAX - sizeof(ellipsis)], ellipsis);
1519 }
1520 log_item_data *lid;
1521 lid = log_line_item_set_with_key(this->ll, LOG_ITEM_LOG_MESSAGE, nullptr,
1523 log_set_lexstring(lid, msg, len);
1524 have_msg = true;
1525 }
1526}
1527
1528inline LogEvent &LogEvent::message(const char *fmt, ...) {
1529 va_list args;
1530 va_start(args, fmt);
1531 set_message(fmt, args);
1532 va_end(args);
1533
1534 return *this;
1535}
1536
1537// Methods initialize and de-initialize logging service for plugins.
1538#if defined(MYSQL_DYNAMIC_PLUGIN)
1539
1540/**
1541 Method to de-initialize logging service in plugin.
1542
1543 param[in,out] reg_srv Plugin registry service.
1544 param[in,out] log_bi Error logging service.
1545 param[in,out] log_bs String service for error logging.
1546*/
1547inline void deinit_logging_service_for_plugin(
1548 SERVICE_TYPE(registry) * *reg_srv, SERVICE_TYPE(log_builtins) * *log_bi,
1549 SERVICE_TYPE(log_builtins_string) * *log_bs) {
1550 using log_builtins_t = SERVICE_TYPE_NO_CONST(log_builtins);
1551 using log_builtins_string_t = SERVICE_TYPE_NO_CONST(log_builtins_string);
1552 if (*log_bi)
1553 (*reg_srv)->release(
1554 reinterpret_cast<my_h_service>(const_cast<log_builtins_t *>(*log_bi)));
1555 if (*log_bs)
1556 (*reg_srv)->release(reinterpret_cast<my_h_service>(
1557 const_cast<log_builtins_string_t *>(*log_bs)));
1559 *log_bi = nullptr;
1560 *log_bs = nullptr;
1561 *reg_srv = nullptr;
1562}
1563
1564/**
1565 Method to de-initialize logging service in plugin.
1566
1567 param[in,out] reg_srv Plugin registry service.
1568 param[in,out] log_bi Error logging service.
1569 param[in,out] log_bs String service for error logging.
1570
1571 @retval false Success.
1572 @retval true Failed.
1573*/
1574inline bool init_logging_service_for_plugin(
1575 SERVICE_TYPE(registry) * *reg_srv, SERVICE_TYPE(log_builtins) * *log_bi,
1576 SERVICE_TYPE(log_builtins_string) * *log_bs) {
1577 my_h_service log_srv = nullptr;
1578 my_h_service log_str_srv = nullptr;
1580 if (!(*reg_srv)->acquire("log_builtins.mysql_server", &log_srv) &&
1581 !(*reg_srv)->acquire("log_builtins_string.mysql_server", &log_str_srv)) {
1582 (*log_bi) = reinterpret_cast<SERVICE_TYPE(log_builtins) *>(log_srv);
1583 (*log_bs) =
1584 reinterpret_cast<SERVICE_TYPE(log_builtins_string) *>(log_str_srv);
1585 } else {
1586 deinit_logging_service_for_plugin(reg_srv, log_bi, log_bs);
1587 return true;
1588 }
1589 return false;
1590}
1591
1592#elif defined(EXTRA_CODE_FOR_UNIT_TESTING)
1593
1594/**
1595 Method is used by unit tests.
1596
1597 param[in,out] reg_srv Plugin registry service.
1598 param[in,out] log_bi Error logging service.
1599 param[in,out] log_bs String service for error logging.
1600
1601 @retval false Success.
1602 @retval true Failed.
1603*/
1604inline bool init_logging_service_for_plugin(
1605 SERVICE_TYPE(registry) * *reg_srv [[maybe_unused]],
1606 SERVICE_TYPE(log_builtins) * *log_bi [[maybe_unused]],
1607 SERVICE_TYPE(log_builtins_string) * *log_bs [[maybe_unused]])
1608
1609{
1610 return false;
1611}
1612
1613/**
1614 Method is used by unit tests.
1615
1616 param[in,out] reg_srv Plugin registry service.
1617 param[in,out] log_bi Error logging service.
1618 param[in,out] log_bs String service for error logging.
1619*/
1620inline void deinit_logging_service_for_plugin(
1621 SERVICE_TYPE(registry) * *reg_srv [[maybe_unused]],
1622 SERVICE_TYPE(log_builtins) * *log_bi [[maybe_unused]],
1623 SERVICE_TYPE(log_builtins_string) * *log_bs [[maybe_unused]]) {}
1624
1625#endif // MYSQL_DYNAMIC_PLUGIN
1626
1627#endif // __cplusplus
1628
1629#endif
Modular logger: fluid API.
Definition: log_builtins.h:881
~LogEvent()
Destructor automatically sends the event on.
Definition: log_builtins.h:931
LogEvent & host(const char *val)
Whose session did the issue appear in?
Definition: log_builtins.h:1214
LogEvent & user(const char *val)
What user were we working for at the time of the issue?
Definition: log_builtins.h:1189
LogEvent & string_value(const char *key, const char *val, size_t len)
Add a ad hoc string value with the given key.
Definition: log_builtins.h:1473
LogEvent()
"Full customization" constructor.
Definition: log_builtins.h:967
char * msg
Definition: log_builtins.h:884
LogEvent & lookup_quoted(longlong errcode, const char *tag,...)
Definition: log_builtins.h:1416
LogEvent & lookup_quotedv(longlong errcode, const char *tag, va_list vl)
Definition: log_builtins.h:1427
bool have_msg
Definition: log_builtins.h:886
LogEvent & prio(longlong val)
Set error message priority.
Definition: log_builtins.h:1273
LogEvent & subsys(const char *val)
Which subsystem in the source was the problem detected in? ("Repl"/"InnoDB"/"Server")
Definition: log_builtins.h:1148
LogEvent & errcode(longlong val)
Append a numeric error code.
Definition: log_builtins.h:1050
LogEvent & source_file(const char *val)
Which source file was the problem detected in?
Definition: log_builtins.h:1111
bool set_errcode(longlong errcode)
Set MySQL error-code if none has been set yet.
Definition: log_builtins.h:896
LogEvent & os_errno(longlong val)
Append a numeric (operating system, as opposed to MySQL) error number.
Definition: log_builtins.h:1086
LogEvent & type(enum_log_type val)
Set log type.
Definition: log_builtins.h:1038
LogEvent & thread_id(longlong val)
What thread / "connection ID" was the issue detected in?
Definition: log_builtins.h:1226
LogEvent & os_errmsg(const char *val)
Append a textual (operating system, as opposed to MySQL) error message, vulgo, strerror()
Definition: log_builtins.h:1099
LogEvent & component(const char *val)
Which component in the source was the problem detected in? This should be the same string that is giv...
Definition: log_builtins.h:1163
LogEvent & lookupv(longlong errcode, va_list args)
Find an error message by its MySQL error code.
Definition: log_builtins.h:1410
const char * msg_tag
Definition: log_builtins.h:885
LogEvent & verbatim(const char *msg_arg)
Add a message to the event, verbatim (i.e.
Definition: log_builtins.h:1316
LogEvent & message(const char *fmt,...)
Fill in a format string by substituting the % with the given arguments, then add the result as the ev...
Definition: log_builtins.h:1528
LogEvent & errsymbol(const char *val)
Append a (string) error symbol.
Definition: log_builtins.h:1062
void steal(log_line **save_to)
Definition: log_builtins.h:1013
LogEvent & table_name(const char *val)
What table were we working on?
Definition: log_builtins.h:1250
LogEvent & label(const char *val)
Set a label (usually "warning"/"error"/"information").
Definition: log_builtins.h:1287
LogEvent & source_line(longlong val)
Which line in the source file was the problem detected on?
Definition: log_builtins.h:1123
LogEvent & query_id(longlong val)
What query apparently caused the issue?
Definition: log_builtins.h:1238
LogEvent & message_quoted(const char *tag, const char *fmt,...)
Fill in a format string by substituting the % with the given arguments and tag, then add the result a...
Definition: log_builtins.h:1367
LogEvent & messagev(const char *fmt, va_list ap)
Fill in a format string by substituting the % with the given arguments, then add the result as the ev...
Definition: log_builtins.h:1333
LogEvent & sqlstate(const char *val)
Append a (string) SQL state.
Definition: log_builtins.h:1074
LogEvent & float_value(const char *key, double val)
Add a ad hoc (not "well-known") float value with the given key.
Definition: log_builtins.h:1457
log_line * ll
Definition: log_builtins.h:883
LogEvent & int_value(const char *key, longlong val)
Add a ad hoc integer value with the given key.
Definition: log_builtins.h:1442
LogEvent & user(LEX_CSTRING val)
What user were we working for at the time of the issue?
Definition: log_builtins.h:1176
LogEvent & string_value(const char *key, const char *val)
Add a ad hoc string value with the given key.
Definition: log_builtins.h:1489
void set_message_by_errcode(longlong errcode, va_list ap)
Set the error message (by MySQL error code).
Definition: log_builtins.h:1498
void set_message(const char *fmt, va_list ap)
Set the error message.
Definition: log_builtins.h:1507
LogEvent & lookup(longlong errcode,...)
Find an error message by its MySQL error code.
Definition: log_builtins.h:1390
LogEvent & host(LEX_CSTRING val)
Whose session did the issue appear in?
Definition: log_builtins.h:1201
Specifies macros to define Components.
static char buf[MAX_BUF]
Definition: conf_to_src.cc:73
void write(W *w, const T &t, const char *key, size_t key_sz)
Definition: sdi_impl.h:335
struct my_h_service_imp * my_h_service
A handle type for acquired Service.
Definition: registry.h:33
#define malloc(A)
Definition: lexyy.cc:914
#define free(A)
Definition: lexyy.cc:915
Error logging, slow query logging, general query logging: If it's server-internal,...
#define log_line_init
Definition: log_builtins.h:749
#define log_line_item_types_seen
Definition: log_builtins.h:753
const mysql_service_log_builtins_string_t * log_bs
string built-ins
Definition: keyring_file.cc:137
void log_line_process_hook_set(log_line_processor llp)
Set the log-event processor.
Definition: log_builtins.cc:105
#define log_set_cstring
Definition: log_builtins.h:758
#define log_set_float
Definition: log_builtins.h:756
log_line_processor log_line_process_hook_get(void)
Get current log-event processor.
Definition: log_builtins.cc:119
#define log_malloc
Definition: log_builtins.h:759
#define log_line_exit
Definition: log_builtins.h:750
#define log_line_submit
Definition: log_builtins.h:754
#define log_line_item_set
Definition: log_builtins.h:752
#define log_set_int
Definition: log_builtins.h:755
#define log_msg
Definition: log_builtins.h:761
#define error_msg_by_errcode
Definition: log_builtins.h:762
#define log_free
Definition: log_builtins.h:760
bool(* log_line_processor)(log_line *ll)
This defines built-in functions for use by logging services.
Definition: log_builtins.h:56
#define log_line_item_set_with_key
Definition: log_builtins.h:751
const mysql_service_log_builtins_t * log_bi
accessor built-ins
Definition: keyring_file.cc:136
#define log_set_lexstring
Definition: log_builtins.h:757
enum enum_log_service_error log_service_error
Error codes.
#define LOG_BUFF_MAX
advisory.
Definition: log_shared.h:225
enum enum_log_item_class log_item_class
enum_log_type
log_type – which log to send data to check vs enum_log_table_type and LOG_FILE/LOG_TABLE/LOG_NONE
Definition: log_shared.h:66
@ LOG_ITEM_SRV_COMPONENT
log called from component ...
Definition: log_shared.h:136
@ LOG_ITEM_SRC_FUNC
log called from function ...
Definition: log_shared.h:134
@ LOG_ITEM_LOG_LABEL
label, unless auto-derived
Definition: log_shared.h:143
@ LOG_ITEM_SQL_QUERY_ID
query ID
Definition: log_shared.h:140
@ LOG_ITEM_SQL_ERRSYMBOL
mysql error code (symbolic)
Definition: log_shared.h:128
@ LOG_ITEM_GEN_FLOAT
float not otherwise specified
Definition: log_shared.h:151
@ LOG_ITEM_LOG_TYPE
error log, etc.
Definition: log_shared.h:126
@ LOG_ITEM_SRC_FILE
log called from file ...
Definition: log_shared.h:132
@ LOG_ITEM_SQL_TABLE_NAME
table name
Definition: log_shared.h:141
@ LOG_ITEM_MSC_USER
offending thread owned by ...
Definition: log_shared.h:137
@ LOG_ITEM_LOG_MESSAGE
the message, format string
Definition: log_shared.h:145
@ LOG_ITEM_GEN_INTEGER
integer not otherwise specified
Definition: log_shared.h:152
@ LOG_ITEM_LOG_PRIO
log priority (error, warn, ...)
Definition: log_shared.h:142
@ LOG_ITEM_SRV_SUBSYS
log called from subsystem ...
Definition: log_shared.h:135
@ LOG_ITEM_SYS_ERRNO
OS errno.
Definition: log_shared.h:130
@ LOG_ITEM_SQL_ERRCODE
mysql error code (numeric)
Definition: log_shared.h:127
@ LOG_ITEM_SRV_THREAD
connection ID
Definition: log_shared.h:139
@ LOG_ITEM_SRC_LINE
log called from line ...
Definition: log_shared.h:133
@ LOG_ITEM_GEN_LEX_STRING
lex string not otherwise specified
Definition: log_shared.h:153
@ LOG_ITEM_MSC_HOST
responsible user on host ...
Definition: log_shared.h:138
@ LOG_ITEM_SYS_STRERROR
OS strerror()
Definition: log_shared.h:131
@ LOG_ITEM_SQL_STATE
SQL state.
Definition: log_shared.h:129
@ LOG_ITEM_FREE_NONE
Definition: log_shared.h:179
@ LOG_ITEM_FREE_VALUE
Definition: log_shared.h:181
enum enum_log_item_type log_item_type
item_type – what to log
uint64 log_item_type_mask
a bit mask of log_types.
Definition: log_shared.h:216
static int log_type
Definition: mi_log.cc:47
Header for compiler-dependent features.
unsigned long long int ulonglong
Definition: my_inttypes.h:56
long long int longlong
Definition: my_inttypes.h:55
uint32_t uint32
Definition: my_inttypes.h:67
loglevel
Definition: my_loglevel.h:41
Definition: buf0block_hint.cc:30
constexpr value_type timestamp
Definition: classic_protocol_constants.h:278
Definition: os0file.h:89
bool length(const dd::Spatial_reference_system *srs, const Geometry *g1, double *length, bool *null) noexcept
Computes the length of linestrings and multilinestrings.
Definition: length.cc:76
char * strndup(const char *s, size_t n)
The strndup() function returns a pointer to a new string which is a duplicate of the string s,...
Definition: wrapper_functions.h:123
stdx::expected< void, std::error_code > close(file_handle_type native_handle)
close file handle.
Definition: file.h:239
mutable_buffer buffer(void *p, size_t n) noexcept
Definition: buffer.h:418
stdx::expected< int, std::error_code > open(const char *fname, int flags, mode_t mode) noexcept
Definition: file_handle.cc:79
required string key
Definition: replication_asynchronous_connection_failover.proto:60
static int compare(size_t a, size_t b)
Function to compare two size_t integers for their relative order.
Definition: rpl_utility.cc:107
#define DECLARE_METHOD(retval, name, args)
Declares a method as a part of the Service definition.
Definition: service.h:103
#define SERVICE_TYPE(name)
Generates the standard Service type name.
Definition: service.h:76
#define END_SERVICE_DEFINITION(name)
A macro to end the last Service definition started with the BEGIN_SERVICE_DEFINITION macro.
Definition: service.h:91
#define SERVICE_TYPE_NO_CONST(name)
Generates the standard Service type name.
Definition: service.h:71
#define BEGIN_SERVICE_DEFINITION(name)
Declares a new Service.
Definition: service.h:86
Specifies macros to define Service Implementations.
Declaration of the registry plugin service.
const mysql_service_registry_t * mysql_plugin_registry_acquire()
Returns a new reference to the "registry" service.
Definition: plugin_registry_service.cc:47
int mysql_plugin_registry_release(const mysql_service_registry_t *)
Releases a registry service reference.
Definition: plugin_registry_service.cc:75
case opt name
Definition: sslopt-case.h:29
Definition: mysql_lex_string.h:40
const char * str
Definition: mysql_lex_string.h:41
size_t length
Definition: mysql_lex_string.h:42
Iterator over the key/value pairs of a log_line.
Definition: keyring_log_builtins_definition.cc:64
Definition: log_shared.h:196
log_line ("log event")
Definition: keyring_log_builtins_definition.cc:72
static const mysql_service_registry_t * reg_srv
Initialize parameters required for error logging.
Definition: test_plugin.cc:62
Definition: log_shared.h:185
int n
Definition: xcom_base.cc:509