MySQL 9.1.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 Set/reset one or more log line flags.
248
249 Example to set the flag:
250 log_line_set_flag(ll, LOG_LINE_EMIT_TELEMETRY, LOG_LINE_EMIT_TELEMETRY);
251 to reset the flag:
252 log_line_set_flag(ll, LOG_LINE_EMIT_TELEMETRY, 0);
253*/
254DECLARE_METHOD(void, line_set_flag,
257
258/**
259 Create new log item with key name "key", and allocation flags of
260 "alloc" (see enum_log_item_free).
261 Will return a pointer to the item's log_item_data struct for
262 convenience.
263 This is mostly interesting for filters and other services that create
264 items that are not part of a log_line; sources etc. that intend to
265 create an item for a log_line (the more common case) should usually
266 use the below line_item_set_with_key() which creates an item (like
267 this function does), but also correctly inserts it into a log_line.
268
269 @param li the log_item to work on
270 @param t the item-type
271 @param key the key to set on the item.
272 ignored for non-generic types (may pass nullptr for those)
273 see alloc
274 @param alloc LOG_ITEM_FREE_KEY if key was allocated by caller
275 LOG_ITEM_FREE_NONE if key was not allocated
276 Allocated keys will automatically free()d when the
277 log_item is.
278 The log_item's alloc flags will be set to the
279 submitted value; specifically, any pre-existing
280 value will be clobbered. It is therefore WRONG
281 a) to use this on a log_item that already has a key;
282 it should only be used on freshly init'd log_items;
283 b) to use this on a log_item that already has a
284 value (specifically, an allocated one); the correct
285 order is to init a log_item, then set up type and
286 key, and finally to set the value. If said value is
287 an allocated string, the log_item's alloc should be
288 bitwise or'd with LOG_ITEM_FREE_VALUE.
289
290 @retval a pointer to the log_item's log_data, for easy chaining:
291 log_item_set_with_key(...)->data_integer= 1;
292*/
293DECLARE_METHOD(log_item_data *, item_set_with_key,
294 (log_item * li, log_item_type t, const char *key, uint32 alloc));
295
296/**
297 As log_item_set_with_key(), except that the key is automatically
298 derived from the wellknown log_item_type t.
299
300 Create new log item with type "t".
301 Will return a pointer to the item's log_item_data struct for
302 convenience.
303 This is mostly interesting for filters and other services that create
304 items that are not part of a log_line; sources etc. that intend to
305 create an item for a log_line (the more common case) should usually
306 use the below line_item_set_with_key() which creates an item (like
307 this function does), but also correctly inserts it into a log_line.
308
309 The allocation of this item will be LOG_ITEM_FREE_NONE;
310 specifically, any pre-existing value will be clobbered.
311 It is therefore WRONG
312 a) to use this on a log_item that already has a key;
313 it should only be used on freshly init'd log_items;
314 b) to use this on a log_item that already has a
315 value (specifically, an allocated one); the correct
316 order is to init a log_item, then set up type and
317 key, and finally to set the value. If said value is
318 an allocated string, the log_item's alloc should be
319 bitwise or'd with LOG_ITEM_FREE_VALUE.
320
321 @param li the log_item to work on
322 @param t the item-type
323
324 @retval a pointer to the log_item's log_data, for easy chaining:
325 log_item_set_with_key(...)->data_integer= 1;
326*/
328
329/**
330 Create new log item in log line "ll", with key name "key", and
331 allocation flags of "alloc" (see enum_log_item_free).
332 On success, the number of registered items on the log line is increased,
333 the item's type is added to the log_line's "seen" property,
334 and a pointer to the item's log_item_data struct is returned for
335 convenience.
336
337 @param ll the log_line to work on
338 @param t the item-type
339 @param key the key to set on the item.
340 ignored for non-generic types (may pass nullptr for those)
341 see alloc
342 @param alloc LOG_ITEM_FREE_KEY if key was allocated by caller
343 LOG_ITEM_FREE_NONE if key was not allocated
344 Allocated keys will automatically free()d when the
345 log_item is.
346 The log_item's alloc flags will be set to the
347 submitted value; specifically, any pre-existing
348 value will be clobbered. It is therefore WRONG
349 a) to use this on a log_item that already has a key;
350 it should only be used on freshly init'd log_items;
351 b) to use this on a log_item that already has a
352 value (specifically, an allocated one); the correct
353 order is to init a log_item, then set up type and
354 key, and finally to set the value. If said value is
355 an allocated string, the log_item's alloc should be
356 bitwise or'd with LOG_ITEM_FREE_VALUE.
357
358 @retval a pointer to the log_item's log_data, for easy chaining:
359 log_line_item_set_with_key(...)->data_integer= 1;
360*/
361DECLARE_METHOD(log_item_data *, line_item_set_with_key,
362 (log_line * ll, log_item_type t, const char *key, uint32 alloc));
363
364/**
365 Create a new log item of well-known type "t" in log line "ll".
366 On success, the number of registered items on the log line is increased,
367 the item's type is added to the log_line's "seen" property,
368 and a pointer to the item's log_item_data struct is returned for
369 convenience.
370
371 The allocation of this item will be LOG_ITEM_FREE_NONE;
372 specifically, any pre-existing value will be clobbered.
373 It is therefore WRONG
374 a) to use this on a log_item that already has a key;
375 it should only be used on freshly init'd log_items;
376 b) to use this on a log_item that already has a
377 value (specifically, an allocated one); the correct
378 order is to init a log_item, then set up type and
379 key, and finally to set the value. If said value is
380 an allocated string, the log_item's alloc should be
381 bitwise or'd with LOG_ITEM_FREE_VALUE.
382
383 @param ll the log_line to work on
384 @param t the item-type
385
386 @retval a pointer to the log_item's log_data, for easy chaining:
387 log_line_item_set_with_key(...)->data_integer= 1;
388*/
389DECLARE_METHOD(log_item_data *, line_item_set,
391
392/**
393 Dynamically allocate and initialize a log_line.
394
395 @retval nullptr could not set up buffer (too small?)
396 @retval other address of the newly initialized log_line
397*/
398DECLARE_METHOD(log_line *, line_init, ());
399
400/**
401 Release a log_line allocated with line_init()
402
403 @param ll a log_line previously allocated with line_init()
404*/
405DECLARE_METHOD(void, line_exit, (log_line * ll));
406
407/**
408 How many items are currently set on the given log_line?
409
410 @param ll the log-line to examine
411
412 @retval the number of items set
413*/
414DECLARE_METHOD(int, line_item_count, (log_line * ll));
415
416/**
417 Test whether a given type is presumed present on the log line.
418
419 @param ll the log_line to examine
420 @param m the log_type to test for
421
422 @retval 0 not present
423 @retval !=0 present
424*/
425DECLARE_METHOD(log_item_type_mask, line_item_types_seen,
427
428/**
429 Get log-line's output buffer.
430 If the logger core provides this buffer, the log-service may use it
431 to assemble its output therein and implicitly return it to the core.
432 Participation is required for services that support populating
433 performance_schema.error_log, and optional for all others.
434
435 @param ll the log_line to examine
436
437 @retval nullptr success, an output buffer is available
438 @retval otherwise failure, no output buffer is available
439*/
440DECLARE_METHOD(log_item *, line_get_output_buffer, (log_line * ll));
441
442/**
443 Get an iterator for the items in a log_line.
444 For now, only one iterator may exist per log_line.
445
446 @param ll the log_line to examine
447
448 @retval a log_iter_iter, or nullptr on failure
449*/
450DECLARE_METHOD(log_item_iter *, line_item_iter_acquire, (log_line * ll));
451
452/**
453 Release an iterator for the items in a log_line.
454
455 @param it the iterator to release
456*/
457DECLARE_METHOD(void, line_item_iter_release, (log_item_iter * it));
458/**
459 Use the log_line iterator to get the first item from the set.
460
461 @param it the iterator to use
462
463 @retval pointer to the first log_item in the collection, or nullptr
464*/
465DECLARE_METHOD(log_item *, line_item_iter_first, (log_item_iter * it));
466
467/**
468 Use the log_line iterator to get the next item from the set.
469
470 @param it the iterator to use
471
472 @retval pointer to the next log_item in the collection, or nullptr
473*/
474DECLARE_METHOD(log_item *, line_item_iter_next, (log_item_iter * it));
475
476/**
477 Use the log_line iterator to get the current item from the set.
478
479 @param it the iterator to use
480
481 @retval pointer to the current log_item in the collection, or nullptr
482*/
483DECLARE_METHOD(log_item *, line_item_iter_current, (log_item_iter * it));
484
485/**
486 Complete, filter, and write submitted log items.
487
488 This expects a log_line collection of log-related key/value pairs,
489 e.g. from log_message().
490
491 Where missing, timestamp, priority, thread-ID (if any) and so forth
492 are added.
493
494 Log item source services, log item filters, and log item sinks are
495 then called; then all applicable resources are freed.
496
497 This interface is intended to facilitate the building of submission
498 interfaces other than the variadic message() one below. See the
499 example fluent C++ LogEvent() wrapper for an example of how to leverage
500 it.
501
502 @param ll key/value pairs describing info to log
503
504 @retval int number of fields in created log line
505*/
506DECLARE_METHOD(int, line_submit, (log_line * ll));
507
508/**
509 Submit a log-message for log "log_type".
510 Variadic convenience function for logging.
511
512 This fills in the array that is used by the filter and log-writer
513 services. Where missing, timestamp, priority, and thread-ID (if any)
514 are added. Log item source services, log item filters, and log item
515 writers are called.
516
517
518 The variadic list accepts a list of "assignments" of the form
519 - log_item_type, value, for well-known types, and
520 - log_item_type, key, value, for ad-hoc types (LOG_ITEM_GEN_*)
521
522 As its last item, the list should have
523 - an element of type LOG_ITEM_LOG_MESSAGE, containing a printf-style
524 format string, followed by all variables necessary to satisfy the
525 substitutions in that string
526
527 OR
528
529 - an element of type LOG_ITEM_LOG_LOOKUP, containing a MySQL error code,
530 which will be looked up in the list or regular error messages, followed
531 by all variables necessary to satisfy the substitutions in that string
532
533 OR
534
535 - an element of type LOG_ITEM_LOG_VERBATIM, containing a string that will
536 be used directly, with no % substitutions
537
538 see log_vmessage() for more information.
539*/
540DECLARE_METHOD(int, message, (int log_type, ...));
541
542/**
543 Escape \0 bytes, add \0 terminator. For log-writers and other sinks
544 that terminate in an API using C-strings.
545
546
547 @param li list_item to process
548
549 @retval -1 out of memory
550 @retval 0 success
551*/
552DECLARE_METHOD(int, sanitize, (log_item * li));
553
554/**
555 Return MySQL error message for a given error code.
556
557 @param mysql_errcode the error code the message for which to look up
558
559 @retval the message (a printf-style format string)
560*/
561DECLARE_METHOD(const char *, errmsg_by_errcode, (int mysql_errcode));
562
563/**
564 Return MySQL error code for a given error symbol.
565
566 @param sym the symbol to look up
567
568 @retval -1 failure
569 @retval >=0 the MySQL error code
570*/
571DECLARE_METHOD(longlong, errcode_by_errsymbol, (const char *sym));
572
573/**
574 Convenience function: Derive a log label ("error", "warning",
575 "information") from a severity.
576
577 @param prio the severity/prio in question
578
579 @return a label corresponding to that priority.
580 @retval "System" for prio of SYSTEM_LEVEL
581 @retval "Error" for prio of ERROR_LEVEL
582 @retval "Warning" for prio of WARNING_LEVEL
583 @retval "Note" for prio of INFORMATION_LEVEL
584*/
585DECLARE_METHOD(const char *, label_from_prio, (int prio));
586
587/**
588 Parse a ISO8601 timestamp and return the number of microseconds
589 since the epoch. Heeds +/- timezone info if present.
590
591 @see make_iso8601_timestamp()
592
593 @param timestamp an ASCII string containing an ISO8601 timestamp
594 @param len Length in bytes of the aforementioned string
595
596 @return microseconds since the epoch
597*/
598DECLARE_METHOD(ulonglong, parse_iso8601_timestamp,
599 (const char *timestamp, size_t len));
600
601/**
602 open an error log file
603
604 @param name_or_ext if beginning with '.':
605 @@global.log_error, except with this extension
606 otherwise:
607 use this as file name in the same location as
608 @@global.log_error
609
610 Value not contain folder separators!
611
612 @param[out] my_errstream an error log handle, or nullptr on failure
613
614 @returns LOG_SERVICE_SUCCESS success
615 @returns LOG_SERVICE_INVALID_ARGUMENT no my_errstream, or bad log name
616 @returns LOG_SERVICE_OUT_OF_MEMORY could not allocate file handle
617 @returns LOG_SERVICE_LOCK_ERROR couldn't lock lock
618 @returns LOG_SERVICE_UNABLE_TO_WRITE couldn't write to given location
619 @returns LOG_SERVICE_COULD_NOT_MAKE_LOG_NAME could not make log name
620*/
621DECLARE_METHOD(log_service_error, open_errstream,
622 (const char *name_or_ext, void **my_errstream));
623
624/**
625 write to an error log file previously opened with open_errstream()
626
627 @param my_errstream a handle describing the log file
628 @param buffer pointer to the string to write
629 @param length length of the string to write
630
631 @returns LOG_SERVICE_SUCCESS success
632 @returns otherwise failure
633*/
634DECLARE_METHOD(log_service_error, write_errstream,
635 (void *my_errstream, const char *buffer, size_t length));
636
637/**
638 are we writing to a dedicated errstream, or are we sharing it?
639
640 @param my_errstream a handle describing the log file
641
642 @retval 0 not dedicated (multiplexed, stderr, ...)
643 @retval 1 dedicated
644*/
645DECLARE_METHOD(int, dedicated_errstream, (void *my_errstream));
646
647/**
648 close an error log file previously opened with open_errstream()
649
650 @param my_stream a handle describing the log file
651
652 @returns LOG_SERVICE_SUCCESS on success
653*/
654DECLARE_METHOD(log_service_error, close_errstream, (void **my_errstream));
655
656/**
657 re-open an error log file
658 (primarily to facilitate flush/log-rotation)
659
660 If the new file can be opened, update the my_errstream descriptor to
661 use it and close the old file. Otherwise, keep using the old file.
662
663 @param name_or_ext if beginning with '.':
664 @@global.log_error, except with this extension
665 otherwise:
666 use this as file name in the same location as
667 @@global.log_error
668
669 Value may not contain folder separators!
670
671 In the general case, the caller will be a
672 log-writer, the log-writer will just pass
673 its preferred file extension, and the resulting
674 file name and path will therefore be the same
675 as for the original log file.
676
677 @param[in,out] my_errstream an error log handle
678
679 @returns LOG_SERVICE_INVALID_ARGUMENT, or the result of open_errstream()
680*/
681DECLARE_METHOD(log_service_error, reopen_errstream,
682 (const char *file, void **my_errstream));
683
685
686/**
687 String primitives for logging services.
688*/
689BEGIN_SERVICE_DEFINITION(log_builtins_string)
690// alloc (len+1) bytes
691DECLARE_METHOD(void *, malloc, (size_t len));
692// alloc (len+1) bytes, then copy len bytes from fm, and \0 terminate
693// like my_strndup(), and unlike strndup(), \0 in input won't end copying
694DECLARE_METHOD(char *, strndup, (const char *fm, size_t len));
695// free allocated memory
696DECLARE_METHOD(void, free, (void *ptr));
697
698// length of nul terminated byte string
699DECLARE_METHOD(size_t, length, (const char *s));
700// find char in string, from the left
701DECLARE_METHOD(char *, find_first, (const char *s, int c));
702// find char in string, from the right
703DECLARE_METHOD(char *, find_last, (const char *s, int c));
704
705// compare two NUL-terminated byte-strings
707 (const char *a, const char *b, size_t len,
708 bool case_insensitive));
709
710/**
711 Wrapper for std::snprintf()
712 Replace all % in format string with variables from list.
713 Do not use in new code; use std::snprintf() instead.
714
715 @param to buffer to write the result to
716 @param n size of that buffer
717 @param fmt format string
718 @param ap va_list with valuables for all substitutions in format string
719
720 @retval return value of snprintf
721*/
722DECLARE_METHOD(size_t, substitutev,
723 (char *to, size_t n, const char *fmt, va_list ap))
724MY_ATTRIBUTE((format(printf, 3, 0)));
725
726// replace all % in format string with variables from list (std::snprintf())
727DECLARE_METHOD(size_t, substitute, (char *to, size_t n, const char *fmt, ...))
728MY_ATTRIBUTE((format(printf, 3, 4)));
729
730END_SERVICE_DEFINITION(log_builtins_string)
731
732/**
733 Temporary primitives for logging services.
734*/
736// Are we shutting down yet? Windows EventLog needs to know.
737DECLARE_METHOD(size_t, notify_client,
738 (void *thd, uint severity, uint code, char *to, size_t n,
739 const char *format, ...))
740MY_ATTRIBUTE((format(printf, 6, 7)));
741END_SERVICE_DEFINITION(log_builtins_tmp)
742
743/**
744 Syslog/Eventlog functions for logging services.
745*/
746BEGIN_SERVICE_DEFINITION(log_builtins_syseventlog)
748 (const char *name, int option, int facility));
750 (enum loglevel level, const char *msg));
752END_SERVICE_DEFINITION(log_builtins_syseventlog)
753
754#ifdef __cplusplus
755
756#if !defined(LOG_H)
757
758extern SERVICE_TYPE(log_builtins) * log_bi;
759extern SERVICE_TYPE(log_builtins_string) * log_bs;
760
761#define log_line_init log_bi->line_init
762#define log_line_exit log_bi->line_exit
763#define log_line_item_set_with_key log_bi->line_item_set_with_key
764#define log_line_item_set log_bi->line_item_set
765#define log_line_item_types_seen log_bi->line_item_types_seen
766#define log_line_submit log_bi->line_submit
767#define log_set_int log_bi->item_set_int
768#define log_set_float log_bi->item_set_float
769#define log_set_lexstring log_bi->item_set_lexstring
770#define log_set_cstring log_bi->item_set_cstring
771#define log_line_set_flag log_bi->line_set_flag
772#define log_malloc log_bs->malloc
773#define log_free log_bs->free
774#define log_msg log_bs->substitutev
775#define error_msg_by_errcode log_bi->errmsg_by_errcode
776#define error_code_by_errsymbol log_bi->errcode_by_errsymbol
777#else
778
779#include "sql/derror.h"
780
781#define log_malloc(s) my_malloc(0, (s), MYF(0))
782#define log_free my_free
783#define log_msg vsnprintf
784#define error_msg_by_errcode error_message_for_error_log
785#define error_code_by_errsymbol mysql_symbol_to_errno
786#define log_set_int log_item_set_int
787#define log_set_float log_item_set_float
788#define log_set_lexstring log_item_set_lexstring
789#define log_set_cstring log_item_set_cstring
790
791#endif // LOG_H
792
793#ifndef DISABLE_ERROR_LOGGING
794
795#if defined(LOG_COMPONENT_TAG)
796
797#define LogErr(severity, ecode, ...) \
798 LogEvent() \
799 .prio(severity) \
800 .errcode(ecode) \
801 .subsys(LOG_SUBSYSTEM_TAG) \
802 .component(LOG_COMPONENT_TAG) \
803 .source_line(__LINE__) \
804 .source_file(MY_BASENAME) \
805 .function(__FUNCTION__) \
806 .lookup(ecode, ##__VA_ARGS__)
807
808#define LogComponentErr(severity, ecode, ...) \
809 LogEvent() \
810 .prio(severity) \
811 .errcode(ecode) \
812 .subsys(LOG_SUBSYSTEM_TAG) \
813 .component("component:" LOG_COMPONENT_TAG) \
814 .source_line(__LINE__) \
815 .source_file(MY_BASENAME) \
816 .function(__FUNCTION__) \
817 .lookup_quoted(ecode, "Component " LOG_COMPONENT_TAG " reported", \
818 ##__VA_ARGS__)
819
820#define LogPluginErr(severity, ecode, ...) \
821 LogEvent() \
822 .prio(severity) \
823 .errcode(ecode) \
824 .subsys(LOG_SUBSYSTEM_TAG) \
825 .component("plugin:" LOG_COMPONENT_TAG) \
826 .source_line(__LINE__) \
827 .source_file(MY_BASENAME) \
828 .function(__FUNCTION__) \
829 .lookup_quoted(ecode, "Plugin " LOG_COMPONENT_TAG " reported", \
830 ##__VA_ARGS__)
831
832#define LogPluginErrV(severity, ecode, vl) \
833 LogEvent() \
834 .prio(severity) \
835 .errcode(ecode) \
836 .subsys(LOG_SUBSYSTEM_TAG) \
837 .component("plugin:" LOG_COMPONENT_TAG) \
838 .source_line(__LINE__) \
839 .source_file(MY_BASENAME) \
840 .function(__FUNCTION__) \
841 .lookup_quotedv(ecode, "Plugin " LOG_COMPONENT_TAG " reported", vl)
842
843#define LogPluginErrMsg(severity, ecode, ...) \
844 LogEvent() \
845 .prio(severity) \
846 .errcode(ecode) \
847 .subsys(LOG_SUBSYSTEM_TAG) \
848 .component("plugin:" LOG_COMPONENT_TAG) \
849 .source_line(__LINE__) \
850 .source_file(MY_BASENAME) \
851 .function(__FUNCTION__) \
852 .message_quoted("Plugin " LOG_COMPONENT_TAG " reported", ##__VA_ARGS__)
853
854#else
855
856#define LogErr(severity, ecode, ...) \
857 LogEvent() \
858 .prio(severity) \
859 .errcode(ecode) \
860 .subsys(LOG_SUBSYSTEM_TAG) \
861 .source_line(__LINE__) \
862 .source_file(MY_BASENAME) \
863 .function(__FUNCTION__) \
864 .lookup(ecode, ##__VA_ARGS__)
865
866#endif
867
868#else
869
870inline void dummy_log_message(longlong severity [[maybe_unused]],
871 longlong ecode [[maybe_unused]], ...) {
872 return;
873}
874
875#define LogErr(severity, ecode, ...) \
876 dummy_log_message(severity, ecode, ##__VA_ARGS__)
877
878#define LogPluginErr(severity, ecode, ...) \
879 dummy_log_message(severity, ecode, ##__VA_ARGS__)
880#define LogPluginErrV(severity, ecode, ...) \
881 dummy_log_message(severity, ecode, ##__VA_ARGS__)
882#define LogPluginErrMsg(severity, ecode, ...) \
883 dummy_log_message(severity, ecode, ##__VA_ARGS__)
884
885#endif // DISABLE_ERROR_LOGGING
886
887/**
888 Modular logger: fluid API. Server-internal. Lets you use safe and
889 expressive syntax, like so:
890
891 LogEvent(LOG_TYPE_ERROR).prio(INFORMATION_LEVEL).message("Meow! %d", 4711);
892*/
893
894class LogEvent {
895 private:
896 log_line *ll; // Temporary allocation to hold a log-event.
897 char *msg; // Temporary allocation to hold a message.
898 const char *msg_tag;
899 bool have_msg; // Was a message set in `msg` using set_message()?
900
901 /**
902 Set MySQL error-code if none has been set yet.
903
904 @param errcode the error code (not operating system errno!)
905
906 @retval true an error occurred, value not set (OOM?)
907 @retval false value was set without incident, or did not need to be set
908 */
910 if (ll == nullptr) return true;
911
915 }
916 return false; // already set, that's OK then
917 }
918
919 /**
920 Set the error message.
921
922 @param fmt format string. % substitution will be performed.
923 @param ap va_list of the arguments for % substitution.
924 */
925 void set_message(const char *fmt, va_list ap)
926 MY_ATTRIBUTE((format(printf, 2, 0)));
927
928 /**
929 Set the error message (by MySQL error code).
930 The actual message will be looked up using this errcode.
931 As the message is a printf-style format string, % substitution
932 will be performed.
933
934 @param errcode MySQL error code to fetch the message string for
935 @param ap va_list of the arguments for % substitution.
936 */
937 void set_message_by_errcode(longlong errcode, va_list ap);
938
939 public:
940 /**
941 Destructor automatically sends the event on.
942 It is auto-free()d after processing.
943 */
945 if (ll != nullptr) {
946 log_line_submit(this->ll);
948 /*
949 If a message was set on the LogEvent using set_message,
950 the message became part of a log_item on the log_line.
951 have_msg is true. The log_line's log_items were released
952 in log_line_submit(). Null `msg` here to prevent double-free.
953
954 On the other hand, if set_message() was not used, the
955 convenience buffer was never associated with the log_line,
956 and therefore wasn't freed when the log_line was submitted.
957 In that case, we'll leave the pointer intact for clean-up
958 further down.
959 */
960 if (have_msg) msg = nullptr;
961 }
962
963 /*
964 If set_message() attached the buffer `msg` to the log_line,
965 the allocation has either been freed in log_line_submit()
966 above, or it is now owned by someone who stole it using steal().
967 In either case, msg==nullptr and we do nothing here.
968 */
969 if (msg != nullptr) log_free(msg);
970 }
971
972 /**
973 "Full customization" constructor. Use one of the LogErr() macro
974 where possible; it's there to help you remember the minimum set
975 of particles and their data-types. Be prepared for stern looks
976 from your reviewers if you use this constructor except for external
977 (loadable) services that have no error messages registered with the
978 server, and therefore need to submit them free-form.
979 */
981 have_msg = false;
982 if ((ll = log_line_init()) != nullptr) {
983 if ((msg = (char *)log_malloc(LOG_BUFF_MAX)) == nullptr) {
985 ll = nullptr;
986 }
987 } else
988 msg = nullptr;
989 msg_tag = nullptr;
990 }
991
992 /**
993 Save the log-event allocated by LogEvent().
994
995 LogEvent() internally represents the log-event in a log_line
996 structure it allocates. steal() saves this pointer to the
997 method's argument. The pointer in the LogEvent() is then
998 cleared to prevent the destructor from freeing the log_line.
999 Freeing allocated memory is now the caller's responsibility:
1000
1001 log_line *ll;
1002 LogEvent().prio(SYSTEM_LEVEL).message("Hi %s!", user).steal(&ll);
1003
1004 // Do some things with the event ...
1005
1006 log_line_item_free_all(ll);
1007 log_line_exit(ll);
1008
1009 If a message was set, the message buffer pointed to by `msg`
1010 becomes part of the log_line and is released on
1011 log_line_item_free_all() (or equivalent).
1012
1013 If no message was set, the message buffer is released when
1014 the LogEvent's destructor is called.
1015
1016 Note that verbatim() does NOT copy its argument to the
1017 LogEvent's internal allocation `msg`.
1018 Hence the life-cycle management of verbatim()'s argument
1019 would be up to the developer. When using steal(), using it
1020 with one of the set_message() wrappers is generally preferable:
1021
1022 LogEvent().message("%s", my_verbatim_string).steal(&ll);
1023
1024 @param save_to where to save the pointer to the log-event
1025 */
1026 void steal(log_line **save_to) {
1027 *save_to = ll;
1028 ll = nullptr;
1029 /*
1030 If the message was set, the allocation is now part of a log_item
1031 on the log_line. Thus, it is now owned by the called and will
1032 be released when they release the log_items on the log_line.
1033 In that case, we null our pointer to it so we won't double-free
1034 the allocation.
1035
1036 Conversely, if the buffer exists, but hasn't become part of
1037 the log_line through use of a set_message() wrapper, we'll hold
1038 on to the pointer so the empty buffer is released when we dest
1039 the LogEvent().
1040 */
1041 if (have_msg) msg = nullptr;
1042 }
1043
1044 /**
1045 Set log type.
1046
1047 @param val the log type (LOG_TYPE_ERROR)
1048
1049 @retval the LogEvent, for easy fluent-style chaining.
1050 */
1053 return *this;
1054 }
1055
1056 /**
1057 Append a numeric error code
1058
1059 @param val the MySQL error code (not operating system errno!).
1060
1061 @retval the LogEvent, for easy fluent-style chaining.
1062 */
1065 return *this;
1066 }
1067
1068 /**
1069 Append a (string) error symbol
1070
1071 @param val error symbol. NTBS.
1072
1073 @retval the LogEvent, for easy fluent-style chaining.
1074 */
1075 LogEvent &errsymbol(const char *val) {
1077 return *this;
1078 }
1079
1080 /**
1081 Append a (string) SQL state
1082
1083 @param val the SQLstate. NTBS.
1084
1085 @retval the LogEvent, for easy fluent-style chaining.
1086 */
1087 LogEvent &sqlstate(const char *val) {
1089 return *this;
1090 }
1091
1092 /**
1093 Append a numeric (operating system, as opposed to MySQL) error number.
1094
1095 @param val the operating system errno.
1096
1097 @retval the LogEvent, for easy fluent-style chaining.
1098 */
1101 return *this;
1102 }
1103
1104 /**
1105 Append a textual (operating system, as opposed to MySQL) error message,
1106 vulgo, strerror()
1107
1108 @param val the error message returned by the operating system. NTBS.
1109
1110 @retval the LogEvent, for easy fluent-style chaining.
1111 */
1112 LogEvent &os_errmsg(const char *val) {
1114 return *this;
1115 }
1116
1117 /**
1118 Which source file was the problem detected in?
1119
1120 @param val the source file's name. NTBS.
1121
1122 @retval the LogEvent, for easy fluent-style chaining.
1123 */
1124 LogEvent &source_file(const char *val) {
1126 return *this;
1127 }
1128
1129 /**
1130 Which line in the source file was the problem detected on?
1131
1132 @param val the line number.
1133
1134 @retval the LogEvent, for easy fluent-style chaining.
1135 */
1138 return *this;
1139 }
1140
1141 /**
1142 Which function in the source was the problem detected in?
1143
1144 @param val the function's name. NTBS.
1145
1146 @retval the LogEvent, for easy fluent-style chaining.
1147 */
1148 LogEvent &function(const char *val) {
1150 return *this;
1151 }
1152
1153 /**
1154 Which subsystem in the source was the problem detected in?
1155 ("Repl"/"InnoDB"/"Server")
1156
1157 @param val the subsystem. NTBS.
1158
1159 @retval the LogEvent, for easy fluent-style chaining.
1160 */
1161 LogEvent &subsys(const char *val) {
1162 if (val != nullptr)
1164 return *this;
1165 }
1166
1167 /**
1168 Which component in the source was the problem detected in?
1169 This should be the same string that is given to the
1170 component/service framework.
1171
1172 @param val the component. NTBS.
1173
1174 @retval the LogEvent, for easy fluent-style chaining.
1175 */
1176 LogEvent &component(const char *val) {
1177 if (val != nullptr)
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"). LEX_CSTRING.
1186
1187 @retval the LogEvent, for easy fluent-style chaining.
1188 */
1191 val.length);
1192 return *this;
1193 }
1194
1195 /**
1196 What user were we working for at the time of the issue?
1197
1198 @param val the user part (of "user@host"). NTBS.
1199
1200 @retval the LogEvent, for easy fluent-style chaining.
1201 */
1202 LogEvent &user(const char *val) {
1204 return *this;
1205 }
1206
1207 /**
1208 Whose session did the issue appear in?
1209
1210 @param val the host part (of "user@host"). LEX_CSTRING.
1211
1212 @retval the LogEvent, for easy fluent-style chaining.
1213 */
1216 val.length);
1217 return *this;
1218 }
1219
1220 /**
1221 Whose session did the issue appear in?
1222
1223 @param val the host part (of "user@host"). NTBS.
1224
1225 @retval the LogEvent, for easy fluent-style chaining.
1226 */
1227 LogEvent &host(const char *val) {
1229 return *this;
1230 }
1231
1232 /**
1233 What thread / "connection ID" was the issue detected in?
1234
1235 @param val the thread_ID of the session the issue appeared in
1236
1237 @retval the LogEvent, for easy fluent-style chaining.
1238 */
1241 return *this;
1242 }
1243
1244 /**
1245 What query apparently caused the issue?
1246
1247 @param val the query_ID of the offending query
1248
1249 @retval the LogEvent, for easy fluent-style chaining.
1250 */
1253 return *this;
1254 }
1255
1256 /**
1257 What table were we working on?
1258
1259 @param val the table's name/alias. NTBS.
1260
1261 @retval the LogEvent, for easy fluent-style chaining.
1262 */
1263 LogEvent &table_name(const char *val) {
1265 return *this;
1266 }
1267
1268 /**
1269 Set error message priority.
1270 Assign one of ERROR_LEVEL, WARNING_LEVEL, INFORMATION_LEVEL.
1271 log-writers and other sinks should use this value (rather
1272 than that of LOG_ITEM_LOG_EPRIO):
1273
1274 - file writers should use the value to determine
1275 what label to write (perhaps by submitting it to label_from_prio())
1276
1277 - sinks that submit the event data to a sub-system outside of
1278 the MySQL server (such as syslog, EventLog, systemd journal, etc.)
1279 should translate this value into a priority/log level understood
1280 by that target subsystem.
1281
1282 @param val The priority for this LogEvent.
1283
1284 @retval the LogEvent, for easy fluent-style chaining.
1285 */
1288 return *this;
1289 }
1290
1291 /**
1292 Set a label (usually "warning"/"error"/"information").
1293 Will be derived from prio if not set explicitly.
1294 Some log services may ignore custom labels.
1295
1296 @param val the (custom) label to set
1297
1298 @retval the LogEvent, for easy fluent-style chaining.
1299 */
1300 LogEvent &label(const char *val) {
1302 return *this;
1303 }
1304
1305 /**
1306 Add a message to the event, verbatim (i.e. with no % substitutions).
1307 This is an analog of message("%s", message); it can be used when
1308 message may contain user input or a message from another subsystem
1309 that could contain % that must not be interpreted as an invitation
1310 to do % substitutions.
1311
1312 If you use this in a context other than an external service that
1313 has no messages registered with the server, your reviewers will
1314 say unkind things about you. Use registered messages and their
1315 error codes wherever possible!
1316
1317 Combining verbatim() with steal() is discouraged as it burdens
1318 the developer with the life-cycle management of verbatim's
1319 argument. This is a result of verbatim() using its argument
1320 verbatim, rather than setting it up in the LogEvent's internal
1321 allocation `msg` using set_message(). Hence, the LogEvent has
1322 no copy of the message, which is an optimization for the
1323 common, non-steal() case.
1324
1325 @param msg_arg the message. % substitution will not happen.
1326
1327 @retval the LogEvent, for easy fluent-style chaining.
1328 */
1329 LogEvent &verbatim(const char *msg_arg) {
1331 return *this;
1332 }
1333
1334 /**
1335 Fill in a format string by substituting the % with the given
1336 arguments, then add the result as the event's message.
1337 This should be used very sparingly; use registered messages
1338 and their error codes wherever possible!
1339
1340 @param fmt message (treated as a printf-style format-string,
1341 so % substitution will happen)
1342 @param ap valist to satisfy any % in the message
1343
1344 @retval the LogEvent, for easy fluent-style chaining.
1345 */
1346 LogEvent &messagev(const char *fmt, va_list ap)
1347 MY_ATTRIBUTE((format(printf, 2, 0))) {
1348 set_message(fmt, ap);
1349 return *this;
1350 }
1351
1352 /**
1353 Fill in a format string by substituting the % with the given
1354 arguments, then add the result as the event's message.
1355
1356 If you use this in a context other than an external service that
1357 has no messages registered with the server, your reviewers will
1358 say unkind things about you. Use registered messages and their
1359 error codes wherever possible!
1360
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(const char *fmt, ...) MY_ATTRIBUTE((format(printf, 2, 3)));
1368
1369 /**
1370 Fill in a format string by substituting the % with the given
1371 arguments and tag, then add the result as the event's message.
1372
1373 @param tag Tag to prefix to message.
1374 @param fmt message (treated as a printf-style format-string,
1375 so % substitution will happen)
1376 @param ... varargs to satisfy any % in the message
1377
1378 @retval the LogEvent, for easy fluent-style chaining.
1379 */
1380 LogEvent &message_quoted(const char *tag, const char *fmt, ...)
1381 MY_ATTRIBUTE((format(printf, 3, 4))) {
1382 msg_tag = tag;
1383
1384 va_list args;
1385 va_start(args, fmt);
1386 set_message(fmt, args);
1387 va_end(args);
1388
1389 return *this;
1390 }
1391
1392 /**
1393 Find an error message by its MySQL error code.
1394 Substitute the % in that message with the given
1395 arguments, then add the result as the event's message.
1396
1397 @param errcode MySQL error code for the message in question,
1398 e.g. ER_STARTUP
1399 @param ... varargs to satisfy any % in the message
1400
1401 @retval the LogEvent, for easy fluent-style chaining.
1402 */
1404 va_list args;
1405 va_start(args, errcode);
1407 va_end(args);
1408
1409 return *this;
1410 }
1411
1412 /**
1413 Find an error message by its MySQL error code. Substitute the % in that
1414 message with the given arguments list, then add the result as the event's
1415 message.
1416
1417 @param errcode MySQL error code for the message in question,
1418 e.g. ER_STARTUP
1419 @param args varargs to satisfy any % in the message
1420
1421 @retval the LogEvent, for easy fluent-style chaining.
1422 */
1425
1426 return *this;
1427 }
1428
1429 LogEvent &lookup_quoted(longlong errcode, const char *tag, ...) {
1430 msg_tag = tag;
1431
1432 va_list args;
1433 va_start(args, tag);
1435 va_end(args);
1436
1437 return *this;
1438 }
1439
1440 LogEvent &lookup_quotedv(longlong errcode, const char *tag, va_list vl) {
1441 msg_tag = tag;
1443
1444 return *this;
1445 }
1446
1447 /**
1448 Add a ad hoc integer value with the given key.
1449
1450 @param key user-defined key (i.e. not wellknown). NTBS.
1451 @param val value.
1452
1453 @retval the LogEvent, for easy fluent-style chaining.
1454 */
1455 LogEvent &int_value(const char *key, longlong val) {
1458 val);
1459 return *this;
1460 }
1461
1462 /**
1463 Add a ad hoc (not "well-known") float value with the given key.
1464
1465 @param key user-defined key (i.e. not wellknown). NTBS.
1466 @param val value.
1467
1468 @retval the LogEvent, for easy fluent-style chaining.
1469 */
1470 LogEvent &float_value(const char *key, double val) {
1473 val);
1474 return *this;
1475 }
1476
1477 /**
1478 Add a ad hoc string value with the given key.
1479
1480 @param key user-defined key (i.e. not wellknown). NTBS.
1481 @param val value.
1482 @param len length in bytes of the value.
1483
1484 @retval the LogEvent, for easy fluent-style chaining.
1485 */
1486 LogEvent &string_value(const char *key, const char *val, size_t len) {
1490 val, len);
1491 return *this;
1492 }
1493
1494 /**
1495 Add a ad hoc string value with the given key.
1496
1497 @param key user-defined key (i.e. not wellknown). NTBS.
1498 @param val value. NTBS.
1499
1500 @retval the LogEvent, for easy fluent-style chaining.
1501 */
1502 LogEvent &string_value(const char *key, const char *val) {
1506 val);
1507 return *this;
1508 }
1509
1510 /**
1511 Mark log line to skip being additionally emitted as a telemetry log record.
1512
1513 @retval the LogEvent, for easy fluent-style chaining.
1514 */
1517 return *this;
1518 }
1519};
1520
1521inline void LogEvent::set_message_by_errcode(longlong errcode, va_list ap) {
1522 const char *fmt = error_msg_by_errcode((int)errcode);
1523
1524 if ((fmt == nullptr) || (*fmt == '\0')) fmt = "invalid error code";
1525
1527 set_message(fmt, ap);
1528}
1529
1530inline void LogEvent::set_message(const char *fmt, va_list ap) {
1531 if ((ll != nullptr) && (msg != nullptr)) {
1532 char buf[LOG_BUFF_MAX];
1533 if (msg_tag != nullptr) {
1534 snprintf(buf, LOG_BUFF_MAX, "%s: \'%s\'", msg_tag, fmt);
1535 fmt = buf;
1536 }
1537 size_t len = log_msg(msg, LOG_BUFF_MAX, fmt, ap);
1538 if (len >= LOG_BUFF_MAX) {
1539 const char ellipsis[] = " <...>";
1540 len = LOG_BUFF_MAX - 1;
1541 strcpy(&msg[LOG_BUFF_MAX - sizeof(ellipsis)], ellipsis);
1542 }
1543 log_item_data *lid;
1544 lid = log_line_item_set_with_key(this->ll, LOG_ITEM_LOG_MESSAGE, nullptr,
1546 log_set_lexstring(lid, msg, len);
1547 have_msg = true;
1548 }
1549}
1550
1551inline LogEvent &LogEvent::message(const char *fmt, ...) {
1552 va_list args;
1553 va_start(args, fmt);
1554 set_message(fmt, args);
1555 va_end(args);
1556
1557 return *this;
1558}
1559
1560// Methods initialize and de-initialize logging service for plugins.
1561#if defined(MYSQL_DYNAMIC_PLUGIN)
1562
1563/**
1564 Method to de-initialize logging service in plugin.
1565
1566 param[in,out] reg_srv Plugin registry service.
1567 param[in,out] log_bi Error logging service.
1568 param[in,out] log_bs String service for error logging.
1569*/
1570inline void deinit_logging_service_for_plugin(
1571 SERVICE_TYPE(registry) * *reg_srv, SERVICE_TYPE(log_builtins) * *log_bi,
1572 SERVICE_TYPE(log_builtins_string) * *log_bs) {
1573 using log_builtins_t = SERVICE_TYPE_NO_CONST(log_builtins);
1574 using log_builtins_string_t = SERVICE_TYPE_NO_CONST(log_builtins_string);
1575 if (*log_bi)
1576 (*reg_srv)->release(
1577 reinterpret_cast<my_h_service>(const_cast<log_builtins_t *>(*log_bi)));
1578 if (*log_bs)
1579 (*reg_srv)->release(reinterpret_cast<my_h_service>(
1580 const_cast<log_builtins_string_t *>(*log_bs)));
1582 *log_bi = nullptr;
1583 *log_bs = nullptr;
1584 *reg_srv = nullptr;
1585}
1586
1587/**
1588 Method to de-initialize logging service in plugin.
1589
1590 param[in,out] reg_srv Plugin registry service.
1591 param[in,out] log_bi Error logging service.
1592 param[in,out] log_bs String service for error logging.
1593
1594 @retval false Success.
1595 @retval true Failed.
1596*/
1597inline bool init_logging_service_for_plugin(
1598 SERVICE_TYPE(registry) * *reg_srv, SERVICE_TYPE(log_builtins) * *log_bi,
1599 SERVICE_TYPE(log_builtins_string) * *log_bs) {
1600 my_h_service log_srv = nullptr;
1601 my_h_service log_str_srv = nullptr;
1603 if (!(*reg_srv)->acquire("log_builtins.mysql_server", &log_srv) &&
1604 !(*reg_srv)->acquire("log_builtins_string.mysql_server", &log_str_srv)) {
1605 (*log_bi) = reinterpret_cast<SERVICE_TYPE(log_builtins) *>(log_srv);
1606 (*log_bs) =
1607 reinterpret_cast<SERVICE_TYPE(log_builtins_string) *>(log_str_srv);
1608 } else {
1609 deinit_logging_service_for_plugin(reg_srv, log_bi, log_bs);
1610 return true;
1611 }
1612 return false;
1613}
1614
1615#elif defined(EXTRA_CODE_FOR_UNIT_TESTING)
1616
1617/**
1618 Method is used by unit tests.
1619
1620 param[in,out] reg_srv Plugin registry service.
1621 param[in,out] log_bi Error logging service.
1622 param[in,out] log_bs String service for error logging.
1623
1624 @retval false Success.
1625 @retval true Failed.
1626*/
1627inline bool init_logging_service_for_plugin(
1628 SERVICE_TYPE(registry) * *reg_srv [[maybe_unused]],
1629 SERVICE_TYPE(log_builtins) * *log_bi [[maybe_unused]],
1630 SERVICE_TYPE(log_builtins_string) * *log_bs [[maybe_unused]])
1631
1632{
1633 return false;
1634}
1635
1636/**
1637 Method is used by unit tests.
1638
1639 param[in,out] reg_srv Plugin registry service.
1640 param[in,out] log_bi Error logging service.
1641 param[in,out] log_bs String service for error logging.
1642*/
1643inline void deinit_logging_service_for_plugin(
1644 SERVICE_TYPE(registry) * *reg_srv [[maybe_unused]],
1645 SERVICE_TYPE(log_builtins) * *log_bi [[maybe_unused]],
1646 SERVICE_TYPE(log_builtins_string) * *log_bs [[maybe_unused]]) {}
1647
1648#endif // MYSQL_DYNAMIC_PLUGIN
1649
1650#endif // __cplusplus
1651
1652#endif
Modular logger: fluid API.
Definition: log_builtins.h:894
~LogEvent()
Destructor automatically sends the event on.
Definition: log_builtins.h:944
LogEvent & host(const char *val)
Whose session did the issue appear in?
Definition: log_builtins.h:1227
LogEvent & user(const char *val)
What user were we working for at the time of the issue?
Definition: log_builtins.h:1202
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:1486
LogEvent()
"Full customization" constructor.
Definition: log_builtins.h:980
char * msg
Definition: log_builtins.h:897
LogEvent & lookup_quoted(longlong errcode, const char *tag,...)
Definition: log_builtins.h:1429
LogEvent & lookup_quotedv(longlong errcode, const char *tag, va_list vl)
Definition: log_builtins.h:1440
bool have_msg
Definition: log_builtins.h:899
LogEvent & prio(longlong val)
Set error message priority.
Definition: log_builtins.h:1286
LogEvent & subsys(const char *val)
Which subsystem in the source was the problem detected in? ("Repl"/"InnoDB"/"Server")
Definition: log_builtins.h:1161
LogEvent & errcode(longlong val)
Append a numeric error code.
Definition: log_builtins.h:1063
LogEvent & source_file(const char *val)
Which source file was the problem detected in?
Definition: log_builtins.h:1124
bool set_errcode(longlong errcode)
Set MySQL error-code if none has been set yet.
Definition: log_builtins.h:909
LogEvent & os_errno(longlong val)
Append a numeric (operating system, as opposed to MySQL) error number.
Definition: log_builtins.h:1099
LogEvent & type(enum_log_type val)
Set log type.
Definition: log_builtins.h:1051
LogEvent & thread_id(longlong val)
What thread / "connection ID" was the issue detected in?
Definition: log_builtins.h:1239
LogEvent & os_errmsg(const char *val)
Append a textual (operating system, as opposed to MySQL) error message, vulgo, strerror()
Definition: log_builtins.h:1112
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:1176
LogEvent & lookupv(longlong errcode, va_list args)
Find an error message by its MySQL error code.
Definition: log_builtins.h:1423
const char * msg_tag
Definition: log_builtins.h:898
LogEvent & verbatim(const char *msg_arg)
Add a message to the event, verbatim (i.e.
Definition: log_builtins.h:1329
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:1551
LogEvent & errsymbol(const char *val)
Append a (string) error symbol.
Definition: log_builtins.h:1075
void steal(log_line **save_to)
Definition: log_builtins.h:1026
LogEvent & table_name(const char *val)
What table were we working on?
Definition: log_builtins.h:1263
LogEvent & label(const char *val)
Set a label (usually "warning"/"error"/"information").
Definition: log_builtins.h:1300
LogEvent & source_line(longlong val)
Which line in the source file was the problem detected on?
Definition: log_builtins.h:1136
LogEvent & query_id(longlong val)
What query apparently caused the issue?
Definition: log_builtins.h:1251
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:1380
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:1346
LogEvent & sqlstate(const char *val)
Append a (string) SQL state.
Definition: log_builtins.h:1087
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:1470
log_line * ll
Definition: log_builtins.h:896
LogEvent & int_value(const char *key, longlong val)
Add a ad hoc integer value with the given key.
Definition: log_builtins.h:1455
LogEvent & user(LEX_CSTRING 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)
Add a ad hoc string value with the given key.
Definition: log_builtins.h:1502
void set_message_by_errcode(longlong errcode, va_list ap)
Set the error message (by MySQL error code).
Definition: log_builtins.h:1521
void set_message(const char *fmt, va_list ap)
Set the error message.
Definition: log_builtins.h:1530
LogEvent & lookup(longlong errcode,...)
Find an error message by its MySQL error code.
Definition: log_builtins.h:1403
LogEvent & host(LEX_CSTRING val)
Whose session did the issue appear in?
Definition: log_builtins.h:1214
LogEvent & no_telemetry()
Mark log line to skip being additionally emitted as a telemetry log record.
Definition: log_builtins.h:1515
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:761
#define log_line_item_types_seen
Definition: log_builtins.h:765
const mysql_service_log_builtins_string_t * log_bs
string built-ins
Definition: keyring_file.cc:142
void log_line_process_hook_set(log_line_processor llp)
Set the log-event processor.
Definition: log_builtins.cc:126
#define log_set_cstring
Definition: log_builtins.h:770
#define log_set_float
Definition: log_builtins.h:768
log_line_processor log_line_process_hook_get(void)
Get current log-event processor.
Definition: log_builtins.cc:140
#define log_malloc
Definition: log_builtins.h:772
#define log_line_set_flag
Definition: log_builtins.h:771
#define log_line_exit
Definition: log_builtins.h:762
#define log_line_submit
Definition: log_builtins.h:766
#define log_line_item_set
Definition: log_builtins.h:764
#define log_set_int
Definition: log_builtins.h:767
#define log_msg
Definition: log_builtins.h:774
#define error_msg_by_errcode
Definition: log_builtins.h:775
#define log_free
Definition: log_builtins.h:773
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:763
const mysql_service_log_builtins_t * log_bi
accessor built-ins
Definition: keyring_file.cc:141
#define log_set_lexstring
Definition: log_builtins.h:769
enum enum_log_service_error log_service_error
Error codes.
@ LOG_LINE_EMIT_TELEMETRY
emit log line as telemetry record
Definition: log_shared.h:161
uint64 log_line_flags_mask
a bit mask with flags describing a log line
Definition: log_shared.h:230
#define LOG_BUFF_MAX
advisory.
Definition: log_shared.h:233
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:184
@ LOG_ITEM_FREE_VALUE
Definition: log_shared.h:186
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:221
static int log_type
Definition: mi_log.cc:47
static mi_bit_type mask[]
Definition: mi_packrec.cc:141
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:201
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:190
int n
Definition: xcom_base.cc:509