$treeview $search $mathjax $extrastylesheet
artdaq_utilities
v1_04_10
$projectbrief
|
$projectbrief
|
$searchbox |
00001 00002 #include "artdaq-utilities/Plugins/MetricMacros.hh" 00003 #include "fhiclcpp/ParameterSet.h" 00004 #include "messagefacility/MessageLogger/MessageLogger.h" 00005 #define TRACE_NAME "procFile_metric" 00006 #include "trace.h" 00007 00008 #include <sys/stat.h> // mkfifo 00009 #include <fcntl.h> // open 00010 #include <stdlib.h> // exit 00011 #include <ctime> 00012 #include <string> 00013 #include <boost/thread.hpp> 00014 #include <map> 00015 00016 namespace artdaq 00017 { 00024 class ProcFileMetric : public MetricPlugin 00025 { 00026 private: 00027 std::string pipe_; 00028 std::unordered_map<std::string, std::string> value_map_; 00029 bool stopped_; 00030 boost::thread thread_; 00031 public: 00043 explicit ProcFileMetric(fhicl::ParameterSet const& config, std::string const& app_name) : MetricPlugin(config, app_name) 00044 , pipe_(pset.get<std::string>("pipe", "/tmp/eventQueueStat")) 00045 , value_map_() 00046 , stopped_(true) 00047 { 00048 auto names = pset.get<std::vector<std::string>>("names", std::vector<std::string>()); 00049 00050 for (auto name : names) 00051 { 00052 value_map_[name] = ""; 00053 } 00054 00055 int sts = mkfifo(pipe_.c_str(), 0777); 00056 if (sts != 0) { perror("ProcFileMetric mkfifo"); } 00057 TLOG(10) << "ProcFileMetric mkfifo()" << pipe_ << " sts=" << sts; 00058 startMetrics(); 00059 } 00060 00064 ~ProcFileMetric() { 00065 TLOG(11) << "~ProcFileMetric" ; 00066 stopMetrics(); 00067 } 00068 00073 std::string getLibName() const override { return "procFile"; } 00074 00080 void sendMetric_(const std::string& name, const std::string& value, const std::string&) override { 00081 if (value_map_.count(name)) { 00082 TLOG(12) << "sendMetric_ setting value=" << value; 00083 value_map_[name] = value; 00084 } 00085 } 00086 00093 void sendMetric_(const std::string& name, const int& value, const std::string& unit) override { 00094 sendMetric_(name, std::to_string(value), unit); 00095 } 00096 00103 void sendMetric_(const std::string& name, const double& value, const std::string& unit) override { 00104 sendMetric_(name, std::to_string(value), unit); 00105 } 00106 00113 void sendMetric_(const std::string& name, const float& value, const std::string& unit) override { 00114 sendMetric_(name, std::to_string(value), unit); 00115 } 00116 00123 void sendMetric_(const std::string& name, const unsigned long int& value, const std::string& unit) override 00124 { 00125 sendMetric_(name, std::to_string(value), unit); 00126 } 00127 00131 void startMetrics_() override 00132 { 00133 if (stopped_) 00134 { 00135 // start thread 00136 stopped_ = false; 00137 boost::thread::attributes attrs; 00138 attrs.set_stack_size(4096 * 2000); // 8000 KB 00139 try { 00140 thread_ = boost::thread(attrs, boost::bind(&ProcFileMetric::writePipe, this)); 00141 } 00142 catch (boost::exception const& e) 00143 { 00144 std::cerr << "Creating ProcFile Metric thread failed! e: " << boost::diagnostic_information(e) << std::endl; 00145 exit(4); 00146 } 00147 } 00148 } 00149 00153 void stopMetrics_() override 00154 { 00155 if (!stopped_) 00156 { 00157 stopped_ = true; 00158 // do read on pipe to make sure writePipe is not blocking on open 00159 TLOG(11) << "stopMetrics_ before open " << pipe_; 00160 int fd = open(pipe_.c_str(), O_RDONLY | O_NONBLOCK); 00161 if (fd == -1) { perror("stopMetrics_ open(\"r\")"); exit(1); } 00162 TLOG(10) << "stopMetrics_ between open and unlink" << pipe_ << " fd=" << fd; 00163 unlink(pipe_.c_str()); 00164 TLOG(11) << "stopMetrics_ unlinked " << pipe_; 00165 # if 0 00166 char buf[256]; 00167 read(fd, buf, sizeof(buf)); 00168 # endif 00169 usleep(10000); 00170 close(fd); 00171 TLOG(11) << "stopMetrics_ after close " << pipe_; 00172 if (thread_.joinable()) thread_.join(); 00173 } 00174 } 00175 00179 void writePipe() 00180 { 00181 while (!stopped_) 00182 { 00183 TLOG(11) << "writePipe before open"; 00184 int fd = open(pipe_.c_str(), O_WRONLY); 00185 std::string str; 00186 for (auto value : value_map_) { 00187 TLOG(10) << "writePipe open fd=" << fd << " name=" << value.first << " value=" << value.second; // can't have args b/c name may have % 00188 str += value.first + ": " + value.second + "\n"; 00189 //snprintf(buf, sizeof(buf), "%s: %lu\n", value.first.c_str(), value.second); 00190 } 00191 int sts = write(fd, str.c_str(), str.size()); 00192 TLOG(11) << "writePipe write complete sts=" << sts; 00193 close(fd); 00194 TLOG(11) << "writePipe after close -- about to usleep"; 00195 usleep(400000); // must wait to make sure other end closes 00196 } 00197 00198 } 00199 }; 00200 } //End namespace artdaq 00201 00202 DEFINE_ARTDAQ_METRIC(artdaq::ProcFileMetric)