Belle II Software  release-05-01-25
LogListener.cc
1 #include "daq/slc/readout/LogListener.h"
2 
3 #include "daq/slc/readout/ProcessController.h"
4 
5 #include <daq/slc/runcontrol/RCCallback.h>
6 #include <daq/slc/runcontrol/RCCommand.h>
7 #include <daq/slc/nsm/NSMCommunicator.h>
8 
9 #include <daq/slc/system/File.h>
10 #include <daq/slc/system/FileReader.h>
11 
12 #include <daq/slc/base/IOException.h>
13 #include <daq/slc/base/StringUtil.h>
14 #include <daq/slc/system/LogFile.h>
15 
16 #include <iostream>
17 #include <sstream>
18 #include <ctype.h>
19 
20 namespace Belle2 {
27 
29 }
30 
31 using namespace Belle2;
32 
33 void LogListener::run()
34 {
35  File fd(m_pipe[0]);
36  PipeReader preader(fd);
37  char c;
38  std::stringstream ss;
39  std::string s;
40  LogFile::Priority priority = LogFile::UNKNOWN;
41  int count = 0;
42  try {
43  while (true) {
44  c = preader.readChar(); //read next character from pipe
45 
46  if (c != '\n' && iscntrl(c)) continue; //character is unprintable, skip
47 
48  if (c == '\n' && count > 0) { //newline received line was not empty -> message is assembled, submit
49  std::string assembledLogMessage(ss.str());
50 
51  // basf2 has a flag to escape newlines with "\\n" to write multi-line log messages into a single line
52  // see: https://agira.desy.de/browse/BII-6470
53  // if m_enableUnescapeNewlines is set, these "\\n" will be replaced with "\n" newlines again before the log message is sent out
54 
55  if (m_enableUnescapeNewlines) {
56  assembledLogMessage = StringUtil::replace(assembledLogMessage, "\\n", "\n");
57  }
58 
59  s = m_con->getParName() + " : " + assembledLogMessage;
60  ss.str("");
61  //m_con->lock();
62  if (priority == LogFile::UNKNOWN) {
63  priority = LogFile::DEBUG;
64  }
65 
66  if (priority > LogFile::DEBUG) {
67  m_con->getCallback()->log(priority, s);
68  } else {
69  LogFile::debug(s);
70  }
71 
72  if (m_con->getCallback()->getNode().getState() == RCState::RUNNING_S) {
73  if (priority == LogFile::ERROR) {
74  // m_con->getCallback()->log(LogFile::ERROR, s);
75  } else if (priority == LogFile::FATAL) {
76  // m_con->getCallback()->log(LogFile::FATAL, s));
77  m_con->getCallback()->setState(RCState::ERROR_ES);
78  }
79  }
80  //m_con->unlock();
81  count = 0;
82  priority = LogFile::UNKNOWN;
83  } else if (isprint(c)) { //continue to assemble message
84  if (count == 0 && c == '[') { //start of a "[DEBUG]"-like priority identifier preceding each log line
85  ss << c;
86  while (true) {
87  c = preader.readChar();
88  if (c == ']') { //end of a "[DEBUG]"-like priority identifier
89  ss << c;
90  s = ss.str();
91  if (s == "[DEBUG]") priority = LogFile::DEBUG;
92  else if (s == "[INFO]") priority = LogFile::INFO;
93  else if (s == "[NOTICE]") priority = LogFile::NOTICE;
94  else if (s == "[WARNING]") priority = LogFile::WARNING;
95  else if (s == "[ERROR]") priority = LogFile::ERROR;
96  else if (s == "[FATAL]") priority = LogFile::FATAL;
97  else if (s.find("STOP") != std::string::npos) {
98  StringList sl = StringUtil::split(s, '=');
99  if (sl.size() > 1) {
100  std::string nodename = StringUtil::replace(sl[1], "]", "");
101  try {
102  NSMCommunicator::send(NSMMessage(NSMNode(nodename), RCCommand::STOP));
103  } catch (const std::exception& e) {
104  }
105  }
106  count = 0;
107  ss.str("");
108  break;
109  }
110  if (priority > 0) {
111  count = 0;
112  ss.str("");
113  } else {
114  priority = LogFile::DEBUG;
115  }
116  break;
117  }
118  ss << c;
119  }
120  } else {
121  if (c != ' ' || count > 0) {
122  ss << c;
123  count++;
124  }
125  }
126  }
127  }
128  } catch (const IOException& e) {
129  LogFile::debug(e.what());
130  if (count > 0) {
131  s = m_con->getParName() + " : " + ss.str();
132  ss.str("");
133  //m_con->lock();
134  if (priority == LogFile::UNKNOWN) {
135  priority = LogFile::DEBUG;
136  }
137  m_con->getCallback()->log(priority, s);
138  if (m_con->getCallback()->getNode().getState() == RCState::RUNNING_S) {
139  if (priority == LogFile::ERROR) {
140  //m_con->getCallback()->reply(NSMMessage(NSMCommand::ERROR, s));
141  } else if (priority == LogFile::FATAL) {
142  //m_con->getCallback()->reply(NSMMessage(NSMCommand::ERROR, s));
143  m_con->getCallback()->setState(RCState::ERROR_ES);
144  }
145  }
146  //m_con->unlock();
147  }
148  }
149  close(m_pipe[0]);
150 }
prepareAsicCrosstalkSimDB.e
e
aux.
Definition: prepareAsicCrosstalkSimDB.py:53
Belle2::NSMNode
Definition: NSMNode.h:14
Belle2::IOException
Definition: IOException.h:12
Belle2::File
Definition: File.h:14
Belle2::NSMMessage
Definition: NSMMessage.h:29
Belle2
Abstract base class for different kinds of events.
Definition: MillepedeAlgorithm.h:19
Belle2::FileReader
Definition: FileReader.h:13