artdaq_utilities  v1_05_00
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 <algorithm>
12 #include <boost/asio.hpp>
13 #include <chrono>
14 #include <ctime>
15 #include <iostream>
16 #include <string>
17 
18 using boost::asio::ip::tcp;
19 
20 namespace artdaq {
32 {
33 private:
34  std::string host_;
35  int port_;
36  std::string namespace_;
37  boost::asio::io_service io_service_;
38  tcp::socket socket_;
39  bool stopped_;
40  int errorCount_;
41  std::chrono::steady_clock::time_point waitStart_;
42 
43 public:
56  explicit GraphiteMetric(fhicl::ParameterSet const& config, std::string const& app_name)
57  : MetricPlugin(config, app_name)
58  , host_(pset.get<std::string>("host", "localhost"))
59  , port_(pset.get<int>("port", 2003))
60  , namespace_(pset.get<std::string>("namespace", "artdaq."))
61  , io_service_()
62  , socket_(io_service_)
63  , stopped_(true)
64  , errorCount_(0)
65  {
66  startMetrics();
67  }
68 
72  virtual ~GraphiteMetric() { stopMetrics(); }
73 
78  std::string getLibName() const override { return "graphite"; }
79 
85  void sendMetric_(const std::string& name, const std::string& value, const std::string&) override
86  {
87  if (!stopped_)
88  {
89  const auto result = std::time(0);
90  boost::asio::streambuf data;
91  auto nameTemp(name);
92  std::replace(nameTemp.begin(), nameTemp.end(), ' ', '_');
93  std::ostream out(&data);
94  out << namespace_ << nameTemp << " "
95  << value << " "
96  << result << std::endl;
97 
98  boost::system::error_code error;
99  boost::asio::write(socket_, data, error);
100  if (error)
101  {
102  errorCount_++;
103  reconnect_();
104  }
105  }
106  }
107 
114  void sendMetric_(const std::string& name, const int& value, const std::string& unit) override
115  {
116  sendMetric_(name, std::to_string(value), unit);
117  }
118 
125  void sendMetric_(const std::string& name, const double& value, const std::string& unit) override
126  {
127  sendMetric_(name, std::to_string(value), unit);
128  }
129 
136  void sendMetric_(const std::string& name, const float& value, const std::string& unit) override
137  {
138  sendMetric_(name, std::to_string(value), unit);
139  }
140 
147  void sendMetric_(const std::string& name, const unsigned long int& value, const std::string& unit) override
148  {
149  sendMetric_(name, std::to_string(value), unit);
150  }
151 
155  void startMetrics_() override
156  {
157  if (stopped_)
158  {
159  reconnect_();
160  stopped_ = false;
161  }
162  }
163 
167  void stopMetrics_() override
168  {
169  if (!stopped_)
170  {
171  socket_.shutdown(boost::asio::socket_base::shutdown_send);
172  socket_.close();
173  stopped_ = true;
174  }
175  }
176 
177 private:
181  void reconnect_()
182  {
183  if (errorCount_ < 5)
184  {
185  boost::system::error_code error;
186  tcp::resolver resolver(io_service_);
187  tcp::resolver::query query(host_, std::to_string(port_));
188  boost::asio::connect(socket_, resolver.resolve(query), error);
189  if (!error) { errorCount_ = 0; }
190  else
191  {
192  mf::LogWarning("GraphiteMetric") << "Error reconnecting socket, attempt #" << errorCount_;
193  }
194  waitStart_ = std::chrono::steady_clock::now();
195  }
196  else if (std::chrono::duration_cast<std::chrono::seconds>(std::chrono::steady_clock::now() - waitStart_).count() >= 5) //Seconds
197  {
198  errorCount_ = 0;
199  }
200  }
201 };
202 } //End namespace artdaq
203 
204 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:29
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 const &config, std::string const &app_name)
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.