1ZMQ_SOCKET_MONITOR_V(3)           0MQ Manual           ZMQ_SOCKET_MONITOR_V(3)
2
3
4

NAME

6       zmq_socket_monitor_versioned - monitor socket events
7

SYNOPSIS

9       int zmq_socket_monitor_versioned (void *socket, char *endpoint,
10       uint64_t events, int event_version, int type);
11
12       int zmq_socket_monitor_pipes_stats (void *socket);
13

DESCRIPTION

15       The zmq_socket_monitor_versioned() method lets an application thread
16       track socket events (like connects) on a ZeroMQ socket. Each call to
17       this method creates a ZMQ_PAIR socket and binds that to the specified
18       inproc:// endpoint. To collect the socket events, you must create your
19       own ZMQ_PAIR socket, and connect that to the endpoint.
20
21       The events argument is a bitmask of the socket events you wish to
22       monitor, see Supported events below. To monitor all events for a
23       version, use the event value ZMQ_EVENT_ALL_V<version>, e.g.
24       ZMQ_EVENT_ALL_V1. For non-DRAFT event versions, this value will not
25       change in the future, so new event types will only be added in new
26       versions (note that this is a change over zmq_socket_monitor and the
27       unversioned ZMQ_EVENT_ALL).
28
29       Note that event_version 2 is currently in DRAFT mode. The protocol may
30       be changed at any time for event_versions in DRAFT.
31
32       ZMQ_CURRENT_EVENT_VERSION and ZMQ_CURRENT_EVENT_VERSION_DRAFT are
33       always defined to the most recent stable or DRAFT event version, which
34       are currently 1 resp. 2
35
36       This page describes the protocol for event_version 2 only. For the
37       protocol used with event_version 1, please refer to
38       zmq_socket_monitor(3).
39
40       Each event is sent in multiple frames. The first frame contains an
41       event number (64 bits). The number and content of further frames depend
42       on this event number.
43
44       Unless it is specified differently, the second frame contains the
45       number of value frames that will follow it as a 64 bits integer. The
46       third frame to N-th frames contain an event value (64 bits) that
47       provides additional data according to the event number. Each event type
48       might have a different number of values. The second-to-last and last
49       frames contain strings that specifies the affected connection or
50       endpoint. The former frame contains a string denoting the local
51       endpoint, while the latter frame contains a string denoting the remote
52       endpoint. Either of these may be empty, depending on the event type and
53       whether the connection uses a bound or connected local endpoint.
54
55       Note that the format of the second and further frames, and also the
56       number of frames, may be different for events added in the future.
57
58       The type argument is used to specify the type of the monitoring socket.
59       Supported types are ZMQ_PAIR, ZMQ_PUB and ZMQ_PUSH. Note that consumers
60       of the events will have to be compatible with the socket type, for
61       instance a monitoring socket of type ZMQ_PUB will require consumers of
62       type ZMQ_SUB. In the case that the monitoring socket type is of
63       ZMQ_PUB, the multipart message topic is the event number, thus
64       consumers should subscribe to the events they want to receive.
65
66       The zmq_socket_monitor_pipes_stats() method triggers an event of type
67       ZMQ_EVENT_PIPES_STATS for each connected peer of the monitored socket.
68       NOTE: zmq_socket_monitor_pipes_stats() is in DRAFT state.
69
70           Monitoring events are only generated by some transports: At the moment these
71           are SOCKS, TCP, IPC, and TIPC. Note that it is not an error to call
72           'zmq_socket_monitor_versioned' on a socket that is connected or bound to some
73           other transport, as this may not be known at the time
74           'zmq_socket_monitor_versioned' is called. Also, a socket can be connected/bound
75           to multiple endpoints using different transports.
76
77       Supported events (v1)
78
79           ZMQ_EVENT_CONNECTED
80           ~~~~~~~~~~~~~~~~~~~
81           The socket has successfully connected to a remote peer. The event value
82           is the file descriptor (FD) of the underlying network socket. Warning:
83           there is no guarantee that the FD is still valid by the time your code
84           receives this event.
85
86           ZMQ_EVENT_CONNECT_DELAYED
87           ~~~~~~~~~~~~~~~~~~~~~~~~~
88           A connect request on the socket is pending. The event value is unspecified.
89
90           ZMQ_EVENT_CONNECT_RETRIED
91           ~~~~~~~~~~~~~~~~~~~~~~~~~
92           A connect request failed, and is now being retried. The event value is the
93           reconnect interval in milliseconds. Note that the reconnect interval is
94           recalculated for each retry.
95
96           ZMQ_EVENT_LISTENING
97           ~~~~~~~~~~~~~~~~~~~
98           The socket was successfully bound to a network interface. The event value
99           is the FD of the underlying network socket. Warning: there is no guarantee
100           that the FD is still valid by the time your code receives this event.
101
102           ZMQ_EVENT_BIND_FAILED
103           ~~~~~~~~~~~~~~~~~~~~~
104           The socket could not bind to a given interface. The event value is the
105           errno generated by the system bind call.
106
107           ZMQ_EVENT_ACCEPTED
108           ~~~~~~~~~~~~~~~~~~
109           The socket has accepted a connection from a remote peer. The event value is
110           the FD of the underlying network socket. Warning: there is no guarantee that
111           the FD is still valid by the time your code receives this event.
112
113           ZMQ_EVENT_ACCEPT_FAILED
114           ~~~~~~~~~~~~~~~~~~~~~~~
115           The socket has rejected a connection from a remote peer. The event value is
116           the errno generated by the accept call.
117
118           ZMQ_EVENT_CLOSED
119           ~~~~~~~~~~~~~~~~
120           The socket was closed. The event value is the FD of the (now closed) network
121           socket.
122
123           ZMQ_EVENT_CLOSE_FAILED
124           ~~~~~~~~~~~~~~~~~~~~~~
125           The socket close failed. The event value is the errno returned by the system
126           call. Note that this event occurs only on IPC transports.
127
128           ZMQ_EVENT_DISCONNECTED
129           ~~~~~~~~~~~~~~~~~~~~~~
130           The socket was disconnected unexpectedly. The event value is the FD of the
131           underlying network socket. Warning: this socket will be closed.
132
133           ZMQ_EVENT_MONITOR_STOPPED
134           ~~~~~~~~~~~~~~~~~~~~~~~~~
135           Monitoring on this socket ended.
136
137           ZMQ_EVENT_HANDSHAKE_FAILED_NO_DETAIL
138           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
139           Unspecified error during handshake.
140           The event value is an errno.
141
142           ZMQ_EVENT_HANDSHAKE_SUCCEEDED
143           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
144           The ZMTP security mechanism handshake succeeded.
145           The event value is unspecified.
146
147           ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL
148           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
149           The ZMTP security mechanism handshake failed due to some mechanism protocol
150           error, either between the ZMTP mechanism peers, or between the mechanism
151           server and the ZAP handler. This indicates a configuration or implementation
152           error in either peer resp. the ZAP handler.
153           The event value is one of the ZMQ_PROTOCOL_ERROR_* values:
154           ZMQ_PROTOCOL_ERROR_ZMTP_UNSPECIFIED
155           ZMQ_PROTOCOL_ERROR_ZMTP_UNEXPECTED_COMMAND
156           ZMQ_PROTOCOL_ERROR_ZMTP_INVALID_SEQUENCE
157           ZMQ_PROTOCOL_ERROR_ZMTP_KEY_EXCHANGE
158           ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_UNSPECIFIED
159           ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_MESSAGE
160           ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_HELLO
161           ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_INITIATE
162           ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_ERROR
163           ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_READY
164           ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_WELCOME
165           ZMQ_PROTOCOL_ERROR_ZMTP_INVALID_METADATA
166           ZMQ_PROTOCOL_ERROR_ZMTP_CRYPTOGRAPHIC
167           ZMQ_PROTOCOL_ERROR_ZMTP_MECHANISM_MISMATCH
168           ZMQ_PROTOCOL_ERROR_ZAP_UNSPECIFIED
169           ZMQ_PROTOCOL_ERROR_ZAP_MALFORMED_REPLY
170           ZMQ_PROTOCOL_ERROR_ZAP_BAD_REQUEST_ID
171           ZMQ_PROTOCOL_ERROR_ZAP_BAD_VERSION
172           ZMQ_PROTOCOL_ERROR_ZAP_INVALID_STATUS_CODE
173           ZMQ_PROTOCOL_ERROR_ZAP_INVALID_METADATA
174
175           ZMQ_EVENT_HANDSHAKE_FAILED_AUTH
176           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
177           The ZMTP security mechanism handshake failed due to an authentication failure.
178           The event value is the status code returned by the ZAP handler (i.e. 300,
179           400 or 500).
180
181       Supported events (v2)
182
183           ZMQ_EVENT_PIPE_STATS
184           ~~~~~~~~~~~~~~~~~~~~
185           This event provides two values, the number of messages in each of the two
186           queues associated with the returned endpoint (respectively egress and ingress).
187           This event only triggers after calling the function
188           _zmq_socket_monitor_pipes_stats()_.
189           NOTE: this measurement is asynchronous, so by the time the message is received
190           the internal state might have already changed.
191           NOTE: when the monitored socket and the monitor are not used in a poll, the
192           event might not be delivered until an API has been called on the monitored
193           socket, like zmq_getsockopt for example (the option is irrelevant).
194           NOTE: in DRAFT state, not yet available in stable releases.
195
196
197
198           RETURN VALUE
199
200       The zmq_socket_monitor() and zmq_socket_monitor_pipes_stats() functions
201       return a value of 0 or greater if successful. Otherwise they return -1
202       and set errno to one of the values defined below.
203

ERRORS - ZMQ_SOCKET_MONITOR()

205       ETERM
206           The 0MQ context associated with the specified socket was
207           terminated.
208
209       EPROTONOSUPPORT
210           The transport protocol of the monitor endpoint is not supported.
211           Monitor sockets are required to use the inproc:// transport.
212
213       EINVAL
214           The monitor endpoint supplied does not exist or the specified
215           socket type is not supported.
216

ERRORS - ZMQ_SOCKET_MONITOR_PIPES_STATS()

218       ENOTSOCK
219           The socket parameter was not a valid 0MQ socket.
220
221       EINVAL
222           The socket did not have monitoring enabled.
223
224       EAGAIN
225           The monitored socket did not have any connections to monitor yet.
226

EXAMPLE

228       Monitoring client and server sockets.
229
230           //  Read one event off the monitor socket; return values and addresses
231           //  by reference, if not null, and event number by value. Returns -1
232           //  in case of error.
233
234           static uint64_t
235           get_monitor_event (void *monitor, uint64_t *value, char **local_address, char **remote_address)
236           {
237               //  First frame in message contains event number
238               zmq_msg_t msg;
239               zmq_msg_init (&msg);
240               if (zmq_msg_recv (&msg, monitor, 0) == -1)
241                   return -1;              //  Interrupted, presumably
242               assert (zmq_msg_more (&msg));
243
244               uint64_t event;
245               memcpy (&event, zmq_msg_data (&msg), sizeof (event));
246               zmq_msg_close (&msg);
247
248               //  Second frame in message contains the number of values
249               zmq_msg_init (&msg);
250               if (zmq_msg_recv (&msg, monitor, 0) == -1)
251                   return -1;              //  Interrupted, presumably
252               assert (zmq_msg_more (&msg));
253
254               uint64_t value_count;
255               memcpy (&value_count, zmq_msg_data (&msg), sizeof (value_count));
256               zmq_msg_close (&msg);
257
258               for (uint64_t i = 0; i < value_count; ++i) {
259                   //  Subsequent frames in message contain event values
260                   zmq_msg_init (&msg);
261                   if (zmq_msg_recv (&msg, monitor, 0) == -1)
262                       return -1;              //  Interrupted, presumably
263                   assert (zmq_msg_more (&msg));
264
265                   if (value_ && value_ + i)
266                       memcpy (value_ + i, zmq_msg_data (&msg), sizeof (*value_));
267                   zmq_msg_close (&msg);
268               }
269
270               //  Second-to-last frame in message contains local address
271               zmq_msg_init (&msg);
272               if (zmq_msg_recv (&msg, monitor, 0) == -1)
273                   return -1;              //  Interrupted, presumably
274               assert (zmq_msg_more (&msg));
275
276               if (local_address_) {
277                   uint8_t *data = (uint8_t *) zmq_msg_data (&msg);
278                   size_t size = zmq_msg_size (&msg);
279                   *local_address_ = (char *) malloc (size + 1);
280                   memcpy (*local_address_, data, size);
281                   (*local_address_)[size] = 0;
282               }
283               zmq_msg_close (&msg);
284
285               //  Last frame in message contains remote address
286               zmq_msg_init (&msg);
287               if (zmq_msg_recv (&msg, monitor, 0) == -1)
288                   return -1;              //  Interrupted, presumably
289               assert (!zmq_msg_more (&msg));
290
291               if (remote_address_) {
292                   uint8_t *data = (uint8_t *) zmq_msg_data (&msg);
293                   size_t size = zmq_msg_size (&msg);
294                   *remote_address_ = (char *) malloc (size + 1);
295                   memcpy (*remote_address_, data, size);
296                   (*remote_address_)[size] = 0;
297               }
298               zmq_msg_close (&msg);
299
300               return event;
301           }
302
303           int main (void)
304           {
305               void *ctx = zmq_ctx_new ();
306               assert (ctx);
307
308               //  We'll monitor these two sockets
309               void *client = zmq_socket (ctx, ZMQ_DEALER);
310               assert (client);
311               void *server = zmq_socket (ctx, ZMQ_DEALER);
312               assert (server);
313
314               //  Socket monitoring only works over inproc://
315               int rc = zmq_socket_monitor_versioned (client, "tcp://127.0.0.1:9999", 0, 2);
316               assert (rc == -1);
317               assert (zmq_errno () == EPROTONOSUPPORT);
318
319               //  Monitor all events on client and server sockets
320               rc = zmq_socket_monitor_versioned (client, "inproc://monitor-client", ZMQ_EVENT_ALL, 2);
321               assert (rc == 0);
322               rc = zmq_socket_monitor_versioned (server, "inproc://monitor-server", ZMQ_EVENT_ALL, 2);
323               assert (rc == 0);
324
325               //  Create two sockets for collecting monitor events
326               void *client_mon = zmq_socket (ctx, ZMQ_PAIR);
327               assert (client_mon);
328               void *server_mon = zmq_socket (ctx, ZMQ_PAIR);
329               assert (server_mon);
330
331               //  Connect these to the inproc endpoints so they'll get events
332               rc = zmq_connect (client_mon, "inproc://monitor-client");
333               assert (rc == 0);
334               rc = zmq_connect (server_mon, "inproc://monitor-server");
335               assert (rc == 0);
336
337               //  Now do a basic ping test
338               rc = zmq_bind (server, "tcp://127.0.0.1:9998");
339               assert (rc == 0);
340               rc = zmq_connect (client, "tcp://127.0.0.1:9998");
341               assert (rc == 0);
342               bounce (client, server);
343
344               //  Close client and server
345               close_zero_linger (client);
346               close_zero_linger (server);
347
348               //  Now collect and check events from both sockets
349               int event = get_monitor_event (client_mon, NULL, NULL);
350               if (event == ZMQ_EVENT_CONNECT_DELAYED)
351                   event = get_monitor_event (client_mon, NULL, NULL);
352               assert (event == ZMQ_EVENT_CONNECTED);
353               event = get_monitor_event (client_mon, NULL, NULL);
354               assert (event == ZMQ_EVENT_MONITOR_STOPPED);
355
356               //  This is the flow of server events
357               event = get_monitor_event (server_mon, NULL, NULL);
358               assert (event == ZMQ_EVENT_LISTENING);
359               event = get_monitor_event (server_mon, NULL, NULL);
360               assert (event == ZMQ_EVENT_ACCEPTED);
361               event = get_monitor_event (server_mon, NULL, NULL);
362               assert (event == ZMQ_EVENT_CLOSED);
363               event = get_monitor_event (server_mon, NULL, NULL);
364               assert (event == ZMQ_EVENT_MONITOR_STOPPED);
365
366               //  Close down the sockets
367               close_zero_linger (client_mon);
368               close_zero_linger (server_mon);
369               zmq_ctx_term (ctx);
370
371               return 0 ;
372           }
373
374

SEE ALSO

376       zmq(7)
377

AUTHORS

379       This page was written by the 0MQ community. To make a change please
380       read the 0MQ Contribution Policy at
381       http://www.zeromq.org/docs:contributing.
382
383
384
3850MQ 4.3.4                         01/21/2023           ZMQ_SOCKET_MONITOR_V(3)
Impressum