1 #include "mfextensions/Receivers/UDP_receiver.hh"
2 #include "mfextensions/Receivers/ReceiverMacros.hh"
3 #include "messagefacility/Utilities/ELseverityLevel.h"
4 #include <boost/tokenizer.hpp>
5 #include <boost/regex.hpp>
8 mfviewer::UDPReceiver::UDPReceiver(fhicl::ParameterSet pset) : MVReceiver(pset)
9 , port_(pset.get<int>(
"port", 5140))
11 , socket_(io_service_)
12 , debug_(pset.get<bool>(
"debug_mode", false))
15 boost::system::error_code ec;
16 udp::endpoint listen_endpoint(boost::asio::ip::address::from_string(
"0.0.0.0"), port_);
17 socket_.open(listen_endpoint.protocol());
18 boost::asio::socket_base::reuse_address option(
true);
19 socket_.set_option(option, ec);
22 std::cerr <<
"An error occurred setting reuse_address: " << ec.message() << std::endl;
24 socket_.bind(listen_endpoint, ec);
28 std::cerr <<
"An error occurred in bind(): " << ec.message() << std::endl;
31 if (pset.get<
bool>(
"multicast_enable",
false))
33 std::string multicast_address_string = pset.get<std::string>(
"multicast_address",
"227.128.12.27");
34 auto multicast_address = boost::asio::ip::address::from_string(multicast_address_string);
35 boost::asio::ip::multicast::join_group group_option(multicast_address);
36 socket_.set_option(group_option, ec);
39 std::cerr <<
"An error occurred joining the multicast group " << multicast_address_string
40 <<
": " << ec.message() << std::endl;
43 boost::asio::ip::multicast::enable_loopback loopback_option(
true);
44 socket_.set_option(loopback_option, ec);
48 std::cerr <<
"An error occurred setting the multicast loopback option: " << ec.message() << std::endl;
51 if (debug_) { std::cout <<
"UDPReceiver Constructor Done" << std::endl; }
54 mfviewer::UDPReceiver::~UDPReceiver()
56 if (debug_) { std::cout <<
"Closing UDP Socket" << std::endl; }
60 void mfviewer::UDPReceiver::run()
62 while (!stopRequested_)
64 if (socket_.available() <= 0)
71 udp::endpoint remote_endpoint;
72 boost::system::error_code ec;
73 size_t packetSize = socket_.receive_from(boost::asio::buffer(buffer_), remote_endpoint, 0, ec);
74 if (debug_) { std::cout <<
"Recieved message; validating...(packetSize=" << packetSize <<
")" << std::endl; }
75 std::string message(buffer_, buffer_ + packetSize);
78 std::cerr <<
"Recieved error code: " << ec.message() << std::endl;
80 else if (packetSize > 0 && validate_packet(message))
82 if (debug_) { std::cout <<
"Valid UDP Message received! Sending to GUI!" << std::endl; }
83 emit NewMessage(read_msg(message));
88 std::cout <<
"UDPReceiver shutting down!" << std::endl;
91 qt_mf_msg mfviewer::UDPReceiver::read_msg(std::string input)
93 std::string hostname, category, application, message, hostaddr, file, line, module, eventID;
94 mf::ELseverityLevel sev;
99 if (debug_) { std::cout <<
"Recieved MF/Syslog message with contents: " << input << std::endl; }
101 boost::char_separator<char> sep(
"|",
"", boost::keep_empty_tokens);
102 typedef boost::tokenizer<boost::char_separator<char>> tokenizer;
103 tokenizer tokens(input, sep);
104 tokenizer::iterator it = tokens.begin();
107 boost::regex timestamp(
".*?(\\d{2}-[^-]*-\\d{4}\\s\\d{2}:\\d{2}:\\d{2})");
109 while (it != tokens.end() && !boost::regex_search(*it, res, timestamp))
114 if (it != tokens.end())
118 std::string value(res[1].first, res[1].second);
119 strptime(value.c_str(),
"%d-%b-%Y %H:%M:%S", &tm);
128 if (++it != tokens.end()) { seqNum = std::stoi(*it); }
130 catch (std::invalid_argument e) { it = prevIt; }
131 if (++it != tokens.end()) { hostname = *it; }
132 if (++it != tokens.end()) { hostaddr = *it; }
133 if (++it != tokens.end()) { sev = mf::ELseverityLevel(*it); }
134 if (++it != tokens.end()) { category = *it; }
135 if (++it != tokens.end()) { application = *it; }
139 if (++it != tokens.end()) { pid = std::stol(*it); }
141 catch (std::invalid_argument e) { it = prevIt; }
142 if (++it != tokens.end()) { eventID = *it; }
143 if (++it != tokens.end()) { module = *it; }
144 #if MESSAGEFACILITY_HEX_VERSION >= 0x20201 // Sender and receiver version must match!
145 if (++it != tokens.end()) { file = *it; }
146 if (++it != tokens.end()) { line = *it; }
148 std::ostringstream oss;
150 while (++it != tokens.end())
152 if (!first) { oss <<
"|"; }
153 else { first =
false; }
156 if (debug_) { std::cout <<
"Message content: " << oss.str() << std::endl; }
160 qt_mf_msg msg(hostname, category, application, pid, tv);
161 msg.setSeverity(sev);
162 msg.setMessage(
"UDPMessage", seqNum, message);
163 msg.setHostAddr(hostaddr);
164 msg.setFileName(file);
165 msg.setLineNumber(line);
166 msg.setModule(module);
167 msg.setEventID(eventID);
173 bool mfviewer::UDPReceiver::validate_packet(std::string input)
176 if (input.find(
"MF") == std::string::npos)
178 std::cout <<
"Failed to find \"MF\" in message: " << input << std::endl;
181 if (input.find(
"|") == std::string::npos)
183 std::cout <<
"Failed to find | separator character in message: " << input << std::endl;
189 #include "moc_UDP_receiver.cpp"
Receive messages through a UDP socket. Expects the syslog format provided by UDP_mfPlugin (ELUDP) ...
Qt wrapper around MessageFacility message