]> git.ipfire.org Git - thirdparty/pdns.git/blob - pdns/remote_logger.cc
Merge pull request #4873 from mind04/ed25519
[thirdparty/pdns.git] / pdns / remote_logger.cc
1 #include <unistd.h>
2 #include "remote_logger.hh"
3 #include "config.h"
4 #ifdef PDNS_CONFIG_ARGS
5 #include "logger.hh"
6 #define WE_ARE_RECURSOR
7 #else
8 #include "dolog.hh"
9 #endif
10
11 bool RemoteLogger::reconnect()
12 {
13 if (d_socket >= 0) {
14 close(d_socket);
15 d_socket = -1;
16 }
17 try {
18 d_socket = SSocket(d_remote.sin4.sin_family, SOCK_STREAM, 0);
19 setNonBlocking(d_socket);
20 SConnectWithTimeout(d_socket, d_remote, d_timeout);
21 }
22 catch(const std::exception& e) {
23 #ifdef WE_ARE_RECURSOR
24 L<<Logger::Warning<<"Error connecting to remote logger "<<d_remote.toStringWithPort()<<": "<<e.what()<<std::endl;
25 #else
26 warnlog("Error connecting to remote logger %s: %s", d_remote.toStringWithPort(), e.what());
27 #endif
28 return false;
29 }
30 return true;
31 }
32
33 void RemoteLogger::worker()
34 {
35 if (d_asyncConnect) {
36 reconnect();
37 }
38
39 while(true) {
40 std::string data;
41 {
42 std::unique_lock<std::mutex> lock(d_writeMutex);
43 d_queueCond.wait(lock, [this]{return (!d_writeQueue.empty()) || d_exiting;});
44 if (d_exiting) {
45 return;
46 }
47 data = d_writeQueue.front();
48 d_writeQueue.pop();
49 }
50
51 try {
52 uint16_t len = static_cast<uint16_t>(data.length());
53 sendSizeAndMsgWithTimeout(d_socket, len, data.c_str(), static_cast<int>(d_timeout), nullptr, nullptr, 0, 0, 0);
54 }
55 catch(const std::runtime_error& e) {
56 #ifdef WE_ARE_RECURSOR
57 L<<Logger::Info<<"Error sending data to remote logger "<<d_remote.toStringWithPort()<<": "<< e.what()<<endl;
58 #else
59 vinfolog("Error sending data to remote logger (%s): %s", d_remote.toStringWithPort(), e.what());
60 #endif
61 while (!reconnect()) {
62 sleep(d_reconnectWaitTime);
63 }
64 }
65 }
66 }
67
68 void RemoteLogger::queueData(const std::string& data)
69 {
70 {
71 std::unique_lock<std::mutex> lock(d_writeMutex);
72 if (d_writeQueue.size() >= d_maxQueuedEntries) {
73 d_writeQueue.pop();
74 }
75 d_writeQueue.push(data);
76 }
77 d_queueCond.notify_one();
78 }
79
80 RemoteLogger::RemoteLogger(const ComboAddress& remote, uint16_t timeout, uint64_t maxQueuedEntries, uint8_t reconnectWaitTime, bool asyncConnect): d_remote(remote), d_maxQueuedEntries(maxQueuedEntries), d_timeout(timeout), d_reconnectWaitTime(reconnectWaitTime), d_asyncConnect(asyncConnect), d_thread(&RemoteLogger::worker, this)
81 {
82 if (!d_asyncConnect) {
83 reconnect();
84 }
85 }
86
87 RemoteLogger::~RemoteLogger()
88 {
89 d_exiting = true;
90 if (d_socket >= 0) {
91 close(d_socket);
92 d_socket = -1;
93 }
94 d_queueCond.notify_one();
95 d_thread.join();
96 }