File indexing completed on 2025-08-03 08:20:55
0001 #include "OnlMonClient.h"
0002 #include "ClientHistoList.h"
0003 #include "OnlMonDraw.h"
0004 #include "OnlMonHtml.h"
0005
0006 #include <onlmon/HistoBinDefs.h>
0007 #include <onlmon/OnlMonBase.h> // for OnlMonBase
0008 #include <onlmon/OnlMonDefs.h>
0009
0010 #include <MessageTypes.h> // for kMESS_STRING, kMESS_OBJECT
0011 #include <TCanvas.h>
0012 #include <TDirectory.h>
0013 #include <TFile.h>
0014 #include <TGClient.h> // for gClient, TGClient
0015 #include <TGFrame.h>
0016 #include <TH1.h>
0017 #include <TImage.h>
0018 #include <TIterator.h>
0019 #include <TList.h> // for TList
0020 #include <TMessage.h>
0021 #include <TROOT.h>
0022 #include <TSeqCollection.h>
0023 #include <TSocket.h>
0024 #include <TStyle.h>
0025 #include <TSystem.h>
0026
0027 #include <odbc++/connection.h>
0028 #include <odbc++/drivermanager.h>
0029 #include <odbc++/resultset.h>
0030 #include <odbc++/statement.h> // for Statement
0031 #include <odbc++/types.h> // for SQLException
0032
0033 #include <sys/stat.h>
0034 #include <sys/utsname.h>
0035 #include <unistd.h>
0036 #include <uuid/uuid.h>
0037 #include <algorithm>
0038 #include <cstdio> // for printf, remove
0039 #include <cstdlib> // for getenv, exit
0040 #include <cstring> // for strcmp
0041 #include <filesystem>
0042 #include <fstream>
0043 #include <iostream>
0044 #include <list>
0045 #include <sstream>
0046 #include <utility> // for pair
0047
0048 OnlMonClient *OnlMonClient::__instance = nullptr;
0049
0050 int pinit()
0051 {
0052 return 0;
0053 }
0054
0055 OnlMonClient *OnlMonClient::instance()
0056 {
0057 if (__instance)
0058 {
0059 return __instance;
0060 }
0061 __instance = new OnlMonClient("ONLMONCLIENT");
0062 return __instance;
0063 }
0064
0065 OnlMonClient::OnlMonClient(const std::string &name)
0066 : OnlMonBase(name)
0067 {
0068 defaultStyle = new TStyle();
0069 SetStyleToDefault();
0070 InitAll();
0071 }
0072
0073 void OnlMonClient::InitAll()
0074 {
0075 if (gROOT->FindObject("ServerRunning"))
0076 {
0077 std::cout << "Don't run Server and Client in same session, exiting" << std::endl;
0078 exit(1);
0079 }
0080 if (!gClient)
0081 {
0082 const char *env_display = getenv("DISPLAY");
0083 if (env_display)
0084 {
0085 std::string displaystring = env_display;
0086 std::cout << "Cannot open Display, Display Env Var is set to "
0087 << displaystring << std::endl;
0088 if (displaystring.find("unix") != std::string::npos)
0089 {
0090 utsname ThisNode{};
0091 uname(&ThisNode);
0092 std::cout << "presumably the virtual framebuffer is not running on " << ThisNode.nodename
0093 << ", check if process /usr/X11R6/bin/Xvfb is alive" << std::endl;
0094 }
0095 else if (displaystring.find("localhost") != std::string::npos)
0096 {
0097 std::cout << "Check your ssh forwarding" << std::endl;
0098 std::cout << "your $HOME/.ssh/config has to contain the line" << std::endl;
0099 std::cout << "ForwardX11 yes" << std::endl;
0100 }
0101 }
0102 else
0103 {
0104 std::cout << "Display not set, cannot continue" << std::endl;
0105 }
0106 exit(1);
0107 }
0108
0109 clientrunning = new TH1F("ClientRunning", "ClientRunning", 1, 0, 1);
0110 if (getenv("ONLMON_HTMLDIR") == nullptr)
0111 {
0112 std::cout << "ONLMON_HTMLDIR not set, exiting" << std::endl;
0113 exit(1);
0114 }
0115 fHtml = new OnlMonHtml(getenv("ONLMON_HTMLDIR"));
0116
0117 TGFrame *rootWin = (TGFrame *) gClient->GetRoot();
0118 display_sizex = rootWin->GetDefaultWidth();
0119 display_sizey = rootWin->GetDefaultHeight();
0120 for (int i = 0; i < kMAXSIGNALS; i++)
0121 {
0122 gSystem->IgnoreSignal((ESignals) i);
0123 }
0124 return;
0125 }
0126
0127 OnlMonClient::~OnlMonClient()
0128 {
0129 while (DrawerList.begin() != DrawerList.end())
0130 {
0131 if (verbosity > 0)
0132 {
0133 std::cout << "deleting " << DrawerList.begin()->first << std::endl;
0134 }
0135 delete DrawerList.begin()->second;
0136 DrawerList.erase(DrawerList.begin());
0137 }
0138 while (Histo.begin() != Histo.end())
0139 {
0140 delete Histo.begin()->second;
0141 Histo.erase(Histo.begin());
0142 }
0143 delete clientrunning;
0144 delete fHtml;
0145 delete defaultStyle;
0146
0147 TSeqCollection *allCanvases = gROOT->GetListOfCanvases();
0148 TCanvas *canvas = nullptr;
0149 while ((canvas = static_cast<TCanvas *>(allCanvases->First())))
0150 {
0151 if (verbosity > 0)
0152 {
0153 std::cout << "Deleting Canvas " << canvas->GetName() << std::endl;
0154 }
0155 delete canvas;
0156 }
0157 __instance = nullptr;
0158 return;
0159 }
0160
0161 void OnlMonClient::registerHisto(const std::string &hname, const std::string &subsys)
0162 {
0163 auto subsysiter = SubsysHisto.find(subsys);
0164 if (subsysiter == SubsysHisto.end())
0165 {
0166 std::map<const std::string, ClientHistoList *> entry;
0167
0168 subsysiter = SubsysHisto.insert(std::make_pair(subsys, entry)).first;
0169 if (Verbosity() > 2)
0170 {
0171 std::cout << "inserting " << subsys << " into SubsysHisto, readback: " << subsysiter->first << std::endl;
0172 }
0173 }
0174 auto hiter = subsysiter->second.find(hname);
0175 if (hiter == subsysiter->second.end())
0176 {
0177 ClientHistoList *newhisto = new ClientHistoList();
0178 newhisto->SubSystem(subsys);
0179 subsysiter->second.insert(std::make_pair(hname, newhisto));
0180 if (Verbosity() > 0)
0181 {
0182 std::cout << "new histogram " << hname << " of subsystem " << subsys << std::endl;
0183 }
0184 }
0185 else
0186 {
0187 hiter->second->SubSystem(subsys);
0188 }
0189
0190 std::string frameworkhistoname = "FrameWorkVars";
0191 hiter = subsysiter->second.find(frameworkhistoname);
0192 if (hiter == subsysiter->second.end())
0193 {
0194 ClientHistoList *newhisto = new ClientHistoList();
0195 newhisto->SubSystem(subsys);
0196 subsysiter->second.insert(std::make_pair(frameworkhistoname, newhisto));
0197 if (Verbosity() > 0)
0198 {
0199 std::cout << "new histogram " << frameworkhistoname << " of subsystem " << subsys << std::endl;
0200 }
0201 }
0202 else
0203 {
0204 hiter->second->SubSystem(subsys);
0205 }
0206
0207 return;
0208 }
0209
0210 int OnlMonClient::requestHistoBySubSystem(const std::string &subsys, int getall)
0211 {
0212 std::string mysubsys = subsys.substr(0, subsys.find('_'));
0213 for (const auto &frwrkiter : m_MonitorFetchedSet)
0214 {
0215 if (frwrkiter.find(mysubsys) == std::string::npos)
0216 {
0217 m_MonitorFetchedSet.clear();
0218 break;
0219 }
0220 }
0221 int iret = 0;
0222 std::map<const std::string, ClientHistoList *>::const_iterator histoiter;
0223 std::map<const std::string, ClientHistoList *>::const_iterator histonewiter;
0224 if (!IsMonitorRunning(subsys))
0225 {
0226
0227 auto moniiter = MonitorHostPorts.find(subsys);
0228 if (moniiter != MonitorHostPorts.end())
0229 {
0230 MonitorHostPorts.erase(moniiter);
0231 }
0232
0233 if (FindMonitor(subsys) == 0)
0234 {
0235 auto subsyshistos = SubsysHisto.find(subsys);
0236 if (subsyshistos != SubsysHisto.end())
0237 {
0238 for (auto &hiter : subsyshistos->second)
0239 {
0240 hiter.second->ServerHost("UNKNOWN");
0241 hiter.second->ServerPort(0);
0242 if (hiter.second->Histo() != nullptr)
0243 {
0244 hiter.second->Histo()->Delete();
0245 }
0246 hiter.second->Histo(nullptr);
0247 }
0248 }
0249 return iret;
0250 }
0251 }
0252
0253 if (getall == 0)
0254 {
0255 std::map<std::string, std::map<const std::string, ClientHistoList *>>::const_iterator histos = SubsysHisto.find(subsys);
0256 for (auto &hiter : histos->second)
0257 {
0258 if (requestHistoByName(subsys, hiter.first))
0259 {
0260 if (Verbosity() > 2)
0261 {
0262 std::cout << "Request for " << hiter.first << " on " << subsys << " failed " << std::endl;
0263 }
0264 if (hiter.second->Histo())
0265 {
0266 hiter.second->Histo()->Delete();
0267 hiter.second->Histo(nullptr);
0268 hiter.second->ServerHost("UNKNOWN");
0269 hiter.second->ServerPort(0);
0270 }
0271 iret = -1;
0272 }
0273 }
0274 }
0275 else if (getall == 1)
0276 {
0277 std::map<std::string, std::list<std::string>> transferlist;
0278 std::ostringstream host_port;
0279
0280 int failed_to_locate = 0;
0281 auto subs = SubsysHisto.find(subsys);
0282 {
0283 for (auto &histos : subs->second)
0284 {
0285 if (Verbosity() > 2)
0286 {
0287 std::cout << "checking for subsystem " << subs->first << ", histo " << histos.first << std::endl;
0288 }
0289 if (histos.second->SubSystem() == subsys)
0290 {
0291 int unknown_histo = 0;
0292 std::string hname = histos.first;
0293 if (histos.second->ServerHost() == "UNKNOWN")
0294 {
0295 if (!failed_to_locate)
0296 {
0297
0298 if (LocateHistogram(hname, subsys) < 1)
0299 {
0300 if (Verbosity() > 2)
0301 {
0302 std::cout << "Subsystem " << subsys << " Histogram " << hname << " cannot be located" << std::endl;
0303 }
0304 failed_to_locate = 1;
0305 unknown_histo = 1;
0306 iret = -1;
0307 }
0308 }
0309 else
0310 {
0311 unknown_histo = 1;
0312 }
0313 }
0314
0315 if (histos.second->Histo())
0316 {
0317 histos.second->Histo()->Reset();
0318 }
0319 if (!unknown_histo)
0320 {
0321 std::string fullhname = subsys + std::string(" ") + hname;
0322 (transferlist[subsys]).push_back(fullhname);
0323 }
0324 }
0325 }
0326 }
0327 std::list<std::string>::const_iterator liter;
0328 for (auto &listiter : transferlist)
0329 {
0330 std::list<std::string> hlist = listiter.second;
0331 auto hostportiter = MonitorHostPorts.find(listiter.first);
0332 if (hostportiter == MonitorHostPorts.end())
0333 {
0334 std::cout << __PRETTY_FUNCTION__ << "Cannot find MonitorHostPorts entry for " << listiter.first << std::endl;
0335 std::cout << "existing hosts: " << std::endl;
0336 for (auto &hport : MonitorHostPorts)
0337 {
0338 std::cout << "subsystem " << hport.first << " on host " << hport.second.first
0339 << " listening on port " << hport.second.second << std::endl;
0340 }
0341 continue;
0342 }
0343 if (requestHistoList(listiter.first, hostportiter->second.first, hostportiter->second.second, hlist) != 0)
0344 {
0345 for (liter = hlist.begin(); liter != hlist.end(); ++liter)
0346 {
0347 if (requestHistoByName(*liter))
0348 {
0349 std::cout << "Request for " << *liter << " failed " << std::endl;
0350 histoiter = Histo.find(*liter);
0351 if (histoiter->second && histoiter->second->Histo())
0352 {
0353 histoiter->second->Histo()->Delete();
0354 histoiter->second->Histo(nullptr);
0355 histoiter->second->ServerHost("UNKNOWN");
0356 histoiter->second->ServerPort(0);
0357 }
0358 }
0359 }
0360 }
0361 }
0362 }
0363 else if (getall == 2)
0364 {
0365 const char *hname = "none";
0366 for (histoiter = Histo.begin(); histoiter != Histo.end(); ++histoiter)
0367 {
0368 if (histoiter->second->SubSystem() == subsys)
0369 {
0370 hname = histoiter->first.c_str();
0371 break;
0372 }
0373 }
0374
0375 if (histoiter != Histo.end())
0376 {
0377 std::string hostname = histoiter->second->ServerHost();
0378 int moniport = histoiter->second->ServerPort();
0379 {
0380 if (hostname == "UNKNOWN")
0381 {
0382 if (LocateHistogram(hname, "") < 1)
0383 {
0384 std::cout << "Histogram " << hname << " cannot be located" << std::endl;
0385 return -1;
0386 }
0387 histonewiter = Histo.find(hname);
0388 hostname = histonewiter->second->ServerHost();
0389 moniport = histonewiter->second->ServerPort();
0390 }
0391
0392
0393 for (histonewiter = Histo.begin(); histonewiter != Histo.end(); ++histonewiter)
0394 {
0395 if (histonewiter->second->SubSystem() == subsys)
0396 {
0397 if (histonewiter->second->Histo())
0398 {
0399 histonewiter->second->Histo()->Reset();
0400 }
0401 }
0402 }
0403
0404 if (requestHisto("ALL", hostname, moniport))
0405 {
0406 std::cout << "Request for all histograms from "
0407 << hostname << " failed, trying single " << std::endl;
0408 iret = requestHistoBySubSystem(subsys, 0);
0409 }
0410 }
0411 }
0412 else
0413 {
0414 std::cout << "No Histogram of subsystem "
0415 << subsys << " registered" << std::endl;
0416 }
0417 }
0418 m_MonitorFetchedSet.insert(subsys);
0419 return iret;
0420 }
0421
0422 void OnlMonClient::registerDrawer(OnlMonDraw *Drawer)
0423 {
0424 std::map<const std::string, OnlMonDraw *>::iterator iter = DrawerList.find(Drawer->Name());
0425 if (iter != DrawerList.end())
0426 {
0427 std::cout << "Drawer " << Drawer->Name() << " already registered, I won't overwrite it" << std::endl;
0428 std::cout << "Use a different name and try again" << std::endl;
0429 }
0430 else
0431 {
0432 DrawerList[Drawer->Name()] = Drawer;
0433 Drawer->Init();
0434 SetStyleToDefault();
0435 }
0436 return;
0437 }
0438
0439 int OnlMonClient::Draw(const char *who, const char *what)
0440 {
0441 GetServerInfo();
0442 int iret = DoSomething(who, what, "DRAW");
0443
0444 return iret;
0445 }
0446
0447 int OnlMonClient::SavePlot(const std::string &who, const std::string &what)
0448 {
0449 int iret = DoSomething(who, what, "SAVEPLOT");
0450 TSeqCollection *allCanvases = gROOT->GetListOfCanvases();
0451 TCanvas *canvas = nullptr;
0452 while ((canvas = static_cast<TCanvas *>(allCanvases->First())))
0453 {
0454 if (verbosity > 0)
0455 {
0456 std::cout << "Deleting Canvas " << canvas->GetName() << std::endl;
0457 }
0458 delete canvas;
0459 }
0460
0461 return iret;
0462 }
0463
0464 int OnlMonClient::MakePS(const char *who, const char *what)
0465 {
0466 int iret = DoSomething(who, what, "PS");
0467
0468 return iret;
0469 }
0470
0471 int OnlMonClient::MakeHtml(const char *who, const char *what)
0472 {
0473 isHtml(true);
0474 GetServerInfo();
0475 mode_t old_umask;
0476 int runno = RunNumber();
0477 if (runno <= 0)
0478 {
0479 std::cout << "Run Number too small: " << runno
0480 << " not creating html output" << std::endl;
0481 return 0;
0482 }
0483 char *onlmon_real_html = getenv("ONLMON_REAL_HTML");
0484 if (!onlmon_real_html)
0485 {
0486 old_umask = umask(S_IWOTH);
0487 std::cout << "Making html output group writable so others can run tests as well" << std::endl;
0488 }
0489 fHtml->runNumber(runno);
0490 int iret = DoSomething(who, what, "HTML");
0491
0492 if (!onlmon_real_html)
0493 {
0494 umask(old_umask);
0495 }
0496
0497 return iret;
0498 }
0499
0500 int OnlMonClient::DoSomething(const std::string &who, const std::string &what, const std::string &opt)
0501 {
0502 std::map<const std::string, OnlMonDraw *>::iterator iter;
0503 if (who != "ALL")
0504 {
0505 iter = DrawerList.find(who);
0506 if (iter != DrawerList.end())
0507 {
0508 if (opt == "DRAW")
0509 {
0510 iter->second->Draw(what);
0511 }
0512 else if (opt == "PS")
0513 {
0514 iter->second->MakePS(what);
0515 }
0516 else if (opt == "SAVEPLOT")
0517 {
0518 iter->second->SavePlot(what, "png");
0519 }
0520 else if (opt == "HTML")
0521 {
0522 if (verbosity > 0)
0523 {
0524 std::cout << __PRETTY_FUNCTION__ << " creating html output for "
0525 << iter->second->Name() << std::endl;
0526 }
0527 iter->second->isHtml(true);
0528 if (iter->second->MakeHtml(what))
0529 {
0530 std::cout << "subsystem " << iter->second->Name()
0531 << " not in root file, skipping" << std::endl;
0532 }
0533 }
0534 else
0535 {
0536 std::cout << "option " << opt << " not implemented" << std::endl;
0537 return 0;
0538 }
0539 SetStyleToDefault();
0540 return 0;
0541 }
0542 else
0543 {
0544 std::cout << "Drawer " << who << " not in list" << std::endl;
0545 Print("DRAWER");
0546 return -1;
0547 }
0548 }
0549 else
0550 {
0551 for (iter = DrawerList.begin(); iter != DrawerList.end(); ++iter)
0552 {
0553 if (opt == "DRAW")
0554 {
0555 iter->second->Draw(what);
0556 }
0557 else if (opt == "PS")
0558 {
0559 iter->second->MakePS(what);
0560 }
0561 else if (opt == "HTML")
0562 {
0563 if (verbosity > 0)
0564 {
0565 std::cout << __PRETTY_FUNCTION__ << " creating html output for "
0566 << iter->second->Name() << std::endl;
0567 }
0568 gROOT->Reset();
0569 iter->second->isHtml(true);
0570 int iret = iter->second->MakeHtml(what);
0571 if (iret)
0572 {
0573 std::cout << "subsystem " << iter->second->Name()
0574 << " not in root file, skipping" << std::endl;
0575
0576
0577
0578 TSeqCollection *allCanvases = gROOT->GetListOfCanvases();
0579 TCanvas *canvas = nullptr;
0580 while ((canvas = static_cast<TCanvas *>(allCanvases->First())))
0581 {
0582 std::cout << "Deleting Canvas " << canvas->GetName() << std::endl;
0583 delete canvas;
0584 }
0585 }
0586 }
0587 SetStyleToDefault();
0588 }
0589 }
0590 return 0;
0591 }
0592
0593 int OnlMonClient::requestHistoByName(const std::string &subsys, const std::string &what)
0594 {
0595 std::string hostname = "UNKNOWN";
0596 int moniport = OnlMonDefs::MONIPORT;
0597 std::map<std::string, std::map<const std::string, ClientHistoList *>>::const_iterator histos = SubsysHisto.find(subsys);
0598 auto histoiter = histos->second.find(what);
0599 if (Verbosity() > 2)
0600 {
0601 std::cout << __PRETTY_FUNCTION__ << "checking for " << what << " on monitor " << subsys << std::endl;
0602 }
0603 if (histoiter != histos->second.end())
0604 {
0605 hostname = histoiter->second->ServerHost();
0606 moniport = histoiter->second->ServerPort();
0607 if (hostname == "UNKNOWN")
0608 {
0609 if (LocateHistogram(what, subsys) < 1)
0610 {
0611 std::cout << "Histogram " << what << " cannot be located" << std::endl;
0612 return -1;
0613 }
0614
0615 histoiter = histos->second.find(what);
0616 hostname = histoiter->second->ServerHost();
0617 moniport = histoiter->second->ServerPort();
0618 if (hostname == "UNKNOWN")
0619 {
0620 std::cout << __PRETTY_FUNCTION__ << "host UNKNOWN for whatever reason" << std::endl;
0621 return -3;
0622 }
0623 }
0624 }
0625 else
0626 {
0627 if (LocateHistogram(what, subsys) < 1)
0628 {
0629 std::cout << "Histogram " << what << " cannot be located" << std::endl;
0630 return -2;
0631 }
0632 histoiter = histos->second.find(what);
0633 if (histoiter != histos->second.end())
0634 {
0635 hostname = histoiter->second->ServerHost();
0636 moniport = histoiter->second->ServerPort();
0637 if (hostname == "UNKNOWN")
0638 {
0639 std::cout << __PRETTY_FUNCTION__ << "host UNKNOWN for whatever reason" << std::endl;
0640 return -3;
0641 }
0642 }
0643 else
0644 {
0645 std::cout << __PRETTY_FUNCTION__ << "Problem determining host" << std::endl;
0646 }
0647 }
0648
0649 TSocket sock(hostname.c_str(), moniport);
0650 TMessage *mess;
0651 std::string fullhistoname = subsys + std::string(" ") + what;
0652 if (Verbosity() > 2)
0653 {
0654 std::cout << __PRETTY_FUNCTION__ << " sending " << fullhistoname << " to " << hostname << " port " << moniport << std::endl;
0655 }
0656 sock.Send(fullhistoname.c_str());
0657 while (true)
0658 {
0659 if (verbosity > 1)
0660 {
0661 std::cout << __PRETTY_FUNCTION__ << "Waiting for Message from : " << hostname
0662 << " on port " << moniport << std::endl;
0663 }
0664 sock.Recv(mess);
0665 if (!mess)
0666 {
0667 std::cout << __PRETTY_FUNCTION__ << "Server not running on " << hostname << std::endl;
0668 sock.Close();
0669 return 1;
0670 }
0671 if (mess->What() == kMESS_STRING)
0672 {
0673 char str[OnlMonDefs::MSGLEN];
0674 mess->ReadString(str, OnlMonDefs::MSGLEN);
0675 delete mess;
0676 if (verbosity > 1)
0677 {
0678 std::cout << __PRETTY_FUNCTION__ << "Message: " << str << std::endl;
0679 }
0680 if (!strcmp(str, "Finished"))
0681 {
0682 break;
0683 }
0684 else if (!strcmp(str, "UnknownHisto"))
0685 {
0686 break;
0687 }
0688 else
0689 {
0690 std::cout << __PRETTY_FUNCTION__ << "Unknown Text Message: " << str << std::endl;
0691 sock.Send("Ack");
0692 }
0693 }
0694 else if (mess->What() == kMESS_OBJECT)
0695 {
0696 TH1 *histo = static_cast<TH1 *>(mess->ReadObjectAny(mess->GetClass()));
0697 delete mess;
0698 TH1 *maphist = static_cast<TH1 *>(histo->Clone(histo->GetName()));
0699 if (verbosity > 1)
0700 {
0701 std::cout << __PRETTY_FUNCTION__ << "histoname: " << histo->GetName() << " at "
0702 << histo << std::endl;
0703 }
0704
0705 updateHistoMap(subsys, histo->GetName(), maphist);
0706 delete histo;
0707 sock.Send("Ack");
0708 }
0709 }
0710 sock.Send("Finished");
0711
0712 sock.Close();
0713 return 0;
0714 }
0715
0716 int OnlMonClient::requestHisto(const std::string &what, const std::string &hostname, const int moniport)
0717 {
0718
0719 TSocket sock(hostname.c_str(), moniport);
0720 TMessage *mess;
0721 sock.Send(what.c_str());
0722 while (true)
0723 {
0724 sock.Recv(mess);
0725 if (!mess)
0726 {
0727 std::cout << __PRETTY_FUNCTION__ << "Server not running on " << hostname << std::endl;
0728 sock.Close();
0729 return 1;
0730 }
0731 if (mess->What() == kMESS_STRING)
0732 {
0733 char str[OnlMonDefs::MSGLEN];
0734 mess->ReadString(str, OnlMonDefs::MSGLEN);
0735 delete mess;
0736 if (verbosity > 1)
0737 {
0738 std::cout << __PRETTY_FUNCTION__ << "Message: " << str << std::endl;
0739 }
0740
0741 if (!strcmp(str, "Finished"))
0742 {
0743 break;
0744 }
0745 else if (!strcmp(str, "UnknownHisto"))
0746 {
0747 break;
0748 }
0749 else
0750 {
0751 std::cout << __PRETTY_FUNCTION__ << "Unknown Text Message: " << str << std::endl;
0752 sock.Send("Ack");
0753 }
0754 }
0755 else if (mess->What() == kMESS_OBJECT)
0756 {
0757
0758 TH1 *histo = static_cast<TH1 *>(mess->ReadObjectAny(mess->GetClass()));
0759 delete mess;
0760 if (verbosity > 1)
0761 {
0762 std::cout << __PRETTY_FUNCTION__ << "histoname: " << histo->GetName() << " at "
0763 << histo << std::endl;
0764 }
0765
0766 updateHistoMap(what, histo->GetName(), histo);
0767 sock.Send("Ack");
0768 }
0769 }
0770 sock.Send("Finished");
0771
0772
0773 sock.Close();
0774 return 0;
0775 }
0776
0777 int OnlMonClient::requestMonitorList(const std::string &hostname, const int moniport)
0778 {
0779 TSocket sock(hostname.c_str(), moniport);
0780 TMessage *mess;
0781 sock.Send("LISTMONITORS");
0782 sock.Recv(mess);
0783 if (!mess)
0784 {
0785 std::cout << __PRETTY_FUNCTION__ << "Server not running on " << hostname << std::endl;
0786 sock.Close();
0787 return 1;
0788 }
0789 delete mess;
0790 while (true)
0791 {
0792 sock.Recv(mess);
0793 if (mess->What() == kMESS_STRING)
0794 {
0795 char strmess[OnlMonDefs::MSGLEN];
0796 mess->ReadString(strmess, OnlMonDefs::MSGLEN);
0797 delete mess;
0798 if (Verbosity() > 1)
0799 {
0800 std::cout << "received " << strmess << std::endl;
0801 }
0802 std::string str(strmess);
0803 if (str == "Finished")
0804 {
0805 break;
0806 }
0807 if (Verbosity() > 2)
0808 {
0809 std::cout << "inserting " << str << " on host " << hostname
0810 << " listening to " << moniport << std::endl;
0811 }
0812 MonitorHostPorts.insert(std::make_pair(str, std::make_pair(hostname, moniport)));
0813 }
0814 else
0815 {
0816 std::cout << "requestMonitorList: received unexpected message type: " << mess->What() << std::endl;
0817 break;
0818 }
0819 }
0820 sock.Send("Finished");
0821
0822
0823 sock.Close();
0824 return 0;
0825 }
0826
0827 int OnlMonClient::requestHistoList(const std::string &subsys, const std::string &hostname, const int moniport, std::list<std::string> &histolist)
0828 {
0829
0830 TSocket sock(hostname.c_str(), moniport);
0831 TMessage *mess;
0832 sock.Send("LIST");
0833 std::list<std::string>::const_iterator listiter;
0834 sock.Recv(mess);
0835 if (!mess)
0836 {
0837 std::cout << __PRETTY_FUNCTION__ << "Server not running on " << hostname << std::endl;
0838 sock.Close();
0839 return 1;
0840 }
0841
0842 delete mess;
0843 for (listiter = histolist.begin(); listiter != histolist.end(); ++listiter)
0844 {
0845 if (Verbosity() > 2)
0846 {
0847 std::cout << __PRETTY_FUNCTION__ << "asking for " << *listiter << std::endl;
0848 }
0849 sock.Send((*listiter).c_str());
0850 sock.Recv(mess);
0851 if (!mess)
0852 {
0853 std::cout << __PRETTY_FUNCTION__ << "Server shut down during getting histo list" << std::endl;
0854 sock.Close();
0855 return 1;
0856 }
0857 if (mess->What() == kMESS_STRING)
0858 {
0859 char str[OnlMonDefs::MSGLEN];
0860 mess->ReadString(str, OnlMonDefs::MSGLEN);
0861 delete mess;
0862 if (verbosity > 1)
0863 {
0864 std::cout << __PRETTY_FUNCTION__ << "Message: " << str << std::endl;
0865 }
0866
0867 if (!strcmp(str, "Ack"))
0868 {
0869 break;
0870 }
0871 else if (!strcmp(str, "UnknownHisto"))
0872 {
0873 break;
0874 }
0875 else
0876 {
0877 std::cout << __PRETTY_FUNCTION__ << "Unknown Text Message: " << str << std::endl;
0878 }
0879 }
0880 else if (mess->What() == kMESS_OBJECT)
0881 {
0882
0883 TH1 *histo = static_cast<TH1 *>(mess->ReadObjectAny(mess->GetClass()));
0884 delete mess;
0885 if (verbosity > 1)
0886 {
0887 std::cout << __PRETTY_FUNCTION__ << "histoname: " << histo->GetName() << " at "
0888 << histo << std::endl;
0889 }
0890
0891 updateHistoMap(subsys, histo->GetName(), histo);
0892 }
0893 }
0894 sock.Send("alldone");
0895 sock.Recv(mess);
0896 delete mess;
0897 sock.Send("Finished");
0898
0899
0900 sock.Close();
0901 return 0;
0902 }
0903
0904 void OnlMonClient::updateHistoMap(const std::string &subsys, const std::string &hname, TH1 *h1d)
0905 {
0906 auto subsysiter = SubsysHisto.find(subsys);
0907 if (subsysiter == SubsysHisto.end())
0908 {
0909 std::map<const std::string, ClientHistoList *> newmap;
0910 ClientHistoList *entry = new ClientHistoList(subsys);
0911 entry->Histo(h1d);
0912 newmap.insert(std::make_pair(hname, entry));
0913 SubsysHisto.insert(std::make_pair(subsys, newmap));
0914 return;
0915 }
0916 auto histoiter = subsysiter->second.find(hname);
0917
0918 if (histoiter != subsysiter->second.end())
0919 {
0920 if (Verbosity() > 2)
0921 {
0922 std::cout << "deleting histogram " << hname << " at " << Histo[hname] << std::endl;
0923 }
0924 delete histoiter->second->Histo();
0925 histoiter->second->Histo(h1d);
0926 }
0927 else
0928 {
0929 ClientHistoList *newhisto = new ClientHistoList(subsys);
0930 newhisto->Histo(h1d);
0931 subsysiter->second.insert(std::make_pair(hname, newhisto));
0932 if (Verbosity() > 2)
0933 {
0934 std::cout << "new histogram " << hname << " at " << newhisto->Histo() << std::endl;
0935 }
0936 }
0937 return;
0938 }
0939
0940 OnlMonDraw *
0941 OnlMonClient::getDrawer(const std::string &name)
0942 {
0943 std::map<const std::string, OnlMonDraw *>::iterator iter = DrawerList.find(name);
0944 if (iter != DrawerList.end())
0945 {
0946 return iter->second;
0947 }
0948 std::cout << "Could not locate drawer" << name << std::endl;
0949 return nullptr;
0950 }
0951
0952 TH1 *OnlMonClient::getHisto(const std::string &monitor, const std::string &hname)
0953 {
0954 auto subsysiter = SubsysHisto.find(monitor);
0955 if (subsysiter == SubsysHisto.end())
0956 {
0957 return nullptr;
0958 }
0959 auto hiter = subsysiter->second.find(hname);
0960 if (hiter == subsysiter->second.end())
0961 {
0962 return nullptr;
0963 }
0964 return hiter->second->Histo();
0965 }
0966
0967 void OnlMonClient::Print(const char *what)
0968 {
0969 if (!strcmp(what, "ALL") || !strcmp(what, "DRAWER"))
0970 {
0971
0972 std::cout << "--------------------------------------" << std::endl
0973 << std::endl;
0974 std::cout << "List of Drawers in OnlMonClient:" << std::endl;
0975
0976 std::map<const std::string, OnlMonDraw *>::const_iterator hiter;
0977 for (hiter = DrawerList.begin(); hiter != DrawerList.end(); ++hiter)
0978 {
0979 std::cout << hiter->first << " is at " << hiter->second << std::endl;
0980 }
0981 std::cout << std::endl;
0982 }
0983 if (!strcmp(what, "ALL") || !strcmp(what, "SERVERS"))
0984 {
0985
0986 std::cout << "--------------------------------------" << std::endl
0987 << std::endl;
0988 std::cout << "List of Servers in OnlMonClient:" << std::endl;
0989
0990 std::vector<std::string>::iterator hostiter;
0991 for (hostiter = MonitorHosts.begin(); hostiter != MonitorHosts.end(); ++hostiter)
0992 {
0993 std::cout << "ServerHost: " << *hostiter << std::endl;
0994 }
0995 }
0996 if (!strcmp(what, "ALL") || !strcmp(what, "MONITORS"))
0997 {
0998
0999 std::cout << "--------------------------------------" << std::endl
1000 << std::endl;
1001 std::cout << "List of Monitors in OnlMonClient:" << std::endl;
1002
1003 for (auto &moniiter : MonitorHostPorts)
1004 {
1005 std::cout << "Monitor " << moniiter.first << " runs on " << moniiter.second.first
1006 << " listening to port " << moniiter.second.second << std::endl;
1007 }
1008 }
1009 if (!strcmp(what, "ALL") || !strcmp(what, "HISTOS"))
1010 {
1011
1012 std::cout << "--------------------------------------" << std::endl
1013 << std::endl;
1014 std::cout << "List of Histograms in OnlMonClient:" << std::endl;
1015
1016 std::map<const std::string, ClientHistoList *>::const_iterator hiter;
1017 for (hiter = Histo.begin(); hiter != Histo.end(); ++hiter)
1018 {
1019 if (hiter->second)
1020 {
1021 std::cout << hiter->first << " Address " << hiter->second->Histo()
1022 << " on host " << hiter->second->ServerHost()
1023 << " port " << hiter->second->ServerPort()
1024 << ", subsystem " << hiter->second->SubSystem() << std::endl;
1025 }
1026 }
1027 std::cout << std::endl;
1028 for (auto &subs : SubsysHisto)
1029 {
1030 auto subiter = MonitorHostPorts.find(subs.first);
1031 if (subiter != MonitorHostPorts.end())
1032 {
1033 std::cout << "Subsystem " << subs.first << " runs on " << subiter->second.first;
1034 std::cout << " on port " << subiter->second.second << std::endl;
1035 }
1036 for (auto &histos : subs.second)
1037 {
1038 std::cout << histos.first << " @ " << subs.first
1039 << " Address " << histos.second->Histo()
1040 << " on host " << histos.second->ServerHost()
1041 << " port " << histos.second->ServerPort()
1042 << ", subsystem " << histos.second->SubSystem() << std::endl;
1043 }
1044 }
1045 std::cout << std::endl;
1046 }
1047 if (!strcmp(what, "ALL") || !strcmp(what, "UNKNOWN"))
1048 {
1049
1050 std::cout << "--------------------------------------" << std::endl
1051 << std::endl;
1052 std::cout << "List of Unknown Histograms in OnlMonClient:" << std::endl;
1053
1054 std::map<const std::string, ClientHistoList *>::const_iterator hiter;
1055 for (hiter = Histo.begin(); hiter != Histo.end(); ++hiter)
1056 {
1057 if (hiter->second)
1058 {
1059 if (hiter->second->ServerHost() == "UNKNOWN" ||
1060 hiter->second->SubSystem() == "UNKNOWN")
1061 {
1062 std::cout << hiter->first << " Address " << hiter->second->Histo()
1063 << " on host " << hiter->second->ServerHost()
1064 << " port " << hiter->second->ServerPort()
1065 << ", subsystem " << hiter->second->SubSystem() << std::endl;
1066 }
1067 }
1068 }
1069 std::cout << std::endl;
1070 for (auto &subs : SubsysHisto)
1071 {
1072 for (auto &histos : subs.second)
1073 {
1074 if ( histos.second->ServerHost() == "UNKNOWN" ||
1075 histos.second->SubSystem() == "UNKNOWN")
1076 {
1077 std::cout << histos.first << " @ " << subs.first
1078 << " Address " << histos.second->Histo()
1079 << " on host " << histos.second->ServerHost()
1080 << " port " << histos.second->ServerPort()
1081 << ", subsystem " << histos.second->SubSystem() << std::endl;
1082 }
1083 }
1084 }
1085 std::cout << std::endl;
1086 }
1087 return;
1088 }
1089
1090 void OnlMonClient::PrintHistos(const std::string &what)
1091 {
1092 std::cout << "--------------------------------------" << std::endl
1093 << std::endl;
1094 std::cout << "List of Histograms in OnlMonClient:" << std::endl;
1095 auto iter = SubsysHisto.find(what);
1096 if (iter == SubsysHisto.end())
1097 {
1098 std::cout << "subsystem " << what << " not found, available: " << std::endl;
1099 for (auto &subs : SubsysHisto)
1100 {
1101 std::cout << subs.first << std::endl;
1102 }
1103 return;
1104 }
1105 auto subiter = MonitorHostPorts.find(iter->first);
1106 if (subiter != MonitorHostPorts.end())
1107 {
1108 std::cout << "Subsystem " << iter->first << " runs on " << subiter->second.first;
1109 std::cout << " on port " << subiter->second.second << std::endl;
1110 }
1111 for (auto &histos : iter->second)
1112 {
1113 std::cout << histos.first << " @ " << iter->first
1114 << " Address " << histos.second->Histo()
1115 << " on host " << histos.second->ServerHost()
1116 << " port " << histos.second->ServerPort()
1117 << ", subsystem " << histos.second->SubSystem() << std::endl;
1118 }
1119 std::cout << std::endl;
1120 return;
1121 }
1122
1123 int OnlMonClient::UpdateServerHistoMap(const std::string &hname, const std::string &subsys, const std::string &hostname)
1124 {
1125
1126 std::string searchstring = subsys + ' ' + hname;
1127 int MoniPort = OnlMonDefs::MONIPORT;
1128 int foundit = 0;
1129 do
1130 {
1131 std::cout << "Connecting to " << hostname << ", if it is frozen here - this is the one you need to restart" << std::endl;
1132 TSocket sock(hostname.c_str(), MoniPort);
1133 TMessage *mess;
1134 if (verbosity > 0)
1135 {
1136 std::cout << "UpdateServerHistoMap: sending cmd HistoList to "
1137 << hostname << " on port "
1138 << MoniPort
1139 << std::endl;
1140 }
1141 if (!sock.Send("HistoList"))
1142 {
1143 std::cout << "Server not running on " << hostname
1144 << " port " << MoniPort << std::endl;
1145 goto noserver;
1146 }
1147 while (true)
1148 {
1149 if (verbosity > 0)
1150 {
1151 std::cout << "UpdateServerHistoMap: waiting for response on "
1152 << hostname << " on port "
1153 << MoniPort
1154 << std::endl;
1155 }
1156 sock.Recv(mess);
1157 if (!mess)
1158 {
1159 std::cout << "UpdateServerHistoMap: No Recv, Server not running on "
1160 << hostname
1161 << " on port " << MoniPort << std::endl;
1162 goto noserver;
1163 }
1164 if (mess->What() == kMESS_STRING)
1165 {
1166 char strchr[OnlMonDefs::MSGLEN];
1167 mess->ReadString(strchr, OnlMonDefs::MSGLEN);
1168 delete mess;
1169 std::string str = strchr;
1170 if (verbosity > 0)
1171 {
1172 std::cout << "UpdateServerHistoMap Response: " << str << std::endl;
1173 }
1174 if (str == "Finished")
1175 {
1176 break;
1177 }
1178
1179 if (str == searchstring)
1180 {
1181 std::cout << "found subsystem " << subsys << " histo " << hname << std::endl;
1182 foundit = 1;
1183 }
1184 unsigned int pos_space = str.find(' ');
1185 PutHistoInMap(str.substr(pos_space + 1, str.size()), str.substr(0, pos_space), hostname, MoniPort);
1186 sock.Send("Ack");
1187 }
1188 }
1189 sock.Send("Finished");
1190
1191
1192 noserver:
1193 sock.Close();
1194 if (foundit)
1195 {
1196 return foundit;
1197 }
1198 MoniPort++;
1199 } while ((MoniPort - OnlMonDefs::MONIPORT) < OnlMonDefs::NUMMONIPORT);
1200 return foundit;
1201 }
1202
1203 void OnlMonClient::PutHistoInMap(const std::string &hname, const std::string &subsys, const std::string &hostname, const int port)
1204 {
1205 auto hiter = SubsysHisto.find(subsys);
1206 if (hiter == SubsysHisto.end())
1207 {
1208 std::map<const std::string, ClientHistoList *> entry;
1209
1210 hiter = SubsysHisto.insert(std::make_pair(subsys, entry)).first;
1211 }
1212 auto histoiter = hiter->second.find(hname);
1213 if (histoiter != hiter->second.end())
1214 {
1215 histoiter->second->ServerHost(hostname);
1216 histoiter->second->ServerPort(port);
1217 }
1218 else
1219 {
1220 ClientHistoList *newhisto = new ClientHistoList();
1221 newhisto->ServerHost(hostname);
1222 newhisto->ServerPort(port);
1223 hiter->second.insert(std::make_pair(hname, newhisto));
1224 }
1225 return;
1226 }
1227
1228 void OnlMonClient::AddServerHost(const std::string &hostname)
1229 {
1230 if (find(MonitorHosts.begin(), MonitorHosts.end(), hostname) != MonitorHosts.end())
1231 {
1232 if (Verbosity() > 2)
1233 {
1234 std::cout << "Host " << hostname << " already in list" << std::endl;
1235 }
1236 }
1237 else
1238 {
1239 MonitorHosts.emplace_back(hostname);
1240 }
1241 return;
1242 }
1243
1244 int OnlMonClient::LocateHistogram(const std::string &hname, const std::string &subsys)
1245 {
1246 for (auto &hostiter : MonitorHosts)
1247 {
1248 if (UpdateServerHistoMap(hname, subsys, hostiter) > 0)
1249 {
1250 return 1;
1251 }
1252 }
1253 return 0;
1254 }
1255
1256 int OnlMonClient::RunNumber()
1257 {
1258 int runno = -9999;
1259 for (const auto &frwrkiter : m_MonitorFetchedSet)
1260 {
1261 TH1 *frameworkvars = getHisto(frwrkiter, "FrameWorkVars");
1262 if (frameworkvars)
1263 {
1264 runno = std::max(runno, (int) frameworkvars->GetBinContent(RUNNUMBERBIN));
1265 }
1266 }
1267 return (runno);
1268 }
1269
1270 int OnlMonClient::GetServerInfo()
1271 {
1272 std::map<std::string, int> server_runmap;
1273 int runno = -9999;
1274 for (const auto &frwrkiter : m_MonitorFetchedSet)
1275 {
1276 if (m_ServerStatsMap.find(frwrkiter) == m_ServerStatsMap.end())
1277 {
1278 m_ServerStatsMap[frwrkiter] = std::make_tuple(false, -1, -1, 0, -1);
1279 }
1280 TH1 *frameworkvars = getHisto(frwrkiter, "FrameWorkVars");
1281 if (frameworkvars)
1282 {
1283 int runnumber = frameworkvars->GetBinContent(RUNNUMBERBIN);
1284 time_t currtime = frameworkvars->GetBinContent(CURRENTTIMEBIN);
1285 int eventcounter = frameworkvars->GetBinContent(EVENTCOUNTERBIN);
1286 int gl1foundcounter = frameworkvars->GetBinContent(GL1COUNTERBIN);
1287 if (Verbosity() > 0)
1288 {
1289 std::cout << "Run number for " << frwrkiter << " is "
1290 << runnumber
1291 << " events taken: " << eventcounter;
1292 if (gl1foundcounter > -1)
1293 {
1294 std::cout << " gl1 found " << gl1foundcounter;
1295 }
1296 std::cout << " time is " << ctime(&currtime);
1297 }
1298 runno = std::max(runno, runnumber);
1299 server_runmap[frwrkiter] = runnumber;
1300 auto &statsiter = m_ServerStatsMap[frwrkiter];
1301 std::get<0>(statsiter) = true;
1302 std::get<1>(statsiter) = runnumber;
1303 std::get<2>(statsiter) = eventcounter;
1304 std::get<3>(statsiter) = currtime;
1305 std::get<4>(statsiter) = gl1foundcounter;
1306 }
1307 }
1308 for (auto const &iter : server_runmap)
1309 {
1310 if (iter.second != runno)
1311 {
1312 std::cout << "server " << iter.first << " has bad run " << iter.second << std::endl;
1313 std::cout << "Resetting histos for " << iter.first << std::endl;
1314 std::get<0>(m_ServerStatsMap[iter.first]) = false;
1315 auto subsysiter = SubsysHisto.find(iter.first);
1316 if (subsysiter == SubsysHisto.end())
1317 {
1318 std::cout << "could not find " << iter.first << " in SubsysHisto map" << std::endl;
1319 }
1320 else
1321 {
1322 for (auto &hiter : subsysiter->second)
1323 {
1324 if (hiter.first != "FrameWorkVars")
1325 {
1326 if (hiter.second->Histo())
1327 {
1328 hiter.second->Histo()->Reset();
1329 }
1330 }
1331 }
1332 }
1333 }
1334 }
1335 return (runno);
1336 }
1337
1338 std::pair<time_t,int> OnlMonClient::EventTime(const std::string &which)
1339 {
1340 time_t tret = 0;
1341 int color = 1;
1342 for (const auto &frwrkiter : m_MonitorFetchedSet)
1343 {
1344 tret = std::max(tret, EventTime(frwrkiter, which));
1345 }
1346
1347 if (verbosity > 0)
1348 {
1349 std::cout << "Time is " << ctime(&tret) << std::endl;
1350 }
1351 if (!make_html)
1352 {
1353 time_t clienttime = time(nullptr);
1354 if ((clienttime - tret) > 600)
1355 {
1356 color = 2;
1357 }
1358 }
1359 return (std::make_pair(tret,color));
1360 }
1361
1362 time_t OnlMonClient::EventTime(const std::string &servername, const std::string &which)
1363 {
1364 time_t tret = 0;
1365 int ibin = 0;
1366 if (which == "BOR")
1367 {
1368 ibin = BORTIMEBIN;
1369 }
1370 else if (which == "CURRENT")
1371 {
1372 ibin = CURRENTTIMEBIN;
1373 }
1374 else if (which == "EOR")
1375 {
1376 ibin = EORTIMEBIN;
1377 }
1378 else
1379 {
1380 std::cout << "Bad Option for Time: " << which
1381 << ", implemented are BOR EOR CURRENT" << std::endl;
1382 ibin = CURRENTTIMEBIN;
1383 }
1384 TH1 *frameworkvars = getHisto(servername, "FrameWorkVars");
1385 if (frameworkvars == nullptr)
1386 {
1387 tret = 0;
1388 }
1389 else
1390 {
1391 tret = (time_t) frameworkvars->GetBinContent(ibin);
1392 }
1393 if (verbosity > 0)
1394 {
1395 std::cout << "Time is " << ctime(&tret) << std::endl;
1396 }
1397 return (tret);
1398 }
1399
1400 int OnlMonClient::ReadHistogramsFromFile(const std::string &filename, OnlMonDraw *drawer)
1401 {
1402 std::string subsys = ExtractSubsystem(filename, drawer);
1403 std::cout << "Reading histos from " << filename << std::endl;
1404 TFile *histofile = TFile::Open(filename.c_str(), "READ");
1405 if (!histofile)
1406 {
1407 std::cout << "Can't open " << filename << std::endl;
1408 return -1;
1409 }
1410 TIterator *titer = histofile->GetListOfKeys()->MakeIterator();
1411 TObject *obj;
1412 TH1 *histo, *histoptr;
1413 while ((obj = titer->Next()))
1414 {
1415 if (verbosity > 0)
1416 {
1417 std::cout << "TObject at " << obj << std::endl;
1418 std::cout << obj->GetName() << std::endl;
1419 std::cout << obj->ClassName() << std::endl;
1420 }
1421 histofile->GetObject(obj->GetName(), histoptr);
1422 if (histoptr)
1423 {
1424
1425
1426
1427 histoptr->SetDirectory(0);
1428 histo = dynamic_cast<TH1 *>(histoptr);
1429 updateHistoMap(subsys, histo->GetName(), histo);
1430 if (verbosity > 0)
1431 {
1432 std::cout << "HistoName: " << histo->GetName() << std::endl;
1433 std::cout << "HistoClass: " << histo->ClassName() << std::endl;
1434 }
1435 }
1436 }
1437 delete titer;
1438
1439
1440 gROOT->GetListOfFiles()->Remove( histofile );
1441 return 0;
1442 }
1443
1444 int OnlMonClient::SendCommand(const char *hostname, const int port, const char *cmd)
1445 {
1446
1447 TSocket sock(hostname, port);
1448 TMessage *mess;
1449 if (!sock.Send(cmd))
1450 {
1451 std::cout << "Server not running on " << hostname
1452 << " port " << port << std::endl;
1453 sock.Close();
1454 return -1;
1455 }
1456 while (true)
1457 {
1458 sock.Recv(mess);
1459 if (!mess)
1460 {
1461 std::cout << __PRETTY_FUNCTION__ << "No Recv, Server not running on " << hostname
1462 << " on port " << port << std::endl;
1463 sock.Close();
1464 return -1;
1465 }
1466 if (mess->What() == kMESS_STRING)
1467 {
1468 char str[OnlMonDefs::MSGLEN];
1469 mess->ReadString(str, OnlMonDefs::MSGLEN);
1470 delete mess;
1471 if (verbosity > 1)
1472 {
1473 std::cout << __PRETTY_FUNCTION__ << " Message: " << str << std::endl;
1474 }
1475
1476 if (!strcmp(str, "Finished"))
1477 {
1478 break;
1479 }
1480 }
1481 }
1482 sock.Send("Finished");
1483
1484
1485 sock.Close();
1486 return 0;
1487 }
1488
1489
1490 void OnlMonClient::Verbosity(const int v)
1491 {
1492 verbosity = v;
1493 if (fHtml)
1494 {
1495 fHtml->verbosity(v);
1496 }
1497 }
1498
1499
1500 void OnlMonClient::htmlAddMenu(const OnlMonDraw &drawer,
1501 const std::string &path,
1502 const std::string &relfilename)
1503 {
1504 fHtml->addMenu(drawer.Name(), path, relfilename);
1505 }
1506
1507
1508 void OnlMonClient::htmlNamer(const OnlMonDraw &drawer,
1509 const std::string &basefilename,
1510 const std::string &ext,
1511 std::string &fullfilename,
1512 std::string &filename)
1513 {
1514 fHtml->namer(drawer.Name(), basefilename, ext, fullfilename, filename);
1515 }
1516
1517
1518 std::string
1519 OnlMonClient::htmlRegisterPage(const OnlMonDraw &drawer,
1520 const std::string &path,
1521 const std::string &basefilename,
1522 const std::string &ext)
1523 {
1524 return fHtml->registerPage(drawer.Name(), path, basefilename, ext);
1525 }
1526
1527 int OnlMonClient::CanvasToPng(TCanvas *canvas, std::string const &pngfilename)
1528 {
1529
1530
1531
1532
1533
1534 if (!canvas)
1535 {
1536 std::cout << __PRETTY_FUNCTION__ << " TCanvas is Null Pointer" << std::endl;
1537 return -2;
1538 }
1539 if (pngfilename.empty())
1540 {
1541 std::cout << __PRETTY_FUNCTION__ << " emtpy png filename, not saving TCanvas "
1542 << canvas->GetName() << std::endl;
1543 return -1;
1544 }
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558 canvas->SaveAs(pngfilename.c_str());
1559 return 0;
1560 }
1561
1562 int OnlMonClient::HistoToPng(TH1 *histo, std::string const &pngfilename, const char *drawopt, const int statopt)
1563 {
1564 TCanvas *cgiCanv = new TCanvas("cgiCanv", "cgiCanv", 200, 200, 650, 500);
1565 gStyle->SetOptStat(statopt);
1566 cgiCanv->SetFillColor(0);
1567 cgiCanv->SetBorderMode(0);
1568 cgiCanv->SetBorderSize(2);
1569 cgiCanv->SetFrameFillColor(0);
1570 cgiCanv->SetFrameBorderMode(0);
1571 cgiCanv->SetTickx();
1572 cgiCanv->SetTicky();
1573 cgiCanv->cd();
1574 histo->SetMarkerStyle(8);
1575 histo->SetMarkerSize(0.15);
1576 histo->Draw(drawopt);
1577 uuid_t uu;
1578 uuid_generate(uu);
1579 char uuid[50];
1580 uuid_unparse(uu, uuid);
1581 std::string tmpname = "/tmp/TC" + std::string(uuid);
1582 cgiCanv->Print(tmpname.c_str(), "gif");
1583 TImage *img = TImage::Open(tmpname.c_str());
1584 img->WriteImage(pngfilename.c_str());
1585 if (remove(tmpname.c_str()))
1586 {
1587 std::cout << "Error removing " << tmpname << std::endl;
1588 }
1589 delete cgiCanv;
1590 return 0;
1591 }
1592
1593 int OnlMonClient::SaveLogFile(const OnlMonDraw &drawer)
1594 {
1595
1596
1597 std::ostringstream logfilename;
1598 const char *logdir = getenv("ONLMON_LOGDIR");
1599 if (logdir)
1600 {
1601 logfilename << logdir << "/";
1602 }
1603 int irun = RunNumber();
1604 logfilename << drawer.Name() << "_" << irun << ".log.gz";
1605 std::ifstream infile(logfilename.str().c_str(), std::ios_base::binary);
1606 if (infile.good())
1607 {
1608 std::string outfilename = htmlRegisterPage(drawer, "Logfile", "log", "txt.gz");
1609 std::ofstream outfile(outfilename.c_str(), std::ios_base::binary);
1610 outfile << infile.rdbuf();
1611 infile.close();
1612 outfile.close();
1613 }
1614 return 0;
1615 }
1616
1617 int OnlMonClient::SetStyleToDefault()
1618 {
1619 defaultStyle->cd();
1620 defaultStyle->Reset();
1621 defaultStyle->SetFrameBorderMode(0);
1622 defaultStyle->SetCanvasColor(0);
1623 defaultStyle->SetPadBorderMode(0);
1624 defaultStyle->SetCanvasBorderMode(0);
1625 defaultStyle->SetPalette(1, nullptr);
1626 return 0;
1627 }
1628
1629 void OnlMonClient::CacheRunDB(const int runno)
1630 {
1631 if (runno == cachedrun)
1632 {
1633 return;
1634 }
1635 standalone = 0;
1636 cosmicrun = 0;
1637 runtype = "unknown_runtype";
1638
1639 odbc::Connection *con {nullptr};
1640 odbc::Statement *query {nullptr};
1641 std::ostringstream cmd;
1642 try
1643 {
1644 con = odbc::DriverManager::getConnection("daq", "phnxrc", "");
1645 }
1646 catch (odbc::SQLException &e)
1647 {
1648 printf(" Exception caught during DriverManager::getConnection, Message: %s\n", e.getMessage().c_str());
1649 return;
1650 }
1651
1652 query = con->createStatement();
1653 cmd << "select runnumber from run where runnumber = " << runno;
1654 odbc::ResultSet *rs = nullptr;
1655 int ncount = 10;
1656 while (ncount > 0)
1657 {
1658 try
1659 {
1660 rs = query->executeQuery(cmd.str());
1661 }
1662 catch (odbc::SQLException &e)
1663 {
1664 printf("Exception caught for query %s\nMessage: %s", cmd.str().c_str(), e.getMessage().c_str());
1665 }
1666 if (!rs->next())
1667 {
1668 printf("run table query did not give any result, run %d not in DB yet countdown %d\n", runno, ncount);
1669 ncount--;
1670 sleep(10);
1671 delete rs;
1672 }
1673 else
1674 {
1675 delete rs;
1676 break;
1677 }
1678 }
1679 cmd.str("");
1680 cmd << "SELECT runtype FROM RUN WHERE RUNNUMBER = "
1681 << runno;
1682 if (verbosity > 0)
1683 {
1684 printf("command: %s\n", cmd.str().c_str());
1685 }
1686 try
1687 {
1688 rs = query->executeQuery(cmd.str());
1689 }
1690 catch (odbc::SQLException &e)
1691 {
1692 printf("Exception caught for query %s\nMessage: %s", cmd.str().c_str(), e.getMessage().c_str());
1693 }
1694 if (rs->next())
1695 {
1696 runtype = rs->getString("runtype");
1697 if (runtype == "cosmics")
1698 {
1699 cosmicrun = 1;
1700 }
1701 else
1702 {
1703 cosmicrun = 0;
1704 }
1705 }
1706 delete con;
1707 cachedrun = runno;
1708
1709 return;
1710 }
1711
1712 int OnlMonClient::isCosmicRun()
1713 {
1714 CacheRunDB(RunNumber());
1715 return cosmicrun;
1716 }
1717
1718 int OnlMonClient::isStandalone()
1719 {
1720 CacheRunDB(RunNumber());
1721 return standalone;
1722 }
1723
1724 std::string
1725 OnlMonClient::RunType()
1726 {
1727 CacheRunDB(RunNumber());
1728 return runtype;
1729 }
1730
1731 void OnlMonClient::FindAllMonitors()
1732 {
1733 for (auto &hostiter : MonitorHosts)
1734 {
1735 if (Verbosity() > 2)
1736 {
1737 std::cout << "checking " << hostiter << std::endl;
1738 }
1739 for (unsigned int moniport = OnlMonDefs::MONIPORT; moniport < OnlMonDefs::MONIPORT + OnlMonDefs::NUMMONIPORT; ++moniport)
1740 {
1741 requestMonitorList(hostiter, moniport);
1742 }
1743 }
1744 return;
1745 }
1746
1747 int OnlMonClient::FindMonitor(const std::string &name)
1748 {
1749
1750 int iret = 0;
1751 for (auto &hostiter : MonitorHosts)
1752 {
1753 if (Verbosity() > 2)
1754 {
1755 std::cout << "checking " << hostiter << std::endl;
1756 }
1757 for (unsigned int moniport = OnlMonDefs::MONIPORT; moniport < OnlMonDefs::MONIPORT + OnlMonDefs::NUMMONIPORT; ++moniport)
1758 {
1759 requestMonitorList(hostiter, moniport);
1760 if (Verbosity() > 2)
1761 {
1762 std::cout << "looking for " << name << std::endl;
1763 }
1764 auto moniter = MonitorHostPorts.find(name);
1765 if (moniter != MonitorHostPorts.end())
1766 {
1767 if (Verbosity() > 2)
1768 {
1769 std::cout << "found " << name << " running on " << moniter->second.first
1770 << " listening to port " << moniter->second.second << std::endl;
1771 }
1772 return 1;
1773 }
1774 }
1775 }
1776 return iret;
1777 }
1778
1779 int OnlMonClient::IsMonitorRunning(const std::string &name)
1780 {
1781 int iret = 0;
1782 std::string command = std::string("ISRUNNING") + ' ' + name;
1783 auto moniter = MonitorHostPorts.find(name);
1784 if (moniter == MonitorHostPorts.end())
1785 {
1786 return iret;
1787 }
1788 TSocket sock(moniter->second.first.c_str(), moniter->second.second);
1789 TMessage *mess;
1790 sock.Send(command.c_str());
1791 sock.Recv(mess);
1792 if (!mess)
1793 {
1794 std::cout << __PRETTY_FUNCTION__ << "Server not running on " << moniter->second.first << std::endl;
1795 sock.Close();
1796 return iret;
1797 }
1798 if (mess->What() == kMESS_STRING)
1799 {
1800 char str[OnlMonDefs::MSGLEN];
1801 mess->ReadString(str, OnlMonDefs::MSGLEN);
1802 delete mess;
1803 if (verbosity > 1)
1804 {
1805 std::cout << __PRETTY_FUNCTION__ << "Message: " << str << std::endl;
1806 }
1807 if (!strcmp(str, "Yes"))
1808 {
1809 iret = 1;
1810 }
1811 }
1812 sock.Send("Finished");
1813 sock.Close();
1814 return iret;
1815 }
1816
1817 std::string OnlMonClient::ExtractSubsystem(const std::string &fullfilename, OnlMonDraw *drawer)
1818 {
1819 std::string subsys = std::filesystem::path(fullfilename).filename();
1820 subsys = subsys.substr(subsys.find('-') + 1);
1821 subsys.resize(subsys.find(".root"));
1822 m_MonitorFetchedSet.insert(subsys);
1823 drawer->AddServer(subsys);
1824 return subsys;
1825 }
1826
1827 OnlMonDraw *OnlMonClient::GetDrawer(const std::string &name)
1828 {
1829 auto iter = DrawerList.find(name);
1830 if (iter != DrawerList.end())
1831 {
1832 return iter->second;
1833 }
1834 std::cout << "Cannot locate Drawer " << name << " in my list" << std::endl;
1835 return nullptr;
1836 }
1837
1838 void OnlMonClient::SaveServerHistoMap(const std::string &cachefilename)
1839 {
1840 std::ofstream cachefile(cachefilename);
1841 std::cout << "saving histomap to " << cachefilename << std::endl;
1842 for (auto &subs : SubsysHisto)
1843 {
1844 for (auto &histos : subs.second)
1845 {
1846 cachefile << histos.second->SubSystem() << " " << histos.first << " " << histos.second->ServerHost() << " " << histos.second->ServerPort() << std::endl;
1847 }
1848 }
1849 cachefile.close();
1850 return;
1851 }
1852
1853 void OnlMonClient::ReadServerHistoMap(const std::string &cachefilename)
1854 {
1855 std::ifstream cachefile(cachefilename);
1856 std::string hname;
1857 std::string subsys;
1858 std::string hostname;
1859 int port;
1860 if (cachefile.good())
1861 {
1862 std::cout << "opened histogram map cache file " << cachefilename << std::endl;
1863 std::string line;
1864 while (std::getline(cachefile, line))
1865 {
1866 std::istringstream iss(line);
1867 iss >> subsys;
1868 iss >> hname;
1869 iss >> hostname;
1870 iss >> port;
1871 AddServerHost(hostname);
1872 PutHistoInMap(hname,subsys,hostname,port);
1873 MonitorHostPorts.insert(std::make_pair(subsys, std::make_pair(hostname,port)));
1874 }
1875 cachefile.close();
1876 }
1877 else
1878 {
1879 std::cout << "failed to open histogram map cache file " << cachefilename << std::endl;
1880 }
1881 }