MySQL 8.4.0
Source Code Documentation
handler.h
Go to the documentation of this file.
1/*
2 Copyright (c) 2017, 2024, Oracle and/or its affiliates.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License, version 2.0,
6 as published by the Free Software Foundation.
7
8 This program is designed to work with certain software (including
9 but not limited to OpenSSL) that is licensed under separate terms,
10 as designated in a particular file or component or in included license
11 documentation. The authors of MySQL hereby grant you an additional
12 permission to link the program and your derivative works with the
13 separately licensed software that they have either included with
14 the program or referenced in the documentation.
15
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24*/
25
26#ifndef MYSQL_HARNESS_LOGGER_HANDLER_INCLUDED
27#define MYSQL_HARNESS_LOGGER_HANDLER_INCLUDED
28
29#include "harness_export.h"
31
32#include <fstream>
33#include <iostream>
34#include <mutex>
35#include <string>
36
37namespace mysql_harness {
38
39namespace logging {
40
41/**
42 * Base class for log message handler.
43 *
44 * This class is used to implement a log message handler. You need
45 * to implement the `do_log` primitive to process the log
46 * record. If, for some reason, the implementation is unable to log
47 * the record, and exception can be thrown that will be caught by
48 * the harness.
49 */
50class HARNESS_EXPORT Handler {
51 public:
52 /**
53 * Default identifier
54 *
55 * Every handler provides a default name which could be used as key in
56 * registry to uniquely identify it. There is no obligation to use it, it
57 * is only supplied for convenience. In case of many instances of the same
58 * handler, using a key derived from this default (such as
59 * "my_handler:instance1") is suggested.
60 *
61 * This field should be set in derived classes
62 */
63 static constexpr const char *kDefaultName = nullptr;
64
65 explicit Handler() = default;
66 explicit Handler(const Handler &) = default;
67 Handler &operator=(const Handler &) = default;
68
69 virtual ~Handler() = default;
70
71 void handle(const Record &record);
72
73 void set_level(LogLevel level) { level_ = level; }
74 LogLevel get_level() const { return level_; }
76 precision_ = precision;
77 }
78
79 /**
80 * Request to reopen underlying log sink. Should be no-op for handlers NOT
81 * writing to a file. Useful for log rotation, when the logger got the
82 * signal with the request to reopen the file. Provide a destination filename
83 * for the old file for file based handlers.
84 */
85 virtual void reopen(const std::string dst = "") = 0;
86
87 /**
88 * check if the handler has logged at least one record.
89 *
90 * @retval true if at least one record was logged
91 * @retval false if no record has been logged yet.
92 */
93 bool has_logged() const { return has_logged_; }
94
95 protected:
96 std::string format(const Record &record) const;
97
98 explicit Handler(bool format_messages, LogLevel level,
99 LogTimestampPrecision timestamp_precision);
100
101 void has_logged(bool v) { has_logged_ = v; }
102
103 private:
104 /**
105 * Log message handler primitive.
106 *
107 * This member function is implemented by subclasses to properly log
108 * a record wherever it need to be logged. If it is not possible to
109 * log the message properly, an exception should be thrown and will
110 * be caught by the caller.
111 *
112 * @param record Record containing information about the message.
113 */
114 virtual void do_log(const Record &record) = 0;
115
116 /**
117 * Flags if log messages should be formatted (prefixed with log level,
118 * timestamp, etc) before logging.
119 */
121
122 /**
123 * Log level set for the handler.
124 */
126
127 /**
128 * Timestamp precision for logging
129 */
131
132 bool has_logged_{false};
133};
134
135/**
136 * Handler to write to an output stream.
137 *
138 * @code
139 * Logger logger("my_module");
140 * ...
141 * logger.add_handler(StreamHandler(std::clog));
142 * @endcode
143 */
144class HARNESS_EXPORT StreamHandler : public Handler {
145 public:
146 static constexpr const char *kDefaultName = "stream";
147
148 explicit StreamHandler(std::ostream &stream, bool format_messages = true,
150 LogTimestampPrecision timestamp_precision =
152
153 // for the stream handler there is nothing to do
154 void reopen(const std::string /*dst*/) override {}
155
156 protected:
157 std::ostream &stream_;
158 std::mutex stream_mutex_;
159
160 private:
161 void do_log(const Record &record) override;
162};
163
164/**
165 * Handler to write to a null device such as /dev/null (unix) or NUL (windows).
166 *
167 * This handler produces no output.
168 *
169 * @code
170 * Logger logger("my_module");
171 * ...
172 * logger.add_handler(NullHandler());
173 * @endcode
174 */
175class HARNESS_EXPORT NullHandler : public Handler {
176 public:
177 static constexpr const char *kDefaultName = "null";
178
179 explicit NullHandler(bool format_messages = true,
181 LogTimestampPrecision timestamp_precision =
183
184 // for the null handler there is nothing to do
185 void reopen(const std::string /*dst*/) override {}
186
187 private:
188 void do_log(const Record &record) override;
189};
190
191/**
192 * Handler that writes to a file.
193 *
194 * @code
195 * Logger logger("my_module");
196 * ...
197 * logger.add_handler(FileHandler("/var/log/router.log"));
198 * @endcode
199 */
200class HARNESS_EXPORT FileHandler : public StreamHandler {
201 public:
202 static constexpr const char *kDefaultName = "file";
203
204 explicit FileHandler(const Path &path, bool format_messages = true,
206 LogTimestampPrecision timestamp_precision =
208 ~FileHandler() override;
209
210 void reopen(const std::string dst = "") override;
211
212 private:
213 void do_log(const Record &record) override;
214
216 std::ofstream fstream_;
217};
218
219} // namespace logging
220
221} // namespace mysql_harness
222
223#endif /* MYSQL_HARNESS_LOGGER_HANDLER_INCLUDED */
Class representing a path in a file system.
Definition: filesystem.h:63
Handler that writes to a file.
Definition: handler.h:200
std::ofstream fstream_
Definition: handler.h:216
const Path file_path_
Definition: handler.h:215
Base class for log message handler.
Definition: handler.h:50
void set_timestamp_precision(LogTimestampPrecision precision)
Definition: handler.h:75
void has_logged(bool v)
Definition: handler.h:101
virtual void do_log(const Record &record)=0
Log message handler primitive.
virtual void reopen(const std::string dst="")=0
Request to reopen underlying log sink.
LogTimestampPrecision precision_
Timestamp precision for logging.
Definition: handler.h:130
LogLevel level_
Log level set for the handler.
Definition: handler.h:125
bool format_messages_
Flags if log messages should be formatted (prefixed with log level, timestamp, etc) before logging.
Definition: handler.h:120
Handler(const Handler &)=default
LogLevel get_level() const
Definition: handler.h:74
void set_level(LogLevel level)
Definition: handler.h:73
Handler & operator=(const Handler &)=default
bool has_logged() const
check if the handler has logged at least one record.
Definition: handler.h:93
Handler to write to a null device such as /dev/null (unix) or NUL (windows).
Definition: handler.h:175
void reopen(const std::string) override
Request to reopen underlying log sink.
Definition: handler.h:185
Handler to write to an output stream.
Definition: handler.h:144
void reopen(const std::string) override
Request to reopen underlying log sink.
Definition: handler.h:154
std::ostream & stream_
Definition: handler.h:157
std::mutex stream_mutex_
Definition: handler.h:158
Logging interface for using and extending the logging subsystem.
static char * path
Definition: mysqldump.cc:149
static int record
Definition: mysqltest.cc:195
LogLevel
Log level values.
Definition: logging.h:96
LogTimestampPrecision
Log timestamp precision values.
Definition: logging.h:166
Definition: common.h:42
static int handle(int sql_errno, const char *sqlstate, const char *message, void *state)
Bridge function between the C++ API offered by this module and the C API of the parser service.
Definition: services.cc:64
Log record containing information collected by the logging system.
Definition: logging.h:188