-
-
Notifications
You must be signed in to change notification settings - Fork 93
/
syslog.h
287 lines (257 loc) · 8.53 KB
/
syslog.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
/*
* uuid-syslog - Syslog service
* Copyright 2019 Simon Arlott
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef UUID_SYSLOG_H_
#define UUID_SYSLOG_H_
#include <Arduino.h>
#ifdef ARDUINO_ARCH_ESP8266
#include <ESP8266WiFi.h>
#else
#include <WiFi.h>
#endif
#include <WiFiUdp.h>
#include <time.h>
#include <atomic>
#include <list>
#include <memory>
#include <string>
#include <uuid/log.h>
namespace uuid {
/**
* Syslog service.
*
* - <a href="https://github.com/nomis/mcu-uuid-syslog/">Git Repository</a>
* - <a href="https://mcu-uuid-syslog.readthedocs.io/">Documentation</a>
*/
namespace syslog {
/**
* Log handler for sending messages to a syslog server.
*
* @since 1.0.0
*/
class SyslogService : public uuid::log::Handler {
public:
static constexpr size_t MAX_LOG_MESSAGES = 50; /*!< Maximum number of log messages to buffer before they are output. @since 1.0.0 */
static constexpr uint16_t DEFAULT_PORT = 514; /*!< Default UDP port to send messages to. @since 1.0.0 */
/**
* Create a new syslog service log handler.
*
* @since 1.0.0
*/
SyslogService() = default;
~SyslogService();
/**
* Register the log handler with the logging framework.
*
* @since 1.0.0
*/
void start();
/**
* Get the current log level.
*
* This only affects newly received log messages, not messages that
* have already been queued.
*
* @return The current log level.
* @since 2.0.0
*/
uuid::log::Level log_level() const;
/**
* Set the current log level.
*
* Unless this is the first time the log level is being set, this
* only affects newly received log messages, not messages that have
* already been queued.
*
* @param[in] level Minimum log level that will be sent to the
* syslog server.
* @since 2.0.0
*/
void log_level(uuid::log::Level level);
/**
* Get the maximum number of queued log messages.
*
* @return The maximum number of queued log messages.
* @since 2.0.0
*/
size_t maximum_log_messages() const;
/**
* Set the maximum number of queued log messages.
*
* Defaults to SyslogService::MAX_LOG_MESSAGES.
*
* @since 2.0.0
*/
void maximum_log_messages(size_t count);
/**
* Get the server to send messages to.
*
* @since 2.0.0
* @return IP address and UDP port of the syslog server.
*/
std::pair<IPAddress, uint16_t> destination() const;
/**
* Set the server to send messages to.
*
* To disable sending messages, set the host to `0.0.0.0` and the
* log level to uuid::log::Level::OFF (otherwise they will be
* queued but not sent).
*
* @param[in] host IP address of the syslog server.
* @param[in] port UDP port to send messages to.
* @since 2.0.0
*/
void destination(IPAddress host, uint16_t port = DEFAULT_PORT);
void destination(const char * host, uint16_t port = DEFAULT_PORT);
/**
* Get local hostname.
*
* @since 2.0.0
* @return Hostname of this device.
*/
std::string hostname() const;
/**
* Set local hostname.
*
* @param[in] hostname Hostname of this device.
* @since 2.0.0
*/
void hostname(std::string hostname);
/**
* Get mark interval.
*
* @since 2.0.0
* @return Mark interval in seconds (0 = disable).
*/
unsigned long mark_interval() const;
/**
* Set mark interval.
*
* When no messages have been sent for this period of time, a
* `-- MARK --` message will be generated automatically.
*
* @param[in] interval Mark interval in seconds (0 = disable).
* @since 2.0.0
*/
void mark_interval(unsigned long interval);
/**
* Dispatch queued log messages.
*
* @since 1.0.0
*/
void loop();
/**
* Add a new log message.
*
* This will be put in a queue for output at the next loop()
* process. The queue has a maximum size of
* get_maximum_log_messages() and will discard the oldest message
* first.
*
* @param[in] message New log message, shared by all handlers.
* @since 1.0.0
*/
virtual void operator<<(std::shared_ptr<uuid::log::Message> message);
/**
* added MichaelDvP
* query status variables
*/
size_t queued() {
return log_messages_.size();
}
bool started() {
return started_;
}
IPAddress ip() {
return ip_;
}
unsigned long message_count() {
return log_message_id_;
}
unsigned long message_fails() {
return log_message_fails_;
}
private:
/**
* Log message that has been queued.
*
* Contains an identifier sequence to indicate when log messages
* could not be output because the queue discarded one or more
* messages.
*
* @since 1.0.0
*/
class QueuedLogMessage {
public:
/**
* Create a queued log message.
*
* @param[in] id Identifier to use for the log message on the queue.
* @param[in] content Log message content.
* @since 1.0.0
*/
QueuedLogMessage(unsigned long id, std::shared_ptr<uuid::log::Message> && content);
~QueuedLogMessage() = default;
unsigned long id_; /*!< Sequential identifier for this log message. @since 1.0.0 */
struct timeval time_; /*!< Time message was received. @since 1.0.0 */
const std::shared_ptr<const uuid::log::Message> content_; /*!< Log message content. @since 1.0.0 */
private:
static bool time_good_; /*!< System time appears to be valid. @since 1.0.0 */
};
/**
* Remove messages that were queued before the log level was set.
*
* @param[in] level New log level
* @since 1.0.0
*/
void remove_queued_messages(uuid::log::Level level);
/**
* Check if it is possible to transmit to the server.
*
* @return True if it is safe to transmit a message to the server,
* otherwise false.
* @since 1.0.0
*/
bool can_transmit();
/**
* Attempt to transmit one message to the server.
*
* @param[in] message Log message to be sent.
* @return True if the message was successfully set, otherwise
* false.
* @since 1.0.0
*/
bool transmit(const QueuedLogMessage & message);
static uuid::log::Logger logger_; /*!< uuid::log::Logger instance for syslog services. @since 1.0.0 */
bool started_ = false; /*!< Flag to indicate that messages have started being transmitted. @since 1.0.0 */
WiFiUDP udp_; /*!< UDP client. @since 1.0.0 */
IPAddress ip_; /*!< Host-IP to send messages to. @since 1.0.0 */
std::string host_; /*!< Host to send messages to. */
uint16_t port_ = DEFAULT_PORT; /*!< Port to send messages to. @since 1.0.0 */
uint64_t last_transmit_ = 0; /*!< Last transmit time. @since 1.0.0 */
std::string hostname_{'-'}; /*!< Local hostname. @since 1.0.0 */
size_t maximum_log_messages_ = MAX_LOG_MESSAGES; /*!< Maximum number of log messages to buffer before they are output. @since 1.0.0 */
unsigned long log_message_id_ = 0; /*!< The next identifier to use for queued log messages. @since 1.0.0 */
std::list<QueuedLogMessage> log_messages_; /*!< Queued log messages, in the order they were received. @since 1.0.0 */
std::atomic<bool> log_messages_overflow_{false}; /*!< Check if log messages have overflowed the buffer. @since 1.0.0 */
uint64_t mark_interval_ = 0; /*!< Mark interval in milliseconds. @since 2.0.0 */
uint64_t last_message_ = 0; /*!< Last message/mark time. @since 2.0.0 */
unsigned long log_message_fails_ = 0;
};
} // namespace syslog
} // namespace uuid
#endif