1 /* NagiosLogger C Client
3 * Author: Thomas Guyot-Sionnest <tguyot@gmail.com>
6 * gcc -Wall -lzmq -o client client.c
9 * gcc -O2 -DNDEBUG -lzmq -o client client.c && strip client
13 /* This is the send timeout in microseconds */
14 #define SEND_TIMEOUT 1000000 /* 1 second */
25 /* wrapper around zmq_poll which may return zero without reaching the
26 * specified timeout */
28 my_zmqpoll(zmq_pollitem_t
*items
, const int nitems
, const long timeout
)
30 struct timeval tv
, te
;
34 /* Populate te with timeout value */
35 te
.tv_sec
= timeout
/ 1000000;
36 te
.tv_usec
= timeout
- (te
.tv_sec
* 1000000);
38 rc
= gettimeofday(&tv
, NULL
);
41 /* Add current time to the timeout (end time) */
42 te
.tv_sec
+= tv
.tv_sec
;
43 te
.tv_usec
+= tv
.tv_usec
;
44 te
.tv_sec
+= te
.tv_usec
/ 1000000;
45 te
.tv_usec
%= 1000000;
47 /* Loop over, return either >0, or 0 after a timeout */
50 ret
= zmq_poll(items
, nitems
, tmleft
);
53 rc
= gettimeofday(&tv
, NULL
);
57 /* Keep on looping unless time's up */
58 if (te
.tv_sec
< tv
.tv_sec
||
59 (te
.tv_sec
== tv
.tv_sec
&& te
.tv_usec
<= tv
.tv_usec
))
61 tmleft
= ((te
.tv_sec
- tv
.tv_sec
) * 1000000) + (te
.tv_usec
- tv
.tv_usec
);
69 /* Send formatted message to url */
71 logevent(const char *url
, const char *message
)
76 zmq_pollitem_t items
[1];
78 /* Send the message */
79 rc
= zmq_msg_init_size(&query
, strlen(message
));
82 memcpy(zmq_msg_data(&query
), message
, strlen(message
));
84 ctx
= zmq_init (1, 1, ZMQ_POLL
);
87 socket
= zmq_socket(ctx
, ZMQ_REQ
);
90 rc
= zmq_connect(socket
, url
);
93 rc
= zmq_send(socket
, &query
, 0);
96 zmq_msg_close(&query
);
98 /* Wait for a reply */
99 rc
= zmq_msg_init(&query
);
102 items
[0].socket
= socket
;
103 items
[0].events
= ZMQ_POLLIN
;
104 rc
= my_zmqpoll(items
, 1, SEND_TIMEOUT
);
107 rc
= zmq_recv(socket
, &query
, ZMQ_NOBLOCK
);
108 if (rc
== -1 && errno
== EAGAIN
) {
112 zmq_msg_close(&query
);
116 /* Clean up - FIXME: random SEGV on zmq_term
124 /* Print usage and exit */
126 usage(const char *progname
, const char *error_msg
)
129 assert(progname
!= NULL
);
131 printf("Error: %s\n", error_msg
);
134 printf("Usage: %s <ZMQ_URL> <Server> <Notification Type> <Service State ID> <Host> <Service Desc> <Message>\n", progname
);
135 printf("Usage: %s <ZMQ_URL> <Server> <Notification Type> <Host State ID> <Host> <Message>\n", progname
);
143 /* Parse arguments and format message */
145 main(int argc
, char **argv
)
148 char *url
, *server
, *notype
, *stateid
, *host
, *message
;
149 char *fmt_msg
= NULL
;
150 char *service
= NULL
;
151 const char *paramtype
= "";
153 if (argc
< 7 || argc
> 8) {
154 for (i
=1; i
<argc
; i
++) {
155 if (strcmp(argv
[i
], "-h") == 0 ||
156 strcmp(argv
[i
], "--help") == 0) {
157 usage(argv
[0], NULL
);
160 usage(argv
[0], "Wrong number of arguments");
163 for (i
=1; i
<argc
; i
++) {
166 url
= strdup(argv
[i
]);
169 server
= strdup(argv
[i
]);
172 notype
= strdup(argv
[i
]);
175 stateid
= strdup(argv
[i
]);
176 if (strlen(stateid
) != strspn(stateid
, "0123456789"))
177 usage(argv
[0], "State ID is not a number");
180 host
= strdup(argv
[i
]);
184 message
= strdup(argv
[i
]);
187 service
= strdup(argv
[i
]);
188 paramtype
= "Service";
192 message
= strdup(argv
[i
]);
197 /* Format is: server(str)[Tab]notificationtype(str)[Tab]stateid(int)[Tab]host(str)[Tab]service(str)[Tab]message(str) */
198 i
= strlen(server
) + strlen(notype
) + strlen(stateid
) + strlen(host
) + (service
? strlen(service
) : 0) + strlen(message
) + 5 ;
199 fmt_msg
= malloc(i
+1);
200 assert(fmt_msg
!= NULL
);
201 rc
= snprintf(fmt_msg
, i
+1, "%s\t%s\t%s\t%s\t%s\t%s", server
, notype
, stateid
, host
, service
? service
: "", message
);
204 if (logevent(url
, fmt_msg
)) {
205 printf("Successfully sent %s Alert event to %s\n", paramtype
, url
);
208 printf("Failed sending %s Alert event to %s\n", paramtype
, url
);