Belle II Software development
LogListener Class Reference

Public Member Functions

 LogListener (ProcessController *con, int pipe[2], bool enableUnescapeNewlines=true)
 
void run ()
 

Private Attributes

ProcessControllerm_con
 
int m_pipe [2]
 
bool m_enableUnescapeNewlines
 

Detailed Description

Definition at line 19 of file LogListener.h.

Constructor & Destructor Documentation

◆ LogListener()

LogListener ( ProcessController con,
int  pipe[2],
bool  enableUnescapeNewlines = true 
)
inline

Definition at line 22 of file LogListener.h.

23 : m_con(con), m_enableUnescapeNewlines(enableUnescapeNewlines)
24 {
25 m_pipe[0] = pipe[0];
26 m_pipe[1] = pipe[1];
27 }

◆ ~LogListener()

~LogListener ( )
inline

Definition at line 28 of file LogListener.h.

28{}

Member Function Documentation

◆ run()

void run ( )

Definition at line 40 of file LogListener.cc.

41{
42 File fd(m_pipe[0]);
43 PipeReader preader(fd);
44 std::stringstream ss;
45 std::string s;
46 LogFile::Priority priority = LogFile::UNKNOWN;
47 int count = 0;
48 try {
49 while (true) {
50 int c = preader.readChar(); //read next character from pipe
51
52 if (c != '\n' && iscntrl(c)) continue; //character is unprintable, skip
53
54 if (c == '\n' && count > 0) { //newline received line was not empty -> message is assembled, submit
55 std::string assembledLogMessage(ss.str());
56
57 // basf2 has a flag to escape newlines with "\\n" to write multi-line log messages into a single line
58 // see: https://gitlab.desy.de/belle2/software/basf2/-/issues/6353
59 // if m_enableUnescapeNewlines is set, these "\\n" will be replaced with "\n" newlines again before the log message is sent out
60
61 if (m_enableUnescapeNewlines) {
62 assembledLogMessage = StringUtil::replace(assembledLogMessage, "\\n", "\n");
63 }
64
65 s = m_con->getParName() + " : " + assembledLogMessage;
66 ss.str("");
67 //m_con->lock();
68 if (priority == LogFile::UNKNOWN) {
69 priority = LogFile::DEBUG;
70 }
71
72 if (priority > LogFile::DEBUG) {
73 m_con->getCallback()->log(priority, s);
74 } else {
75 LogFile::debug(s);
76 }
77
78 if (m_con->getCallback()->getNode().getState() == RCState::RUNNING_S) {
79 if (priority == LogFile::ERROR) {
80 // m_con->getCallback()->log(LogFile::ERROR, s);
81 } else if (priority == LogFile::FATAL) {
82 // m_con->getCallback()->log(LogFile::FATAL, s));
83 m_con->getCallback()->setState(RCState::ERROR_ES);
84 }
85 }
86 //m_con->unlock();
87 count = 0;
88 priority = LogFile::UNKNOWN;
89 } else if (isprint(c)) { //continue to assemble message
90 if (count == 0 && c == '[') { //start of a "[DEBUG]"-like priority identifier preceding each log line
91 ss << c;
92 while (true) {
93 c = preader.readChar();
94 if (c == ']') { //end of a "[DEBUG]"-like priority identifier
95 ss << c;
96 s = ss.str();
97 if (s == "[DEBUG]") priority = LogFile::DEBUG;
98 else if (s == "[INFO]") priority = LogFile::INFO;
99 else if (s == "[NOTICE]") priority = LogFile::NOTICE;
100 else if (s == "[WARNING]") priority = LogFile::WARNING;
101 else if (s == "[ERROR]") priority = LogFile::ERROR;
102 else if (s == "[FATAL]") priority = LogFile::FATAL;
103 else if (s.find("STOP") != std::string::npos) {
104 StringList sl = StringUtil::split(s, '=');
105 if (sl.size() > 1) {
106 std::string nodename = StringUtil::replace(sl[1], "]", "");
107 try {
108 NSMCommunicator::send(NSMMessage(NSMNode(nodename), RCCommand::STOP));
109 } catch (const std::exception& e) {
110 }
111 }
112 count = 0;
113 ss.str("");
114 break;
115 }
116 if (priority > 0) {
117 count = 0;
118 ss.str("");
119 } else {
120 priority = LogFile::DEBUG;
121 }
122 break;
123 }
124 ss << c;
125 }
126 } else {
127 if (c != ' ' || count > 0) {
128 ss << c;
129 count++;
130 }
131 }
132 }
133 }
134 } catch (const IOException& e) {
135 LogFile::debug(e.what());
136 if (count > 0) {
137 s = m_con->getParName() + " : " + ss.str();
138 ss.str("");
139 //m_con->lock();
140 if (priority == LogFile::UNKNOWN) {
141 priority = LogFile::DEBUG;
142 }
143 m_con->getCallback()->log(priority, s);
144 if (m_con->getCallback()->getNode().getState() == RCState::RUNNING_S) {
145 if (priority == LogFile::ERROR) {
146 //m_con->getCallback()->reply(NSMMessage(NSMCommand::ERROR, s));
147 } else if (priority == LogFile::FATAL) {
148 //m_con->getCallback()->reply(NSMMessage(NSMCommand::ERROR, s));
149 m_con->getCallback()->setState(RCState::ERROR_ES);
150 }
151 }
152 //m_con->unlock();
153 }
154 }
155 close(m_pipe[0]);
156}

Member Data Documentation

◆ m_con

ProcessController* m_con
private

Definition at line 34 of file LogListener.h.

◆ m_enableUnescapeNewlines

bool m_enableUnescapeNewlines
private

Definition at line 37 of file LogListener.h.

◆ m_pipe

int m_pipe[2]
private

Definition at line 35 of file LogListener.h.


The documentation for this class was generated from the following files: