1 #define TRACE_NAME "UDP_Receiver"
3 #include "mfextensions/Receivers/UDP_receiver.hh"
4 #include "mfextensions/Receivers/ReceiverMacros.hh"
6 #include "messagefacility/Utilities/ELseverityLevel.h"
7 #include <boost/tokenizer.hpp>
8 #include <boost/regex.hpp>
13 , message_port_(pset.get<int>(
"port", 5140))
14 , message_addr_(pset.get<std::string>(
"message_address",
"227.128.12.27"))
15 , multicast_enable_(pset.get<bool>(
"multicast_enable", false))
16 , multicast_out_addr_(pset.get<std::string>(
"multicast_interface_ip",
"0.0.0.0"))
19 TLOG(TLVL_TRACE) <<
"UDPReceiver Constructor";
23 void mfviewer::UDPReceiver::setupMessageListener_()
25 TLOG(TLVL_INFO) <<
"Setting up message listen socket, address=" << message_addr_ <<
":" << message_port_;
26 message_socket_ = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
27 if (message_socket_ < 0)
29 TLOG(TLVL_ERROR) <<
"Error creating socket for receiving messages! err=" << strerror(errno);
33 struct sockaddr_in si_me_request;
36 if (setsockopt(message_socket_, SOL_SOCKET, SO_REUSEADDR, &yes,
sizeof(yes)) < 0)
38 TLOG(TLVL_ERROR) <<
"Unable to enable port reuse on message socket, err=" << strerror(errno);
41 memset(&si_me_request, 0,
sizeof(si_me_request));
42 si_me_request.sin_family = AF_INET;
43 si_me_request.sin_port = htons(message_port_);
44 si_me_request.sin_addr.s_addr = htonl(INADDR_ANY);
45 if (bind(message_socket_, (
struct sockaddr *)&si_me_request,
sizeof(si_me_request)) == -1)
47 TLOG(TLVL_ERROR) <<
"Cannot bind message socket to port " << message_port_ <<
", err=" << strerror(errno);
51 if (message_addr_ !=
"localhost" && multicast_enable_)
54 int sts =
ResolveHost(message_addr_.c_str(), mreq.imr_multiaddr);
57 TLOG(TLVL_ERROR) <<
"Unable to resolve multicast message address, err=" << strerror(errno);
63 TLOG(TLVL_ERROR) <<
"Unable to resolve hostname for " << multicast_out_addr_;
66 if (setsockopt(message_socket_, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq,
sizeof(mreq)) < 0)
68 TLOG(TLVL_ERROR) <<
"Unable to join multicast group, err=" << strerror(errno);
72 TLOG(TLVL_INFO) <<
"Done setting up message receive socket";
78 TLOG(TLVL_DEBUG) <<
"Closing message receive socket";
79 close(message_socket_);
85 while (!stopRequested_)
87 if (message_socket_ == -1) setupMessageListener_();
90 struct pollfd ufds[1];
91 ufds[0].fd = message_socket_;
92 ufds[0].events = POLLIN | POLLPRI | POLLERR;
93 int rv = poll(ufds, 1, ms_to_wait);
96 if (rv <= 0 || (ufds[0].revents != POLLIN && ufds[0].revents != POLLPRI))
98 if (rv == 1 && (ufds[0].revents & (POLLNVAL | POLLERR | POLLHUP)))
100 close(message_socket_);
101 message_socket_ = -1;
110 char buffer[TRACE_STREAMER_MSGMAX + 1];
111 auto packetSize = read(message_socket_, &buffer, TRACE_STREAMER_MSGMAX);
114 TLOG(TLVL_ERROR) <<
"Error receiving message, errno=" << errno <<
" (" << strerror(errno) <<
")";
118 TLOG(TLVL_TRACE) <<
"Recieved message; validating...(packetSize=" << packetSize <<
")";
119 std::string message(buffer, buffer + packetSize);
120 if (validate_packet(message))
122 TLOG(TLVL_TRACE) <<
"Valid UDP Message received! Sending to GUI!";
123 emit NewMessage(read_msg(message));
127 TLOG(TLVL_INFO) <<
"UDPReceiver shutting down!";
132 std::string hostname, category, application, message, hostaddr, file, line, module, eventID;
133 mf::ELseverityLevel sev;
138 TLOG(TLVL_TRACE) <<
"Recieved MF/Syslog message with contents: " << input;
140 boost::char_separator<char> sep(
"|",
"", boost::keep_empty_tokens);
141 typedef boost::tokenizer<boost::char_separator<char>> tokenizer;
142 tokenizer tokens(input, sep);
143 tokenizer::iterator it = tokens.begin();
146 boost::regex timestamp(
".*?(\\d{2}-[^-]*-\\d{4}\\s\\d{2}:\\d{2}:\\d{2})");
148 while (it != tokens.end() && !boost::regex_search(*it, res, timestamp))
153 if (it != tokens.end())
157 std::string value(res[1].first, res[1].second);
158 strptime(value.c_str(),
"%d-%b-%Y %H:%M:%S", &tm);
167 if (++it != tokens.end()) { seqNum = std::stoi(*it); }
169 catch (std::invalid_argument e) { it = prevIt; }
170 if (++it != tokens.end()) { hostname = *it; }
171 if (++it != tokens.end()) { hostaddr = *it; }
172 if (++it != tokens.end()) { sev = mf::ELseverityLevel(*it); }
173 if (++it != tokens.end()) { category = *it; }
174 if (++it != tokens.end()) { application = *it; }
178 if (++it != tokens.end()) { pid = std::stol(*it); }
180 catch (std::invalid_argument e) { it = prevIt; }
181 if (++it != tokens.end()) { eventID = *it; }
182 if (++it != tokens.end()) { module = *it; }
183 #if MESSAGEFACILITY_HEX_VERSION >= 0x20201 // Sender and receiver version must match!
184 if (++it != tokens.end()) { file = *it; }
185 if (++it != tokens.end()) { line = *it; }
187 std::ostringstream oss;
189 while (++it != tokens.end())
191 if (!first) { oss <<
"|"; }
192 else { first =
false; }
195 TLOG(TLVL_TRACE) <<
"Message content: " << oss.str();
197 #if MESSAGEFACILITY_HEX_VERSION < 0x20201 // Sender and receiver version must match!
198 boost::regex fileLine(
"^\\s*([^:]*\\.[^:]{1,3}):(\\d+)(.*)");
199 if (boost::regex_search(message, res, fileLine))
201 file = std::string(res[1].first, res[1].second);
202 line = std::string(res[2].first, res[2].second);
203 std::string messagetmp = std::string(res[3].first, res[3].second);
204 message = messagetmp;
209 qt_mf_msg msg(hostname, category, application, pid, tv);
211 msg.
setMessage(
"UDPMessage", seqNum, message);
225 if (input.find(
"MF") == std::string::npos)
227 TLOG(TLVL_WARNING) <<
"Failed to find \"MF\" in message: " << input;
230 if (input.find(
"|") == std::string::npos)
232 TLOG(TLVL_WARNING) <<
"Failed to find | separator character in message: " << input;
238 #include "moc_UDP_receiver.cpp"
void updateText()
Parse fields and create HTML string representing message
void setEventID(std::string eventID)
Set the Event ID of the message
void run() override
Receiver method. Receive messages and emit NewMessage signal
int ResolveHost(char const *host_in, in_addr &addr)
Convert a string hostname to a in_addr suitable for socket communication.
static bool validate_packet(std::string input)
Run simple validation tests on message
void setFileName(std::string file)
Set the file name field
Receive messages through a UDP socket. Expects the syslog format provided by UDP_mfPlugin (ELUDP) ...
UDPReceiver(fhicl::ParameterSet pset)
UDPReceiver Constructor
Qt wrapper around MessageFacility message
int GetInterfaceForNetwork(char const *host_in, in_addr &addr)
Convert an IP address to the network address of the interface sharing the subnet mask.
void setMessage(std::string prefix, int iteration, std::string msg)
Set the message
virtual ~UDPReceiver()
Destructor – Close socket
A MVReceiver class listens for messages and raises a signal when one arrives
void setSeverity(mf::ELseverityLevel sev)
Set the Severity of the message (MF levels)
void setHostAddr(std::string hostaddr)
Set the hostaddr field
void setLineNumber(std::string line)
Set the line number field
qt_mf_msg read_msg(std::string input)
Parse incoming message
void setModule(std::string module)
Set the module name