1 #include "otsdaq/ARTDAQSupervisor/ARTDAQSupervisorTRACEController.h"
9 ots::ARTDAQSupervisorTRACEController::ARTDAQSupervisorTRACEController() {}
13 static size_t parseOtsTraceLevels(
const std::string& otsOutput,
14 ots::ITRACEController::HostTraceLevelMap& outMap)
16 static const std::string hostTag =
"#OTSTRACE-HOST ";
17 std::set<std::string> hostsSeen;
18 std::istringstream stream(otsOutput);
22 while(std::getline(stream, line))
24 if(line.rfind(hostTag, 0) == 0)
26 std::string host = line.substr(hostTag.size());
27 while(!host.empty() &&
28 (host.back() ==
'\r' || host.back() ==
' ' || host.back() ==
'\t'))
32 auto pos = host.find(
"-data");
33 if(pos != std::string::npos)
35 pos = host.find(
"-ipmi");
36 if(pos != std::string::npos)
40 hostsSeen.insert(curKey);
43 if(line.rfind(
"#OTSTRACE", 0) == 0)
45 if(line.rfind(
"#OTSTRACE-END", 0) == 0)
52 std::istringstream iss(line);
53 std::string name, sM, sS, sT;
54 if(!(iss >> name >> sM >> sS >> sT))
58 uint64_t M = std::stoull(sM,
nullptr, 0);
59 uint64_t S = std::stoull(sS,
nullptr, 0);
60 uint64_t T = std::stoull(sT,
nullptr, 0);
61 outMap[curKey][name].M = M;
62 outMap[curKey][name].S = S;
63 outMap[curKey][name].T = T;
70 return hostsSeen.size();
73 const ots::ITRACEController::HostTraceLevelMap&
76 __COUT__ <<
"getTraceLevels() BEGIN" << __E__;
78 traceLevelsMap_.clear();
80 ots::ITRACEController::addTraceLevelsForThisHost();
86 time_t now = time(
nullptr);
87 if(!lastSetLevels_.empty() && (now - lastSetTime_) < 5)
89 __COUT__ <<
"Using cached set-response levels (" << lastSetLevels_.size()
90 <<
" host key(s), age " << (now - lastSetTime_) <<
"s)." << __E__;
91 for(
const auto& hostEntry : lastSetLevels_)
92 traceLevelsMap_[hostEntry.first] = hostEntry.second;
93 lastSetLevels_.clear();
97 lastSetLevels_.clear();
99 std::string cmd =
"ots -tt";
100 __COUT__ <<
"Primary TRACE path: " << cmd << __E__;
107 catch(
const std::exception& e)
109 __COUT_ERR__ <<
"'ots -tt' failed: " << e.what() << __E__;
113 __COUT_ERR__ <<
"'ots -tt' failed (unknown exception)." << __E__;
116 size_t artdaqHostCount = parseOtsTraceLevels(out, traceLevelsMap_);
117 __COUT__ <<
"'ots -tt' populated " << artdaqHostCount <<
" artdaq host(s)."
127 std::vector<std::string> keysToRemove;
128 for(
auto& entry : traceLevelsMap_)
130 const std::string& key = entry.first;
131 auto dotPos = key.find(
'.');
132 if(dotPos == std::string::npos)
134 std::string shortKey = key.substr(0, dotPos);
135 auto it = traceLevelsMap_.find(shortKey);
136 if(it != traceLevelsMap_.end() && it->first != key)
139 for(
const auto& label : entry.second)
140 it->second.emplace(label.first, label.second);
141 keysToRemove.push_back(key);
144 for(
const auto& k : keysToRemove)
145 traceLevelsMap_.erase(k);
148 __COUT__ <<
"getTraceLevels() END -- traceLevelsMap_ has " << traceLevelsMap_.size()
149 <<
" host key(s):" << __E__;
150 for(
const auto& host : traceLevelsMap_)
151 __COUT__ <<
" host key '" << host.first <<
"' with " << host.second.size()
152 <<
" label(s)." << __E__;
154 return traceLevelsMap_;
158 const std::string& label,
160 const std::string& host ,
161 std::string
const& mode )
163 bool allMode = mode ==
"ALL";
166 auto stripHost = [](
const std::string& h) -> std::string {
168 auto pos = s.find(
"-data");
169 if(pos != std::string::npos)
171 pos = s.find(
"-ipmi");
172 if(pos != std::string::npos)
175 if(pos != std::string::npos)
176 s = s.substr(0, pos);
180 std::string localShort = stripHost(getHostnameString());
181 std::string targetShort = stripHost(host);
182 bool isLocal = (host ==
"localhost" || targetShort == localShort);
186 ots::ITRACEController::setTraceLevelsForThisHost(label, lvl, mode);
193 cmd =
"ots -ttlvlmsk '" + host +
"' '" + label +
"' " + std::to_string(lvl.M) +
194 " " + std::to_string(lvl.S) +
" " + std::to_string(lvl.T);
195 else if(mode ==
"FAST")
196 cmd =
"ots -ttlvlM '" + host +
"' '" + label +
"' " + std::to_string(lvl.M);
197 else if(mode ==
"SLOW")
198 cmd =
"ots -ttlvlS '" + host +
"' '" + label +
"' " + std::to_string(lvl.S);
199 else if(mode ==
"TRIGGER")
200 cmd =
"ots -ttlvlT '" + host +
"' '" + label +
"' " + std::to_string(lvl.T);
204 __COUT__ <<
"Remote TRACE set: " << cmd << __E__;
215 if(out.find(
"#OTSTRACE-OK") != std::string::npos)
217 lastSetLevels_.clear();
218 parseOtsTraceLevels(out, lastSetLevels_);
219 lastSetTime_ = time(
nullptr);
220 __COUT__ <<
"Set confirmed; cached " << lastSetLevels_.size()
221 <<
" host(s) from response." << __E__;
224 __COUT_ERR__ <<
"'ots' TRACE set did not confirm (#OTSTRACE-OK missing)."
const ITRACEController::HostTraceLevelMap & getTraceLevels(void) final
pure virtual
virtual void setTraceLevelMask(std::string const &label, TraceMasks const &lvl, std::string const &hostname="localhost", std::string const &mode="ALL") final
pure virtual
static std::string exec(const char *cmd)