]>
Commit | Line | Data |
---|---|---|
12471842 PL |
1 | /* |
2 | * This file is part of PowerDNS or dnsdist. | |
3 | * Copyright -- PowerDNS.COM B.V. and its contributors | |
4 | * | |
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. | |
8 | * | |
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. | |
12 | * | |
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. | |
17 | * | |
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. | |
21 | */ | |
68ee58b6 | 22 | #ifdef HAVE_CONFIG_H |
23 | #include "config.h" | |
24 | #endif | |
25 | #include "iputils.hh" | |
26 | #include "dolog.hh" | |
27 | #include "sstuff.hh" | |
fa8fd4d2 | 28 | |
68ee58b6 | 29 | #include "namespaces.hh" |
30 | #undef L | |
31 | #include "dnsdist.hh" | |
32 | ||
d617b22c | 33 | GlobalStateHolder<vector<CarbonConfig> > g_carbon; |
61d1b966 | 34 | static time_t s_start=time(0); |
35 | uint64_t uptimeOfProcess(const std::string& str) | |
36 | { | |
37 | return time(0) - s_start; | |
38 | } | |
68ee58b6 | 39 | |
40 | void* carbonDumpThread() | |
41 | try | |
42 | { | |
43 | auto localCarbon = g_carbon.getLocal(); | |
44 | for(int numloops=0;;++numloops) { | |
d617b22c | 45 | if(localCarbon->empty()) { |
68ee58b6 | 46 | sleep(1); |
47 | continue; | |
48 | } | |
d617b22c RG |
49 | /* this is wrong, we use the interval of the first server |
50 | for every single one of them */ | |
51 | if(numloops) { | |
52 | const unsigned int interval = localCarbon->at(0).interval; | |
53 | sleep(interval); | |
3565320b | 54 | } |
d617b22c RG |
55 | |
56 | for (const auto& conf : *localCarbon) { | |
57 | const auto& server = conf.server; | |
58 | std::string hostname = conf.ourname; | |
59 | if(hostname.empty()) { | |
60 | char tmp[80]; | |
61 | memset(tmp, 0, sizeof(tmp)); | |
62 | gethostname(tmp, sizeof(tmp)); | |
63 | char *p = strchr(tmp, '.'); | |
64 | if(p) *p=0; | |
65 | hostname=tmp; | |
66 | boost::replace_all(hostname, ".", "_"); | |
67 | } | |
68 | ||
3565320b RG |
69 | try { |
70 | Socket s(server.sin4.sin_family, SOCK_STREAM); | |
71 | s.setNonBlocking(); | |
72 | s.connect(server); // we do the connect so the attempt happens while we gather stats | |
73 | ostringstream str; | |
74 | time_t now=time(0); | |
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)) | |
78 | str<<(*val)->load(); | |
af619119 RG |
79 | else if (const auto& dval = boost::get<double*>(&e.second)) |
80 | str<<**dval; | |
3565320b RG |
81 | else |
82 | str<<(*boost::get<DNSDistStats::statfunction_t>(&e.second))(e.first); | |
83 | str<<' '<<now<<"\r\n"; | |
84 | } | |
85 | const auto states = g_dstates.getCopy(); | |
af619119 RG |
86 | for(const auto& state : states) { |
87 | string serverName = state->getName(); | |
3565320b RG |
88 | boost::replace_all(serverName, ".", "_"); |
89 | const string base = "dnsdist." + hostname + ".main.servers." + serverName + "."; | |
af619119 RG |
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"; | |
3565320b RG |
95 | } |
96 | for(const auto& front : g_frontends) { | |
97 | if (front->udpFD == -1 && front->tcpFD == -1) | |
98 | continue; | |
963bef8d | 99 | |
3565320b RG |
100 | string frontName = front->local.toStringWithPort() + (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"; | |
104 | } | |
9e9be156 RG |
105 | const auto localPools = g_pools.getCopy(); |
106 | for (const auto& entry : localPools) { | |
107 | string poolName = entry.first; | |
108 | boost::replace_all(poolName, ".", "_"); | |
109 | if (poolName.empty()) { | |
110 | poolName = "_default_"; | |
111 | } | |
112 | const string base = "dnsdist." + hostname + ".main.pools." + poolName + "."; | |
113 | const std::shared_ptr<ServerPool> pool = entry.second; | |
114 | str<<base<<"servers" << " " << pool->servers.size() << " " << now << "\r\n"; | |
115 | if (pool->packetCache != nullptr) { | |
116 | const auto& cache = pool->packetCache; | |
117 | str<<base<<"cache-size" << " " << cache->getMaxEntries() << " " << now << "\r\n"; | |
118 | str<<base<<"cache-entries" << " " << cache->getEntriesCount() << " " << now << "\r\n"; | |
119 | str<<base<<"cache-hits" << " " << cache->getHits() << " " << now << "\r\n"; | |
120 | str<<base<<"cache-misses" << " " << cache->getMisses() << " " << now << "\r\n"; | |
121 | str<<base<<"cache-deferred-inserts" << " " << cache->getDeferredInserts() << " " << now << "\r\n"; | |
122 | str<<base<<"cache-deferred-lookups" << " " << cache->getDeferredLookups() << " " << now << "\r\n"; | |
123 | str<<base<<"cache-lookup-collisions" << " " << cache->getLookupCollisions() << " " << now << "\r\n"; | |
124 | str<<base<<"cache-insert-collisions" << " " << cache->getInsertCollisions() << " " << now << "\r\n"; | |
cc8cefe1 | 125 | str<<base<<"cache-ttl-too-shorts" << " " << cache->getTTLTooShorts() << " " << now << "\r\n"; |
9e9be156 RG |
126 | } |
127 | } | |
786e4d8c RS |
128 | |
129 | { | |
130 | WriteLock wl(&g_qcount.queryLock); | |
131 | std::string qname; | |
132 | for(auto &record: g_qcount.records) { | |
133 | qname = record.first; | |
134 | boost::replace_all(qname, ".", "_"); | |
135 | str<<"dnsdist.querycount." << qname << ".queries " << record.second << " " << now << "\r\n"; | |
136 | } | |
137 | g_qcount.records.clear(); | |
138 | } | |
139 | ||
3565320b | 140 | const string msg = str.str(); |
a1a787dc | 141 | |
3565320b RG |
142 | int ret = waitForRWData(s.getHandle(), false, 1 , 0); |
143 | if(ret <= 0 ) { | |
144 | vinfolog("Unable to write data to carbon server on %s: %s", server.toStringWithPort(), (ret<0 ? strerror(errno) : "Timeout")); | |
145 | continue; | |
146 | } | |
147 | s.setBlocking(); | |
a683e8bd | 148 | writen2(s.getHandle(), msg.c_str(), msg.size()); |
3565320b RG |
149 | } |
150 | catch(std::exception& e) { | |
151 | warnlog("Problem sending carbon data: %s", e.what()); | |
68ee58b6 | 152 | } |
68ee58b6 | 153 | } |
154 | } | |
155 | return 0; | |
156 | } | |
157 | catch(std::exception& e) | |
158 | { | |
159 | errlog("Carbon thread died: %s", e.what()); | |
160 | return 0; | |
161 | } | |
162 | catch(PDNSException& e) | |
163 | { | |
164 | errlog("Carbon thread died, PDNSException: %s", e.reason); | |
165 | return 0; | |
166 | } | |
167 | catch(...) | |
168 | { | |
169 | errlog("Carbon thread died"); | |
170 | return 0; | |
171 | } |