]> git.ipfire.org Git - thirdparty/pdns.git/blob - pdns/rec-carbon.cc
ef1204d6ec1d3231742bf7df74f6835143a64b8e
[thirdparty/pdns.git] / pdns / rec-carbon.cc
1 #ifdef HAVE_CONFIG_H
2 #include "config.h"
3 #endif
4 #include "mtasker.hh"
5 #include "syncres.hh"
6 #include "rec_channel.hh"
7 #include "iputils.hh"
8 #include "logger.hh"
9 #include "arguments.hh"
10 #include "lock.hh"
11
12
13 void doCarbonDump(void*)
14 try
15 {
16 string hostname;
17 string instance_name;
18 string namespace_name;
19 vector<string> carbonServers;
20
21 {
22 std::lock_guard<std::mutex> l(g_carbon_config_lock);
23 stringtok(carbonServers, arg()["carbon-server"], ", ");
24 namespace_name=arg()["carbon-namespace"];
25 hostname=arg()["carbon-ourname"];
26 instance_name=arg()["carbon-instance"];
27 }
28
29 if(carbonServers.empty())
30 return;
31
32 if(namespace_name.empty()) {
33 namespace_name="pdns";
34 }
35 if(hostname.empty()) {
36 char tmp[HOST_NAME_MAX+1];
37 memset(tmp, 0, sizeof(tmp));
38 if (gethostname(tmp, sizeof(tmp)) != 0) {
39 throw std::runtime_error("The 'carbon-ourname' setting has not been set and we are unable to determine the system's hostname: " + stringerror());
40 }
41 char *p = strchr(tmp, '.');
42 if(p) *p=0;
43
44 hostname=tmp;
45 boost::replace_all(hostname, ".", "_");
46 }
47 if(instance_name.empty()) {
48 instance_name="recursor";
49 }
50
51 registerAllStats();
52 string msg;
53 for(const auto& carbonServer: carbonServers) {
54 ComboAddress remote(carbonServer, 2003);
55 Socket s(remote.sin4.sin_family, SOCK_STREAM);
56
57 s.setNonBlocking();
58 s.connect(remote); // we do the connect so the first attempt happens while we gather stats
59
60 if(msg.empty()) {
61 typedef map<string,string> all_t;
62 all_t all=getAllStatsMap(StatComponent::Carbon);
63
64 ostringstream str;
65 time_t now=time(0);
66
67 for(const all_t::value_type& val : all) {
68 str<<namespace_name<<'.'<<hostname<<'.'<<instance_name<<'.'<<val.first<<' '<<val.second<<' '<<now<<"\r\n";
69 }
70 msg = str.str();
71 }
72
73 int ret=asendtcp(msg, &s); // this will actually do the right thing waiting on the connect
74 if(ret < 0)
75 g_log<<Logger::Warning<<"Error writing carbon data to "<<remote.toStringWithPort()<<": "<<stringerror()<<endl;
76 if(ret==0)
77 g_log<<Logger::Warning<<"Timeout connecting/writing carbon data to "<<remote.toStringWithPort()<<endl;
78 }
79 }
80 catch(PDNSException& e)
81 {
82 g_log<<Logger::Error<<"Error in carbon thread: "<<e.reason<<endl;
83 }
84 catch(std::exception& e)
85 {
86 g_log<<Logger::Error<<"Error in carbon thread: "<<e.what()<<endl;
87 }
88 catch(...)
89 {
90 g_log<<Logger::Error<<"Unknown error in carbon thread"<<endl;
91 }