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

Reply via email to