MySQL 8.3.0
Source Code Documentation
log_service_imp.h
Go to the documentation of this file.
1/* Copyright (c) 2017, 2023, Oracle and/or its affiliates.
2
3This program is free software; you can redistribute it and/or modify
4it under the terms of the GNU General Public License, version 2.0,
5as published by the Free Software Foundation.
6
7This program is also distributed with certain software (including
8but not limited to OpenSSL) that is licensed under separate terms,
9as designated in a particular file or component or in included license
10documentation. The authors of MySQL hereby grant you an additional
11permission to link the program and your derivative works with the
12separately licensed software that they have included with MySQL.
13
14This program is distributed in the hope that it will be useful,
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17GNU General Public License, version 2.0, for more details.
18
19You should have received a copy of the GNU General Public License
20along with this program; if not, write to the Free Software
21Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
22
23/**
24@brief
25
26LOG SINKS: WRITERS
27
28There are two types of writers. "Modern services" like the XML or JSON
29writers don't care whether a key/value pair is a table name or an error
30message, or what -- a string is a string. Thus, these services have to
31cover just three cases: format as string, format as integer, or format
32as float. Trivial.
33
34The other type is services that write to a fixed format, like the
35traditional MySQL error log. The error log has a timestamp,
36connection ID, severity label, and an error message, in that exact order.
37The traditional error log service therefore doesn't attempt to process
38all the information we might send its way; it just needs to know how to
39retrieve the few items it's interested in, and about printing them in
40the prescribed order. All other information is ignored. Still simple,
41just a different kind of simple.
42
43
44INPUT
45
46So as we've seen, both kinds of writers are quite straightforward.
47It's either "handle 3 storage classes" (which is simple) or "handle as
48many specific item types are you're interested in". The first group
49(which handles any and all items) is actually the simplest, and perhaps
50easier to read and understand than the second group, as they're little
51more than a glorified
52
53 switch (item->item_class) {
54 case STRING: sprintf(buf, "%s", item->value.data_string);
55 break;
56 case INTEGER: sprintf(buf, "%d", item->value.data_integer);
57 break;
58 case FLOAT: sprintf(buf, "%f", item->value.data_float);
59 break;
60 }
61
62Anything beyond that in a given source file is usually either
63boilerplate code needed by the component framework (which is
64going to be there no matter how simple or complex our actual
65writer is) or required by the specific output format the sink
66is intended to generate (writing e.g. JSON rows or XML tags,
67escaping characters/entities in string values, indentation,
68and so on).
69
70
71ERROR MESSAGES THAT AREN'T STRINGS, AND OTHER INSANITY
72
73So what if a service is looking for the error message, but it turns
74out that message is not a string?
75
76Well, first off, the well-know items (log message, error number, ...)
77all also have a well-known storage class, so an error message for example
78shall always be of string class. Our code (submission API, filter, ...)
79ensures this. Additionally, there is code in the server to help guard
80against broken modules that violate these guarantees, so individual
81loadable services won't have to check that themselves, either.
82
83In summary, if a case like that happens, it's a bug, and it's a bug that
84we have tools to detect. The expectation is NOT that services have to
85convert data-types on the fly and be able to handle error messages that
86are numbers, or integers that come wrapped in a string, or any such
87nonsense. It is true that modern writers like XML or JSON gracefully
88handle this case at zero overhead (as they only look at storage class,
89not type or semantics), but this is very specifically NOT required of
90any service.
91*/
92
93#ifndef LOG_SERVICE_IMP_H
94#define LOG_SERVICE_IMP_H
95
98
100
102 public:
103 /**
104 Initialize a loadable logging service.
105 */
106 static void init();
107
108 /**
109 De-initialize a loadable logging service.
110 */
111 static void exit();
112
113 public: /* Service Implementations */
114 /**
115 Have the service process one log line.
116 If a run function wishes to itself use error logging
117 in case of severe failure, it may do so after FIRST
118 securing the all further calls to run() will be rejected.
119 "log_sink_test" implements an example of this.
120 */
121 static DEFINE_METHOD(int, run, (void *instance, log_line *ll));
122
123 /**
124 Flush any buffers. This function will be called by the server
125 on FLUSH ERROR LOGS. The service may write its buffers, close
126 and re-open any log files to work with log-rotation, etc.
127 The flush function MUST NOT itself log anything (as the caller
128 holds THR_LOCK_log_stack)!
129 A service implementation may provide a nullptr if it does not
130 wish to provide a flush function.
131
132 @returns <0 an error occurred
133 @returns =0 no work was done
134 @returns >0 flush completed without incident
135 */
136 static DEFINE_METHOD(log_service_error, flush, (void **instance));
137
138 /**
139 Open a new instance.
140
141 @returns <0 a new instance could not be created
142 @returns =0 success, returned handle is valid
143 */
145 (log_line * ll, void **instance));
146
147 /**
148 Close and release an instance. Flushes any buffers.
149
150 @returns <0 an error occurred
151 @returns =0 success
152 */
153 static DEFINE_METHOD(log_service_error, close, (void **instance));
154
155 /**
156 Get characteristics of a log-service.
157
158 @returns <0 an error occurred
159 @returns >=0 characteristics (a set of log_service_chistics flags)
160 */
161 static DEFINE_METHOD(int, characteristics, (void));
162
163 /**
164 Parse a single line in an error log of this format. (optional)
165
166 @returns 0 Success
167 @returns !=0 Failure (out of memory, malformed argument, etc.)
168 */
170 (const char *line_start, size_t line_length));
171
172 /**
173 Provide the name for a log file this service would access.
174
175 */
177 (void *instance, char *buf, size_t bufsize));
178};
179
180#endif /* LOG_SERVICE_IMP_H */
Definition: log_service_imp.h:101
static void exit()
De-initialize a loadable logging service.
static log_service_error get_log_name(void *instance, char *buf, size_t bufsize) noexcept
Provide the name for a log file this service would access.
Definition: log_sink_json.cc:455
static log_service_error open(log_line *ll, void **instance) noexcept
Open a new instance.
Definition: log_filter_dragnet.cc:1568
static int characteristics(void) noexcept
Get characteristics of a log-service.
Definition: log_filter_dragnet.cc:1623
static int run(void *instance, log_line *ll) noexcept
Have the service process one log line.
Definition: log_filter_dragnet.cc:1545
static log_service_error flush(void **instance) noexcept
Flush any buffers.
Definition: log_filter_dragnet.cc:1613
static log_service_error close(void **instance) noexcept
Close and release an instance.
Definition: log_filter_dragnet.cc:1589
static void init()
Initialize a loadable logging service.
static log_service_error parse_log_line(const char *line_start, size_t line_length) noexcept
Parse a single line in an error log of this format.
Definition: log_sink_json.cc:125
enum enum_log_service_error log_service_error
Error codes.
REQUIRES_SERVICE_PLACEHOLDER(registry)
LOG SINKS: WRITERS.
Definition: buf0block_hint.cc:29
#define DEFINE_METHOD(retval, name, args)
A macro to ensure method implementation has required properties, that is it does not throw exceptions...
Definition: service_implementation.h:78
log_line ("log event")
Definition: keyring_log_builtins_definition.cc:71