MySQL  8.0.21
Source Code Documentation
log_service_imp.h
Go to the documentation of this file.
1 /* Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
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 @brief
25 
26 LOG SINKS: WRITERS
27 
28 There are two types of writers. "Modern services" like the XML or JSON
29 writers don't care whether a key/value pair is a table name or an error
30 message, or what -- a string is a string. Thus, these services have to
31 cover just three cases: format as string, format as integer, or format
32 as float. Trivial.
33 
34 The other type is services that write to a fixed format, like the
35 traditional MySQL error log. The error log has a timestamp,
36 connection ID, severity label, and an error message, in that exact order.
37 The traditional error log service therefore doesn't attempt to process
38 all the information we might send its way; it just needs to know how to
39 retrieve the few items it's interested in, and about printing them in
40 the prescribed order. All other information is ignored. Still simple,
41 just a different kind of simple.
42 
43 
44 INPUT
45 
46 So as we've seen, both kinds of writers are quite straightforward.
47 It's either "handle 3 storage classes" (which is simple) or "handle as
48 many specific item types are you're interested in". The first group
49 (which handles any and all items) is actually the simplest, and perhaps
50 easier to read and understand than the second group, as they're little
51 more 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 
62 Anything beyond that in a given source file is usually either
63 boilerplate code needed by the component framework (which is
64 going to be there no matter how simple or complex our actual
65 writer is) or required by the specific output format the sink
66 is intended to generate (writing e.g. JSON rows or XML tags,
67 escaping characters/entities in string values, indentation,
68 and so on).
69 
70 
71 ERROR MESSAGES THAT AREN'T STRINGS, AND OTHER INSANITY
72 
73 So what if a service is looking for the error message, but it turns
74 out that message is not a string?
75 
76 Well, first off, the well-know items (log message, error number, ...)
77 all also have a well-known storage class, so an error message for example
78 shall always be of string class. Our code (submission API, filter, ...)
79 ensures this. Additionally, there is code in the server to help guard
80 against broken modules that violate these guarantees, so individual
81 loadable services won't have to check that themselves, either.
82 
83 In summary, if a case like that happens, it's a bug, and it's a bug that
84 we have tools to detect. The expectation is NOT that services have to
85 convert data-types on the fly and be able to handle error messages that
86 are numbers, or integers that come wrapped in a string, or any such
87 nonsense. It is true that modern writers like XML or JSON gracefully
88 handle this case at zero overhead (as they only look at storage class,
89 not type or semantics), but this is very specifically NOT required of
90 any service.
91 */
92 
93 #ifndef LOG_SERVICE_IMP_H
94 #define LOG_SERVICE_IMP_H
95 
98 
99 extern REQUIRES_SERVICE_PLACEHOLDER(registry);
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  @param instance State-pointer that was returned on open.
122  @param ll The log_line collection of log_items.
123 
124  @retval <0 an error occurred
125  @retval =0 no work was done
126  @retval >0 number of processed entities
127  */
128  static DEFINE_METHOD(int, run, (void *instance, log_line *ll));
129 
130  /**
131  Flush any buffers. This function will be called by the server
132  on FLUSH ERROR LOGS. The service may write its buffers, close
133  and re-open any log files to work with log-rotation, etc.
134  The flush function MUST NOT itself log anything!
135  A service implementation may provide a nullptr if it does not
136  wish to provide a flush function.
137 
138  @param instance State-pointer that was returned on open.
139  Value may be changed in flush.
140 
141  @retval <0 an error occurred
142  @retval =0 no work was done
143  @retval >0 flush completed without incident
144  */
145  static DEFINE_METHOD(int, flush, (void **instance));
146 
147  /**
148  Open a new instance.
149 
150  @param ll optional arguments
151  @param instance If state is needed, the service may allocate and
152  initialize it and return a pointer to it here.
153  (This of course is particularly pertinent to
154  components that may be opened multiple times,
155  such as the JSON log writer.)
156  This state is for use of the log-service component
157  in question only and can take any layout suitable
158  to that component's need. The state is opaque to
159  the server/logging framework. It must be released
160  on close.
161 
162  @retval <0 a new instance could not be created
163  @retval =0 success, returned hande is valid
164  */
165  static DEFINE_METHOD(int, open, (log_line * ll, void **instance));
166 
167  /**
168  Close and release an instance. Flushes any buffers.
169 
170  @param instance State-pointer that was returned on open.
171  If memory was allocated for this state,
172  it should be released, and the pointer
173  set to nullptr.
174 
175  @retval <0 an error occurred
176  @retval =0 success
177  */
178  static DEFINE_METHOD(int, close, (void **instance));
179 
180  /**
181  Get characteristics of a log-service.
182 
183  @retval <0 an error occurred
184  @retval >=0 characteristics (a set of log_service_chistics flags)
185  */
186  static DEFINE_METHOD(int, characteristics, (void));
187 };
188 
189 #endif /* LOG_SERVICE_IMP_H */
static int characteristics(void) noexcept
Get characteristics of a log-service.
Definition: log_filter_dragnet.cc:1625
static int run(void *instance, log_line *ll) noexcept
Have the service process one log line.
Definition: log_filter_dragnet.cc:1545
log_line ("log event")
Definition: log_builtins_imp.h:126
REQUIRES_SERVICE_PLACEHOLDER(registry)
LOG SINKS: WRITERS.
static void init()
Initialize a loadable logging service.
#define DEFINE_METHOD(retval, name, args)
static int close(void **instance) noexcept
Close and release an instance.
Definition: log_filter_dragnet.cc:1589
static void exit()
De-initialize a loadable logging service.
static int open(log_line *ll, void **instance) noexcept
Open a new instance.
Definition: log_filter_dragnet.cc:1568
static int flush(void **instance) noexcept
Flush any buffers.
Definition: log_filter_dragnet.cc:1615
Definition: log_service_imp.h:101