0.9.8.10
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
MetricsCollectorGanglia.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2007-2015 Hypertable, Inc.
3  *
4  * This file is part of Hypertable.
5  *
6  * Hypertable is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; version 3
9  * of the License.
10  *
11  * Hypertable is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19  * 02110-1301, USA.
20  */
21 
27 
28 #include <Common/Compat.h>
29 
31 
32 #include <Common/InetAddr.h>
33 #include <Common/Logger.h>
34 
35 extern "C" {
36 #if defined(__APPLE__) || defined(__sun__) || defined(__FreeBSD__)
37 #include <arpa/inet.h>
38 #include <netinet/ip.h>
39 #endif
40 #include <fcntl.h>
41 #include <netdb.h>
42 #include <netinet/in.h>
43 #include <netinet/tcp.h>
44 #include <poll.h>
45 #include <sys/socket.h>
46 #include <sys/types.h>
47 #include <arpa/inet.h>
48 }
49 
50 #include <cerrno>
51 
52 using namespace Hypertable;
53 using namespace std;
54 
56  PropertiesPtr &props) {
57  InetAddr local_addr(INADDR_ANY, 0);
58 
59  m_port = props->get_i16("Hypertable.Metrics.Ganglia.Port");
60 
61  m_disabled = props->get_bool("Hypertable.Metrics.Ganglia.Disable");
62 
63  m_prefix = "ht." + component + ".";
64 
65  if ((m_sd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
66  HT_FATALF("socket(AF_INET, SOCK_DGRAM, 0) failure - %s", strerror(errno));
67 
68  {
69  int opt;
70 #if defined(__linux__)
71  opt = 0x10;
72  setsockopt(m_sd, SOL_IP, IP_TOS, &opt, sizeof(opt));
73  opt = 0x10;
74  setsockopt(m_sd, SOL_SOCKET, SO_PRIORITY, &opt, sizeof(opt));
75 #elif defined(__APPLE__) || defined(__sun__) || defined(__FreeBSD__)
76  opt = IPTOS_LOWDELAY; /* see <netinet/in.h> */
77  setsockopt(m_sd, IPPROTO_IP, IP_TOS, &opt, sizeof(opt));
78 #endif
79  }
80 
81  if ((::bind(m_sd, (const sockaddr *)&local_addr, sizeof(sockaddr_in))) < 0)
82  HT_FATALF("bind(%s) failure - %s", local_addr.format().c_str(), strerror(errno));
83 
84 }
85 
87  ::close(m_sd);
88 }
89 
90 void MetricsCollectorGanglia::update(const std::string &name, const std::string &value) {
91  lock_guard<mutex> lock(m_mutex);
92  m_values_string[m_prefix + name] = value;
93 }
94 
95 void MetricsCollectorGanglia::update(const std::string &name, int16_t value) {
96  lock_guard<mutex> lock(m_mutex);
97  m_values_int[m_prefix + name] = (int32_t)value;
98 }
99 
100 void MetricsCollectorGanglia::update(const std::string &name, int32_t value) {
101  lock_guard<mutex> lock(m_mutex);
102  m_values_int[m_prefix + name] = value;
103 }
104 
105 void MetricsCollectorGanglia::update(const std::string &name, float value) {
106  lock_guard<mutex> lock(m_mutex);
107  m_values_double[m_prefix + name] = (double)value;
108 }
109 
110 void MetricsCollectorGanglia::update(const std::string &name, double value) {
111  lock_guard<mutex> lock(m_mutex);
112  m_values_double[m_prefix + name] = value;
113 }
114 
116  lock_guard<mutex> lock(m_mutex);
117 
118  if (m_disabled)
119  return;
120 
121  if (!m_connected)
122  this->connect();
123 
124  bool first = true;
125  char cbuf[64];
126 
127  m_message.clear();
128  m_message.append("{ ");
129 
130  for (auto & entry : m_values_string) {
131  if (!first)
132  m_message.append(", \"");
133  else {
134  m_message.append("\"");
135  first = false;
136  }
137  m_message.append(entry.first);
138  m_message.append("\": \"");
139  m_message.append(entry.second);
140  m_message.append("\"");
141  }
142 
143  for (auto & entry : m_values_int) {
144  if (!first)
145  m_message.append(", \"");
146  else {
147  m_message.append("\"");
148  first = false;
149  }
150  m_message.append(entry.first);
151  m_message.append("\": ");
152  sprintf(cbuf, "%d", entry.second);
153  m_message.append(cbuf);
154  }
155 
156  for (auto & entry : m_values_double) {
157  if (!first)
158  m_message.append(", \"");
159  else {
160  m_message.append("\"");
161  first = false;
162  }
163  m_message.append(entry.first);
164  m_message.append("\": ");
165  sprintf(cbuf, "%f", entry.second);
166  m_message.append(cbuf);
167  }
168 
169  m_message.append(" }");
170 
171  if (::send(m_sd, m_message.c_str(), m_message.length(), 0) < 0)
172  HT_THROW(Error::COMM_SEND_ERROR, strerror(errno));
173 
174 }
175 
177  InetAddr addr("localhost", m_port);
178  if (::connect(m_sd, (struct sockaddr *) &addr, sizeof(sockaddr_in)) < 0) {
179  m_connected = false;
180  HT_THROW(Error::COMM_CONNECT_ERROR, strerror(errno));
181  }
182  m_connected = true;
183 }
Declarations for MetricsCollectorGanglia.
STL namespace.
Encapsulate an internet address.
Definition: InetAddr.h:66
std::shared_ptr< Properties > PropertiesPtr
Definition: Properties.h:447
Logging routines and macros.
Compatibility Macros for C/C++.
String format(int sep= ':') const
Returns a string with a dotted notation ("127.0.0.1:8080") including the port.
Definition: InetAddr.h:132
Hypertable definitions
void update(const std::string &name, const std::string &value) override
Updates string metric value.
#define HT_FATALF(msg,...)
Definition: Logger.h:343
void connect()
Connects to Ganglia hypertable extension receive port.
MetricsCollectorGanglia(const std::string &component, PropertiesPtr &props)
Constructor.
Internet address wrapper classes and utility functions.
#define HT_THROW(_code_, _msg_)
Definition: Error.h:478
void publish() override
Publishes metric values to Ganglia hypertable extension.