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