]>
git.ipfire.org Git - thirdparty/pdns.git/blob - pdns/dnsdist-carbon.cc
7929dd14ae2e3acf535af37720c241f3b5640875
2 * This file is part of PowerDNS or dnsdist.
3 * Copyright -- PowerDNS.COM B.V. and its contributors
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
9 * In addition, for the avoidance of any doubt, permission is granted to
10 * link this program with OpenSSL and to (re)distribute the binaries
11 * produced as the result of such linking.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
29 #include "namespaces.hh"
33 GlobalStateHolder
<vector
<CarbonConfig
> > g_carbon
;
34 static time_t s_start
=time(0);
35 uint64_t uptimeOfProcess(const std::string
& str
)
37 return time(0) - s_start
;
40 void* carbonDumpThread()
43 auto localCarbon
= g_carbon
.getLocal();
44 for(int numloops
=0;;++numloops
) {
45 if(localCarbon
->empty()) {
49 /* this is wrong, we use the interval of the first server
50 for every single one of them */
52 const unsigned int interval
= localCarbon
->at(0).interval
;
56 for (const auto& conf
: *localCarbon
) {
57 const auto& server
= conf
.server
;
58 std::string hostname
= conf
.ourname
;
59 if(hostname
.empty()) {
61 memset(tmp
, 0, sizeof(tmp
));
62 gethostname(tmp
, sizeof(tmp
));
63 char *p
= strchr(tmp
, '.');
66 boost::replace_all(hostname
, ".", "_");
70 Socket
s(server
.sin4
.sin_family
, SOCK_STREAM
);
72 s
.connect(server
); // we do the connect so the attempt happens while we gather stats
75 for(const auto& e
: g_stats
.entries
) {
76 str
<<"dnsdist."<<hostname
<<".main."<<e
.first
<<' ';
77 if(const auto& val
= boost::get
<DNSDistStats::stat_t
*>(&e
.second
))
79 else if (const auto& dval
= boost::get
<double*>(&e
.second
))
82 str
<<(*boost::get
<DNSDistStats::statfunction_t
>(&e
.second
))(e
.first
);
83 str
<<' '<<now
<<"\r\n";
85 auto states
= g_dstates
.getLocal();
86 for(const auto& state
: *states
) {
87 string serverName
= state
->name
.empty() ? (state
->remote
.toString() + ":" + std::to_string(state
->remote
.getPort())) : state
->getName();
88 boost::replace_all(serverName
, ".", "_");
89 const string base
= "dnsdist." + hostname
+ ".main.servers." + serverName
+ ".";
90 str
<<base
<<"queries" << ' ' << state
->queries
.load() << " " << now
<< "\r\n";
91 str
<<base
<<"drops" << ' ' << state
->reuseds
.load() << " " << now
<< "\r\n";
92 str
<<base
<<"latency" << ' ' << (state
->availability
!= DownstreamState::Availability::Down
? state
->latencyUsec
/1000.0 : 0) << " " << now
<< "\r\n";
93 str
<<base
<<"senderrors" << ' ' << state
->sendErrors
.load() << " " << now
<< "\r\n";
94 str
<<base
<<"outstanding" << ' ' << state
->outstanding
.load() << " " << now
<< "\r\n";
96 for(const auto& front
: g_frontends
) {
97 if (front
->udpFD
== -1 && front
->tcpFD
== -1)
100 string frontName
= front
->local
.toString() + ":" + std::to_string(front
->local
.getPort()) + (front
->udpFD
>= 0 ? "_udp" : "_tcp");
101 boost::replace_all(frontName
, ".", "_");
102 const string base
= "dnsdist." + hostname
+ ".main.frontends." + frontName
+ ".";
103 str
<<base
<<"queries" << ' ' << front
->queries
.load() << " " << now
<< "\r\n";
105 auto localPools
= g_pools
.getLocal();
106 for (const auto& entry
: *localPools
) {
107 string poolName
= entry
.first
;
108 boost::replace_all(poolName
, ".", "_");
109 if (poolName
.empty()) {
110 poolName
= "_default_";
112 const string base
= "dnsdist." + hostname
+ ".main.pools." + poolName
+ ".";
113 const std::shared_ptr
<ServerPool
> pool
= entry
.second
;
114 str
<<base
<<"servers" << " " << pool
->countServers(false) << " " << now
<< "\r\n";
115 str
<<base
<<"servers-up" << " " << pool
->countServers(true) << " " << now
<< "\r\n";
116 if (pool
->packetCache
!= nullptr) {
117 const auto& cache
= pool
->packetCache
;
118 str
<<base
<<"cache-size" << " " << cache
->getMaxEntries() << " " << now
<< "\r\n";
119 str
<<base
<<"cache-entries" << " " << cache
->getEntriesCount() << " " << now
<< "\r\n";
120 str
<<base
<<"cache-hits" << " " << cache
->getHits() << " " << now
<< "\r\n";
121 str
<<base
<<"cache-misses" << " " << cache
->getMisses() << " " << now
<< "\r\n";
122 str
<<base
<<"cache-deferred-inserts" << " " << cache
->getDeferredInserts() << " " << now
<< "\r\n";
123 str
<<base
<<"cache-deferred-lookups" << " " << cache
->getDeferredLookups() << " " << now
<< "\r\n";
124 str
<<base
<<"cache-lookup-collisions" << " " << cache
->getLookupCollisions() << " " << now
<< "\r\n";
125 str
<<base
<<"cache-insert-collisions" << " " << cache
->getInsertCollisions() << " " << now
<< "\r\n";
126 str
<<base
<<"cache-ttl-too-shorts" << " " << cache
->getTTLTooShorts() << " " << now
<< "\r\n";
131 WriteLock
wl(&g_qcount
.queryLock
);
133 for(auto &record
: g_qcount
.records
) {
134 qname
= record
.first
;
135 boost::replace_all(qname
, ".", "_");
136 str
<<"dnsdist.querycount." << qname
<< ".queries " << record
.second
<< " " << now
<< "\r\n";
138 g_qcount
.records
.clear();
141 const string msg
= str
.str();
143 int ret
= waitForRWData(s
.getHandle(), false, 1 , 0);
145 vinfolog("Unable to write data to carbon server on %s: %s", server
.toStringWithPort(), (ret
<0 ? strerror(errno
) : "Timeout"));
149 writen2(s
.getHandle(), msg
.c_str(), msg
.size());
151 catch(std::exception
& e
) {
152 warnlog("Problem sending carbon data: %s", e
.what());
158 catch(std::exception
& e
)
160 errlog("Carbon thread died: %s", e
.what());
163 catch(PDNSException
& e
)
165 errlog("Carbon thread died, PDNSException: %s", e
.reason
);
170 errlog("Carbon thread died");