Sorry, forgot to attach the patch! BTW this is not really meant for master but rather for review.
-Pieter On Thu, Feb 17, 2011 at 4:28 PM, Pieter Hintjens <[email protected]> wrote: > Hi all, Martin, > > Here is a patch that starts using sys://log in the core. I've logged > the two events that cause most pain, disconnecting peers due to > duplicate identities, and discarding messages that can't be routed via > an XREP due to a mangled envelope. > > The code is pretty crude but it works. > > In C, this is how to fetch and print syslog errors in an application: > > > static void * > syslog_monitor (void *monitor) { > while (1) { > zmq_msg_t message; > zmq_msg_init (&message); > if (zmq_recv (monitor, &message, 0)) > exit (1); // Context terminated, exit > int size = zmq_msg_size (&message); > char *string = malloc (size + 1); > memcpy (string, zmq_msg_data (&message), size); > zmq_msg_close (&message); > string [size] = 0; > printf ("E: (syslog) %s\n", string); > } > return NULL; > } > > int main (int argc, char *argv[]) > { > void *context = zmq_init (1); > > // Start syslog monitor > // Bind subscriber socket to sys://log > void *monitor = zmq_socket (context, ZMQ_SUB); > zmq_connect (monitor, "sys://log"); > zmq_setsockopt (monitor, ZMQ_SUBSCRIBE, NULL, 0); > pthread_t thread; > pthread_create (&thread, NULL, syslog_monitor, monitor); > > ... > -Pieter >
From 757637a90a4bed7178f50fed05d85a9b4eb10b5e Mon Sep 17 00:00:00 2001 From: Pieter Hintjens <[email protected]> Date: Thu, 17 Feb 2011 16:23:01 +0100 Subject: [PATCH 149/149] Added syslog reporting of some major events in 0MQ - log method in object base class sends formatted report to sys://log. - xrep warns when it cannot route a message due to an unknown envelope identity - session warns when it disconnects a peer due to duplicate identity Signed-off-by: Pieter Hintjens <[email protected]> --- src/object.cpp | 34 ++++++++++++++++++++++++++++++++-- src/object.hpp | 7 +++++-- src/session.cpp | 1 + src/xrep.cpp | 2 ++ 4 files changed, 40 insertions(+), 4 deletions(-) diff --git a/src/object.cpp b/src/object.cpp index 9ec73f7..525c04f 100644 --- a/src/object.cpp +++ b/src/object.cpp @@ -31,6 +31,7 @@ zmq::object_t::object_t (ctx_t *ctx_, uint32_t tid_) : ctx (ctx_), tid (tid_) { + memcpy (last_sys_error, " ", 4); } zmq::object_t::object_t (object_t *parent_) : @@ -151,9 +152,38 @@ void zmq::object_t::destroy_socket (socket_base_t *socket_) ctx->destroy_socket (socket_); } -void zmq::object_t::log (zmq_msg_t *msg_) -{ - ctx->log (msg_); +// Sends the string to sys://log, and if the identity is not null +// reports that as a readable string. +// +void zmq::object_t::log (const char *string_, const blob_t &identity_) +{ + // We log errors in 0MQ string format, with trailing null byte + // First four characters of string are error identifier + // We discard duplicates to avoid error message storms + if (memcmp (last_sys_error, string_, 4)) { + ::zmq_msg_t msg; + std::string report = ""; + + report += string_; + if (&identity_) { + report += " (identity = 0x"; + for (uint i = 0; i < identity_.length() && i < 32; i++) { + const char hex [] = "0123456789ABCDEF"; + report += hex [identity_[i] >> 4]; + report += hex [identity_[i] & 15]; + } + report += ", \""; + for (uint i = 0; i < identity_.length() && i < 32; i++) + report += isprint (identity_[i])? identity_[i]: '.'; + report += "\")\0"; + } + // Log the error message + zmq_msg_init_size (&msg, report.length ()); + memcpy (zmq_msg_data (&msg), report.c_str (), report.length ()); + ctx->log (&msg); + zmq_msg_close (&msg); + memcpy (last_sys_error, string_, 4); + } } zmq::io_thread_t *zmq::object_t::choose_io_thread (uint64_t affinity_) diff --git a/src/object.hpp b/src/object.hpp index 748a339..c4c8000 100644 --- a/src/object.hpp +++ b/src/object.hpp @@ -51,8 +51,8 @@ namespace zmq struct endpoint_t find_endpoint (const char *addr_); void destroy_socket (class socket_base_t *socket_); - // Logs an message. - void log (zmq_msg_t *msg_); + // Logs a system error string + void log (const char *string_, const blob_t &identity_); // Chooses least loaded I/O thread. class io_thread_t *choose_io_thread (uint64_t affinity_); @@ -115,6 +115,9 @@ namespace zmq // Thread ID of the thread the object belongs to. uint32_t tid; + // Last error this object logged + char last_sys_error [4]; + void send_command (command_t &cmd_); object_t (const object_t&); diff --git a/src/session.cpp b/src/session.cpp index 350d043..fb0cd5a 100644 --- a/src/session.cpp +++ b/src/session.cpp @@ -234,6 +234,7 @@ void zmq::session_t::process_attach (i_engine *engine_, // If the session already has an engine attached, destroy new one. // Note new engine is not plugged in yet, we don't have to unplug it. if (engine) { + log ("DPID: duplicate peer identity - disconnecting peer", peer_identity_); delete engine_; return; } diff --git a/src/xrep.cpp b/src/xrep.cpp index 9c985c0..135630d 100644 --- a/src/xrep.cpp +++ b/src/xrep.cpp @@ -178,6 +178,8 @@ int zmq::xrep_t::xsend (zmq_msg_t *msg_, int flags_) outpipes_t::iterator it = outpipes.find (identity); if (it != outpipes.end ()) current_out = it->second.writer; + else + log ("IDNF: no such identity, cannot route message - discarding", identity); } int rc = zmq_msg_close (msg_); -- 1.7.0.4
_______________________________________________ zeromq-dev mailing list [email protected] http://lists.zeromq.org/mailman/listinfo/zeromq-dev
