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