artdaq_utilities  v1_02_03
 All Classes Namespaces Functions Variables Typedefs
graphite_metric.cc
1 // graphite_metric.cc: Graphite Metric Plugin
2 // Author: Eric Flumerfelt
3 // Last Modified: 11/13/2014
4 //
5 // An implementation of the MetricPlugin for Graphite
6 
7 #include "artdaq-utilities/Plugins/MetricMacros.hh"
8 #include "fhiclcpp/ParameterSet.h"
9 #include "messagefacility/MessageLogger/MessageLogger.h"
10 
11 #include <iostream>
12 #include <ctime>
13 #include <string>
14 #include <algorithm>
15 #include <boost/asio.hpp>
16 #include <chrono>
17 
18 using boost::asio::ip::tcp;
19 
20 namespace artdaq
21 {
33  {
34  private:
35  std::string host_;
36  int port_;
37  std::string namespace_;
38  boost::asio::io_service io_service_;
39  tcp::socket socket_;
40  bool stopped_;
41  int errorCount_;
42  std::chrono::steady_clock::time_point waitStart_;
43  public:
55  explicit GraphiteMetric(fhicl::ParameterSet config) : MetricPlugin(config)
56  , host_(pset.get<std::string>("host", "localhost"))
57  , port_(pset.get<int>("port", 2003))
58  , namespace_(pset.get<std::string>("namespace", "artdaq."))
59  , io_service_()
60  , socket_(io_service_)
61  , stopped_(true)
62  , errorCount_(0)
63  {
64  startMetrics();
65  }
66 
70  virtual ~GraphiteMetric() { stopMetrics(); }
71 
76  std::string getLibName() const override { return "graphite"; }
77 
83  void sendMetric_(const std::string& name, const std::string& value, const std::string&) override
84  {
85  if (!stopped_)
86  {
87  const auto result = std::time(0);
88  boost::asio::streambuf data;
89  auto nameTemp(name);
90  std::replace(nameTemp.begin(), nameTemp.end(), ' ', '_');
91  std::ostream out(&data);
92  out << namespace_ << nameTemp << " "
93  << value << " "
94  << result << std::endl;
95 
96  boost::system::error_code error;
97  boost::asio::write(socket_, data, error);
98  if (error)
99  {
100  errorCount_++;
101  reconnect_();
102  }
103  }
104  }
105 
112  void sendMetric_(const std::string& name, const int& value, const std::string& unit) override
113  {
114  sendMetric(name, std::to_string(value), unit);
115  }
116 
123  void sendMetric_(const std::string& name, const double& value, const std::string& unit) override
124  {
125  sendMetric(name, std::to_string(value), unit);
126  }
127 
134  void sendMetric_(const std::string& name, const float& value, const std::string& unit) override
135  {
136  sendMetric(name, std::to_string(value), unit);
137  }
138 
145  void sendMetric_(const std::string& name, const unsigned long int& value, const std::string& unit) override
146  {
147  sendMetric(name, std::to_string(value), unit);
148  }
149 
153  void startMetrics_() override
154  {
155  if (stopped_)
156  {
157  reconnect_();
158  stopped_ = false;
159  }
160  }
161 
165  void stopMetrics_() override
166  {
167  if (!stopped_)
168  {
169  socket_.shutdown(boost::asio::socket_base::shutdown_send);
170  socket_.close();
171  stopped_ = true;
172  }
173  }
174 
175  private:
179  void reconnect_()
180  {
181  if (errorCount_ < 5)
182  {
183  boost::system::error_code error;
184  tcp::resolver resolver(io_service_);
185  tcp::resolver::query query(host_, std::to_string(port_));
186  boost::asio::connect(socket_, resolver.resolve(query), error);
187  if (!error) { errorCount_ = 0; }
188  else { mf::LogWarning("GraphiteMetric") << "Error reconnecting socket, attempt #" << errorCount_; }
189  waitStart_ = std::chrono::steady_clock::now();
190  }
191  else if (std::chrono::duration_cast<std::chrono::seconds>(std::chrono::steady_clock::now() - waitStart_).count() >= 5)//Seconds
192  {
193  errorCount_ = 0;
194  }
195  }
196  };
197 } //End namespace artdaq
198 
199 DEFINE_ARTDAQ_METRIC(artdaq::GraphiteMetric)
void sendMetric_(const std::string &name, const double &value, const std::string &unit) override
Send a metric to Graphite.
The MetricPlugin class defines the interface that MetricManager uses to send metric data to the vario...
Definition: MetricPlugin.hh:22
void startMetrics()
Perform startup actions. Simply calls the virtual startMetrics_ function.
fhicl::ParameterSet pset
The ParameterSet used to configure the MetricPlugin.
std::string getLibName() const override
Get the library name for the Graphite metric.
void sendMetric_(const std::string &name, const int &value, const std::string &unit) override
Send a metric to Graphite.
void sendMetric_(const std::string &name, const std::string &value, const std::string &) override
Send a metric to Graphite.
void startMetrics_() override
Perform startup actions. For Graphite, this means reconnecting the socket.
void stopMetrics()
Perform shutdown actions. Zeroes out all accumulators, and sends zeros for each metric. Calls stopMetrics_() for any plugin-defined shutdown actions.
virtual ~GraphiteMetric()
GraphiteMetric Destructor. Calls stopMetrics()
void sendMetric_(const std::string &name, const float &value, const std::string &unit) override
Send a metric to Graphite.
GraphiteMetric(fhicl::ParameterSet config)
GraphiteMetric Constructor.
void stopMetrics_() override
Perform shutdown actions. This shuts down the socket and closes it.
Send a metric to Graphite.
void sendMetric_(const std::string &name, const unsigned long int &value, const std::string &unit) override
Send a metric to Graphite.
void sendMetric(const std::string &name, const std::string &value, const std::string &unit, bool accumulate=true)
Send a metric value to the MetricPlugin.