$treeview $search $mathjax $extrastylesheet
artdaq_utilities
v1_04_10
$projectbrief
|
$projectbrief
|
$searchbox |
00001 // graphite_metric.cc: Graphite Metric Plugin 00002 // Author: Eric Flumerfelt 00003 // Last Modified: 11/13/2014 00004 // 00005 // An implementation of the MetricPlugin for Graphite 00006 00007 #include "artdaq-utilities/Plugins/MetricMacros.hh" 00008 #include "fhiclcpp/ParameterSet.h" 00009 #include "messagefacility/MessageLogger/MessageLogger.h" 00010 00011 #include <iostream> 00012 #include <ctime> 00013 #include <string> 00014 #include <algorithm> 00015 #include <boost/asio.hpp> 00016 #include <chrono> 00017 00018 using boost::asio::ip::tcp; 00019 00020 namespace artdaq 00021 { 00032 class GraphiteMetric : public MetricPlugin 00033 { 00034 private: 00035 std::string host_; 00036 int port_; 00037 std::string namespace_; 00038 boost::asio::io_service io_service_; 00039 tcp::socket socket_; 00040 bool stopped_; 00041 int errorCount_; 00042 std::chrono::steady_clock::time_point waitStart_; 00043 public: 00056 explicit GraphiteMetric(fhicl::ParameterSet const& config, std::string const& app_name) : MetricPlugin(config, app_name) 00057 , host_(pset.get<std::string>("host", "localhost")) 00058 , port_(pset.get<int>("port", 2003)) 00059 , namespace_(pset.get<std::string>("namespace", "artdaq.")) 00060 , io_service_() 00061 , socket_(io_service_) 00062 , stopped_(true) 00063 , errorCount_(0) 00064 { 00065 startMetrics(); 00066 } 00067 00071 virtual ~GraphiteMetric() { stopMetrics(); } 00072 00077 std::string getLibName() const override { return "graphite"; } 00078 00084 void sendMetric_(const std::string& name, const std::string& value, const std::string&) override 00085 { 00086 if (!stopped_) 00087 { 00088 const auto result = std::time(0); 00089 boost::asio::streambuf data; 00090 auto nameTemp(name); 00091 std::replace(nameTemp.begin(), nameTemp.end(), ' ', '_'); 00092 std::ostream out(&data); 00093 out << namespace_ << nameTemp << " " 00094 << value << " " 00095 << result << std::endl; 00096 00097 boost::system::error_code error; 00098 boost::asio::write(socket_, data, error); 00099 if (error) 00100 { 00101 errorCount_++; 00102 reconnect_(); 00103 } 00104 } 00105 } 00106 00113 void sendMetric_(const std::string& name, const int& value, const std::string& unit) override 00114 { 00115 sendMetric_(name, std::to_string(value), unit); 00116 } 00117 00124 void sendMetric_(const std::string& name, const double& value, const std::string& unit) override 00125 { 00126 sendMetric_(name, std::to_string(value), unit); 00127 } 00128 00135 void sendMetric_(const std::string& name, const float& value, const std::string& unit) override 00136 { 00137 sendMetric_(name, std::to_string(value), unit); 00138 } 00139 00146 void sendMetric_(const std::string& name, const unsigned long int& value, const std::string& unit) override 00147 { 00148 sendMetric_(name, std::to_string(value), unit); 00149 } 00150 00154 void startMetrics_() override 00155 { 00156 if (stopped_) 00157 { 00158 reconnect_(); 00159 stopped_ = false; 00160 } 00161 } 00162 00166 void stopMetrics_() override 00167 { 00168 if (!stopped_) 00169 { 00170 socket_.shutdown(boost::asio::socket_base::shutdown_send); 00171 socket_.close(); 00172 stopped_ = true; 00173 } 00174 } 00175 00176 private: 00180 void reconnect_() 00181 { 00182 if (errorCount_ < 5) 00183 { 00184 boost::system::error_code error; 00185 tcp::resolver resolver(io_service_); 00186 tcp::resolver::query query(host_, std::to_string(port_)); 00187 boost::asio::connect(socket_, resolver.resolve(query), error); 00188 if (!error) { errorCount_ = 0; } 00189 else { mf::LogWarning("GraphiteMetric") << "Error reconnecting socket, attempt #" << errorCount_; } 00190 waitStart_ = std::chrono::steady_clock::now(); 00191 } 00192 else if (std::chrono::duration_cast<std::chrono::seconds>(std::chrono::steady_clock::now() - waitStart_).count() >= 5)//Seconds 00193 { 00194 errorCount_ = 0; 00195 } 00196 } 00197 }; 00198 } //End namespace artdaq 00199 00200 DEFINE_ARTDAQ_METRIC(artdaq::GraphiteMetric)