]>
git.ipfire.org Git - thirdparty/pdns.git/blob - pdns/remote_logger.cc
2 #include "threadname.hh"
3 #include "remote_logger.hh"
8 #ifdef PDNS_CONFIG_ARGS
10 #define WE_ARE_RECURSOR
15 void CircularWriteBuffer::write(const std::string
& str
)
17 if(d_buffer
.size() + 2 + str
.size() > d_buffer
.capacity())
20 if(d_buffer
.size() + 2 + str
.size() > d_buffer
.capacity())
21 throw std::runtime_error("Full!");
23 uint16_t len
= htons(str
.size());
24 char* ptr
= (char*)&len
;
25 d_buffer
.insert(d_buffer
.end(), ptr
, ptr
+ 2);
26 d_buffer
.insert(d_buffer
.end(), str
.begin(), str
.end());
29 void CircularWriteBuffer::flush()
31 if(d_buffer
.empty()) // not optional, we report EOF otherwise
34 auto arr1
= d_buffer
.array_one();
35 auto arr2
= d_buffer
.array_two();
40 for(const auto& arr
: {arr1
, arr2
}) {
42 iov
[pos
].iov_base
= arr
.first
;
43 iov
[pos
].iov_len
= arr
.second
;
49 int res
= writev(d_fd
, iov
, pos
);
51 throw std::runtime_error("Couldn't flush a thing: "+string(strerror(errno
)));
54 throw std::runtime_error("EOF");
56 // cout<<"Flushed "<<res<<" bytes out of " << total <<endl;
57 if((size_t)res
== d_buffer
.size())
65 RemoteLogger::RemoteLogger(const ComboAddress
& remote
, uint16_t timeout
, uint64_t maxQueuedBytes
, uint8_t reconnectWaitTime
, bool asyncConnect
): d_remote(remote
), d_maxQueuedBytes(maxQueuedBytes
), d_timeout(timeout
), d_reconnectWaitTime(reconnectWaitTime
), d_asyncConnect(asyncConnect
)
67 if (!d_asyncConnect
) {
69 d_writer
= make_unique
<CircularWriteBuffer
>(d_socket
, d_maxQueuedBytes
);
71 d_thread
= std::thread(&RemoteLogger::maintenanceThread
, this);
74 bool RemoteLogger::reconnect()
81 d_socket
= SSocket(d_remote
.sin4
.sin_family
, SOCK_STREAM
, 0);
82 setNonBlocking(d_socket
);
83 SConnectWithTimeout(d_socket
, d_remote
, d_timeout
);
85 catch(const std::exception
& e
) {
86 #ifdef WE_ARE_RECURSOR
87 g_log
<<Logger::Warning
<<"Error connecting to remote logger "<<d_remote
.toStringWithPort()<<": "<<e
.what()<<std::endl
;
89 warnlog("Error connecting to remote logger %s: %s", d_remote
.toStringWithPort(), e
.what());
96 void RemoteLogger::queueData(const std::string
& data
)
102 std::unique_lock
<std::mutex
> lock(d_mutex
);
105 d_writer
->write(data
);
107 catch(std::exception
& e
) {
108 // cout << "Got exception writing: "<<e.what()<<endl;
118 void RemoteLogger::maintenanceThread()
121 #ifdef WE_ARE_RECURSOR
122 string threadName
= "pdns-r/remLog";
124 string threadName
= "dnsdist/remLog";
126 setThreadName(threadName
);
133 std::unique_lock
<std::mutex
> lock(d_mutex
);
134 if(d_writer
) { // check if it is still set
135 // cout<<"Flush"<<endl;
139 catch(std::exception
& e
) {
140 // cout<<"Flush failed!"<<endl;
147 else if(reconnect()) { // if it was zero, it will remain zero, we are the only ones setting it!
148 std::unique_lock
<std::mutex
> lock(d_mutex
);
149 d_writer
= make_unique
<CircularWriteBuffer
>(d_socket
, d_maxQueuedBytes
);
151 sleep(d_reconnectWaitTime
);
154 catch(std::exception
& e
)
156 cerr
<<"Thead died on: "<<e
.what()<<endl
;
159 RemoteLogger::~RemoteLogger()