1 #define TRACE_NAME "UDP_Receiver"
3 #include "mfextensions/Receivers/UDP_receiver.hh"
5 #include <boost/tokenizer.hpp>
7 #include "messagefacility/Utilities/ELseverityLevel.h"
8 #include "mfextensions/Receivers/ReceiverMacros.hh"
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")),
18 timestamp_regex_(
"(\\d{2}-[^-]*-\\d{4}\\s\\d{2}:\\d{2}:\\d{2})"),
19 file_line_regex_(
"^\\s*([^:]*\\.[^:]{1,3}):(\\d+)(.*)") {
20 TLOG(TLVL_TRACE) <<
"UDPReceiver Constructor";
23 void mfviewer::UDPReceiver::setupMessageListener_() {
24 TLOG(TLVL_INFO) <<
"Setting up message listen socket, address=" << message_addr_ <<
":" << message_port_;
25 message_socket_ = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
26 if (message_socket_ < 0) {
27 TLOG(TLVL_ERROR) <<
"Error creating socket for receiving messages! err=" << strerror(errno);
31 struct sockaddr_in si_me_request;
34 if (setsockopt(message_socket_, SOL_SOCKET, SO_REUSEADDR, &yes,
sizeof(yes)) < 0) {
35 TLOG(TLVL_ERROR) <<
"Unable to enable port reuse on message socket, err=" << strerror(errno);
38 memset(&si_me_request, 0,
sizeof(si_me_request));
39 si_me_request.sin_family = AF_INET;
40 si_me_request.sin_port = htons(message_port_);
41 si_me_request.sin_addr.s_addr = htonl(INADDR_ANY);
42 if (bind(message_socket_, (
struct sockaddr *)&si_me_request,
sizeof(si_me_request)) == -1) {
43 TLOG(TLVL_ERROR) <<
"Cannot bind message socket to port " << message_port_ <<
", err=" << strerror(errno);
47 if (message_addr_ !=
"localhost" && multicast_enable_) {
49 int sts =
ResolveHost(message_addr_.c_str(), mreq.imr_multiaddr);
51 TLOG(TLVL_ERROR) <<
"Unable to resolve multicast message address, err=" << strerror(errno);
56 TLOG(TLVL_ERROR) <<
"Unable to resolve hostname for " << multicast_out_addr_;
59 if (setsockopt(message_socket_, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq,
sizeof(mreq)) < 0) {
60 TLOG(TLVL_ERROR) <<
"Unable to join multicast group, err=" << strerror(errno);
64 TLOG(TLVL_INFO) <<
"Done setting up message receive socket";
68 TLOG(TLVL_DEBUG) <<
"Closing message receive socket";
69 close(message_socket_);
74 while (!stopRequested_) {
75 if (message_socket_ == -1) setupMessageListener_();
78 struct pollfd ufds[1];
79 ufds[0].fd = message_socket_;
80 ufds[0].events = POLLIN | POLLPRI | POLLERR;
81 int rv = poll(ufds, 1, ms_to_wait);
84 if (rv <= 0 || (ufds[0].revents != POLLIN && ufds[0].revents != POLLPRI)) {
85 if (rv == 1 && (ufds[0].revents & (POLLNVAL | POLLERR | POLLHUP))) {
86 close(message_socket_);
95 char buffer[TRACE_STREAMER_MSGMAX + 1];
96 auto packetSize = read(message_socket_, &buffer, TRACE_STREAMER_MSGMAX);
98 TLOG(TLVL_ERROR) <<
"Error receiving message, errno=" << errno <<
" (" << strerror(errno) <<
")";
100 TLOG(TLVL_TRACE) <<
"Recieved message; validating...(packetSize=" << packetSize <<
")";
101 std::string message(buffer, buffer + packetSize);
102 if (validate_packet(message)) {
103 TLOG(TLVL_TRACE) <<
"Valid UDP Message received! Sending to GUI!";
104 emit NewMessage(read_msg(message));
108 TLOG(TLVL_INFO) <<
"UDPReceiver shutting down!";
112 std::string hostname, category, application, message, hostaddr, file, line, module, eventID;
113 mf::ELseverityLevel sev;
118 TLOG(TLVL_TRACE) <<
"Recieved MF/Syslog message with contents: " << input;
120 boost::char_separator<char> sep(
"|",
"", boost::keep_empty_tokens);
121 typedef boost::tokenizer<boost::char_separator<char>> tokenizer;
122 tokenizer tokens(input, sep);
123 tokenizer::iterator it = tokens.begin();
127 while (it != tokens.end() && !boost::regex_search(*it, res, timestamp_regex_)) {
131 if (it != tokens.end()) {
134 std::string value(res[1].first, res[1].second);
135 strptime(value.c_str(),
"%d-%b-%Y %H:%M:%S", &tm);
143 if (++it != tokens.end()) {
144 seqNum = std::stoi(*it);
146 }
catch (
const std::invalid_argument& e) {
149 if (++it != tokens.end()) {
152 if (++it != tokens.end()) {
155 if (++it != tokens.end()) {
156 sev = mf::ELseverityLevel(*it);
158 if (++it != tokens.end()) {
161 if (++it != tokens.end()) {
166 if (++it != tokens.end()) {
167 pid = std::stol(*it);
169 }
catch (
const std::invalid_argument& e) {
172 if (++it != tokens.end()) {
175 if (++it != tokens.end()) {
178 #if MESSAGEFACILITY_HEX_VERSION >= 0x20201 // Sender and receiver version must match!
179 if (++it != tokens.end()) {
182 if (++it != tokens.end()) {
186 std::ostringstream oss;
188 while (++it != tokens.end()) {
196 TLOG(TLVL_TRACE) <<
"Message content: " << oss.str();
198 #if MESSAGEFACILITY_HEX_VERSION < 0x20201 // Sender and receiver version must match!
199 if (boost::regex_search(message, res, file_line_regex_)) {
200 file = std::string(res[1].first, res[1].second);
201 line = std::string(res[2].first, res[2].second);
202 std::string messagetmp = std::string(res[3].first, res[3].second);
203 message = messagetmp;
208 qt_mf_msg msg(hostname, category, application, pid, tv);
210 msg.
setMessage(
"UDPMessage", seqNum, message);
223 if (input.find(
"MF") == std::string::npos) {
224 TLOG(TLVL_WARNING) <<
"Failed to find \"MF\" in message: " << input;
227 if (input.find(
"|") == std::string::npos) {
228 TLOG(TLVL_WARNING) <<
"Failed to find | separator character in message: " << input;
234 #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