]>
Commit | Line | Data |
---|---|---|
aa7929a3 | 1 | #include <unistd.h> |
aa7929a3 | 2 | #include "remote_logger.hh" |
49cfc104 | 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 | |
aa7929a3 RG |
10 | |
11 | bool RemoteLogger::reconnect() | |
12 | { | |
13 | if (d_socket >= 0) { | |
14 | close(d_socket); | |
754f300f | 15 | d_socket = -1; |
aa7929a3 | 16 | } |
c2d1d4ba | 17 | d_connected = false; |
aa7929a3 RG |
18 | try { |
19 | d_socket = SSocket(d_remote.sin4.sin_family, SOCK_STREAM, 0); | |
aa7929a3 | 20 | setNonBlocking(d_socket); |
51959320 | 21 | SConnectWithTimeout(d_socket, d_remote, d_timeout); |
aa7929a3 RG |
22 | } |
23 | catch(const std::exception& e) { | |
49cfc104 | 24 | #ifdef WE_ARE_RECURSOR |
25 | L<<Logger::Warning<<"Error connecting to remote logger "<<d_remote.toStringWithPort()<<": "<<e.what()<<std::endl; | |
26 | #else | |
27 | warnlog("Error connecting to remote logger %s: %s", d_remote.toStringWithPort(), e.what()); | |
28 | #endif | |
aa7929a3 RG |
29 | return false; |
30 | } | |
c2d1d4ba | 31 | d_connected = true; |
aa7929a3 RG |
32 | return true; |
33 | } | |
34 | ||
c2d1d4ba RG |
35 | void RemoteLogger::busyReconnectLoop() |
36 | { | |
37 | while (!reconnect()) { | |
38 | sleep(d_reconnectWaitTime); | |
39 | } | |
40 | } | |
41 | ||
aa7929a3 RG |
42 | void RemoteLogger::worker() |
43 | { | |
44 | while(true) { | |
45 | std::string data; | |
46 | { | |
47 | std::unique_lock<std::mutex> lock(d_writeMutex); | |
48 | d_queueCond.wait(lock, [this]{return (!d_writeQueue.empty()) || d_exiting;}); | |
49 | if (d_exiting) { | |
50 | return; | |
51 | } | |
52 | data = d_writeQueue.front(); | |
53 | d_writeQueue.pop(); | |
54 | } | |
55 | ||
c2d1d4ba RG |
56 | if (!d_connected) { |
57 | busyReconnectLoop(); | |
58 | } | |
59 | ||
aa7929a3 | 60 | try { |
2c570263 RG |
61 | uint16_t len = static_cast<uint16_t>(data.length()); |
62 | sendSizeAndMsgWithTimeout(d_socket, len, data.c_str(), static_cast<int>(d_timeout), nullptr, nullptr, 0, 0, 0); | |
aa7929a3 RG |
63 | } |
64 | catch(const std::runtime_error& e) { | |
49cfc104 | 65 | #ifdef WE_ARE_RECURSOR |
66 | L<<Logger::Info<<"Error sending data to remote logger "<<d_remote.toStringWithPort()<<": "<< e.what()<<endl; | |
67 | #else | |
68 | vinfolog("Error sending data to remote logger (%s): %s", d_remote.toStringWithPort(), e.what()); | |
69 | #endif | |
c2d1d4ba | 70 | busyReconnectLoop(); |
aa7929a3 RG |
71 | } |
72 | } | |
73 | } | |
74 | ||
75 | void RemoteLogger::queueData(const std::string& data) | |
76 | { | |
77 | { | |
78 | std::unique_lock<std::mutex> lock(d_writeMutex); | |
79 | if (d_writeQueue.size() >= d_maxQueuedEntries) { | |
80 | d_writeQueue.pop(); | |
81 | } | |
82 | d_writeQueue.push(data); | |
83 | } | |
84 | d_queueCond.notify_one(); | |
85 | } | |
86 | ||
7af84c28 | 87 | 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) |
aa7929a3 | 88 | { |
7af84c28 RG |
89 | if (!d_asyncConnect) { |
90 | reconnect(); | |
91 | } | |
aa7929a3 RG |
92 | } |
93 | ||
94 | RemoteLogger::~RemoteLogger() | |
95 | { | |
96 | d_exiting = true; | |
754f300f | 97 | if (d_socket >= 0) { |
aa7929a3 | 98 | close(d_socket); |
754f300f | 99 | d_socket = -1; |
c2d1d4ba | 100 | d_connected = false; |
754f300f | 101 | } |
12aff2e5 | 102 | d_queueCond.notify_one(); |
aa7929a3 RG |
103 | d_thread.join(); |
104 | } |