1ZMQ_SOCKET_MONITOR_V(3) 0MQ Manual ZMQ_SOCKET_MONITOR_V(3)
2
3
4
6 zmq_socket_monitor_versioned - monitor socket events
7
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
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
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
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
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
376 zmq(7)
377
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 07/22/2023 ZMQ_SOCKET_MONITOR_V(3)