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>
00009 #include <fcntl.h>
00010 #include <stdlib.h>
00011 #include <ctime>
00012 #include <string>
00013 #include <thread>
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 std::thread thread_;
00031 public:
00042 explicit ProcFileMetric(fhicl::ParameterSet config) : MetricPlugin(config)
00043 , pipe_(pset.get<std::string>("pipe", "/tmp/eventQueueStat"))
00044 , value_map_()
00045 , stopped_(true)
00046 {
00047 auto names = pset.get<std::vector<std::string>>("names", std::vector<std::string>());
00048
00049 for (auto name : names)
00050 {
00051 value_map_[name] = "";
00052 }
00053
00054 int sts = mkfifo(pipe_.c_str(), 0777);
00055 if (sts != 0) { perror("ProcFileMetric mkfifo"); }
00056 TRACE(10, "ProcFileMetric mkfifo(" + pipe_ + ") sts=%d", sts);
00057 startMetrics();
00058 }
00059
00063 ~ProcFileMetric() {
00064 TRACE( 11, "~ProcFileMetric" );
00065 stopMetrics();
00066 }
00067
00072 std::string getLibName() const override { return "procFile"; }
00073
00079 void sendMetric_(const std::string& name, const std::string& value, const std::string&) override {
00080 if (value_map_.count(name)) {
00081 TRACE(12, "sendMetric_ setting value="+ value);
00082 value_map_[name] = value;
00083 }
00084 }
00085
00092 void sendMetric_(const std::string& name, const int& value, const std::string& unit) override {
00093 sendMetric(name, std::to_string(value), unit);
00094 }
00095
00102 void sendMetric_(const std::string& name, const double& value, const std::string& unit) override {
00103 sendMetric(name, std::to_string(value), unit);
00104 }
00105
00112 void sendMetric_(const std::string& name, const float& value, const std::string& unit) override {
00113 sendMetric(name, std::to_string(value), unit);
00114 }
00115
00122 void sendMetric_(const std::string& name, const unsigned long int& value, const std::string& unit) override
00123 {
00124 sendMetric(name, std::to_string(value), unit);
00125 }
00126
00130 void startMetrics_() override
00131 {
00132 if (stopped_)
00133 {
00134
00135 stopped_ = false;
00136 thread_ = std::thread(&ProcFileMetric::writePipe, this);
00137 }
00138 }
00139
00143 void stopMetrics_() override
00144 {
00145 if (!stopped_)
00146 {
00147 stopped_ = true;
00148
00149 TRACE(11, "stopMetrics_ before open " + pipe_);
00150 int fd = open(pipe_.c_str(), O_RDONLY | O_NONBLOCK);
00151 if (fd == -1) { perror("stopMetrics_ open(\"r\")"); exit(1); }
00152 TRACE(10, "stopMetrics_ between open and unlink" + pipe_ + " fd=%d", fd);
00153 unlink(pipe_.c_str());
00154 TRACE(11, "stopMetrics_ unlinked " + pipe_);
00155 # if 0
00156 char buf[256];
00157 read(fd, buf, sizeof(buf));
00158 # endif
00159 usleep(10000);
00160 close(fd);
00161 TRACE(11, "stopMetrics_ after close " + pipe_);
00162 if (thread_.joinable()) thread_.join();
00163 }
00164 }
00165
00169 void writePipe()
00170 {
00171 while (!stopped_)
00172 {
00173 TRACE(11, "writePipe before open");
00174 int fd = open(pipe_.c_str(), O_WRONLY);
00175 std::string str;
00176 for (auto value : value_map_) {
00177 TRACE(10, "writePipe open fd="+std::to_string(fd)+" name="+value.first+" value="+value.second );
00178 str += value.first + ": " + value.second + "\n";
00179
00180 }
00181 int sts = write(fd, str.c_str(), str.size());
00182 TRACE(11, "writePipe write complete sts=%d", sts);
00183 close(fd);
00184 TRACE(11, "writePipe after close -- about to usleep");
00185 usleep(400000);
00186 }
00187
00188 }
00189 };
00190 }
00191
00192 DEFINE_ARTDAQ_METRIC(artdaq::ProcFileMetric)