1- /* $Id$ */
1+ /* $Id: rrd_helpers.c 2200 2010-01-08 17:17:00Z d_pocock $ */
22#include <ctype.h>
33#include <stdio.h>
44#include <stdlib.h>
55#include <string.h>
66#include <sys/types.h>
77#include <sys/stat.h>
88#include <unistd.h>
9+ #include <fcntl.h>
910#include <rrd.h>
1011#include <gmetad.h>
1112#include <errno.h>
1415#include <sys/socket.h>
1516#include <netinet/in.h>
1617#include <netdb.h>
18+ #include <sys/poll.h>
1719
1820#include "rrd_helpers.h"
1921
@@ -236,44 +238,70 @@ static int
236238push_data_to_carbon ( char * graphite_msg )
237239{
238240 int port ;
239- int sock ;
241+ int carbon_socket ;
240242 struct sockaddr_in server ;
243+ int carbon_timeout = 500 ;
241244 int nbytes ;
245+ struct pollfd carbon_struct_poll ;
246+ int poll_rval ;
247+ int fl ;
248+
249+ if (gmetad_config .carbon_port )
250+ port = gmetad_config .carbon_port ;
251+ else
252+ port = 2003 ;
242253
243- port = gmetad_config .carbon_port ? gmetad_config .carbon_port : 2003 ;
244254
245255 debug_msg ("Carbon Proxy:: sending \'%s\' to %s" , graphite_msg , gmetad_config .carbon_server );
246256
247- /* Create a socket. */
248- sock = socket (PF_INET , SOCK_STREAM , 0 );
249- if (sock < 0 )
257+ /* Create a socket. */
258+ carbon_socket = socket (PF_INET , SOCK_STREAM , 0 );
259+ if (carbon_socket < 0 )
250260 {
251261 perror ("socket (client)" );
252- close (sock );
262+ close (carbon_socket );
253263 return EXIT_FAILURE ;
254264 }
255265
266+ /* Set the socket to not block */
267+ fl = fcntl (carbon_socket ,F_GETFL ,0 );
268+ fcntl (carbon_socket ,F_SETFL ,fl | O_NONBLOCK );
269+
256270 /* Connect to the server. */
257271 init_sockaddr (& server , gmetad_config .carbon_server , port );
258- if (0 > connect (sock ,
259- (struct sockaddr * ) & server ,
260- sizeof (server )))
261- {
262- perror ("connect (client)" );
263- close (sock );
264- return EXIT_FAILURE ;
265- }
266-
267- /* Send data to the server. */
268- nbytes = write (sock , graphite_msg , strlen (graphite_msg ) + 1 );
269- if (nbytes < 0 )
270- {
271- perror ("write" );
272- close (sock );
272+ connect (carbon_socket , (struct sockaddr * ) & server , sizeof (server ));
273+
274+ /* Start Poll */
275+ carbon_struct_poll .fd = carbon_socket ;
276+ carbon_struct_poll .events = POLLOUT ;
277+ poll_rval = poll ( & carbon_struct_poll , 1 , carbon_timeout ); // default timeout .5s
278+
279+ /* Send data to the server when the socket becomes ready */
280+ if ( poll_rval < 0 ) {
281+ debug_msg ("carbon proxy:: poll() error" );
282+ } else if ( poll_rval == 0 ) {
283+ debug_msg ("carbon proxy:: Timeout connecting to %s" ,gmetad_config .carbon_server );
284+ } else {
285+ if ( carbon_struct_poll .revents & POLLOUT ) {
286+ /* Ready to send data to the server. */
287+ debug_msg ("carbon proxy:: %s is ready to receive" ,gmetad_config .carbon_server );
288+ nbytes = write (carbon_socket , graphite_msg , strlen (graphite_msg ) + 1 );
289+ if (nbytes < 0 ) {
290+ perror ("write" );
291+ close (carbon_socket );
292+ return EXIT_FAILURE ;
293+ }
294+ } else if ( carbon_struct_poll .revents & POLLHUP ) {
295+ debug_msg ("carbon proxy:: Recvd an RST from %s during transmission" ,gmetad_config .carbon_server );
296+ close (carbon_socket );
297+ return EXIT_FAILURE ;
298+ } else if ( carbon_struct_poll .revents & POLLERR ) {
299+ debug_msg ("carbon proxy:: Recvd an POLLERR from %s during transmission" ,gmetad_config .carbon_server );
300+ close (carbon_socket );
273301 return EXIT_FAILURE ;
274302 }
275-
276- close (sock );
303+ }
304+ close (carbon_socket );
277305 return EXIT_SUCCESS ;
278306}
279307
@@ -282,15 +310,16 @@ write_data_to_carbon ( const char *source, const char *host, const char *metric,
282310 const char * sum , unsigned int process_time )
283311{
284312
285- char s_process_time [15 ];
313+ char s_process_time [15 ];
286314 char graphite_msg [ PATHSIZE + 1 ];
287315 int i ;
288316
289317 /* if process_time is undefined, we set it to the current time */
290318 if (!process_time )
291319 process_time = time (0 );
292320
293- sprintf (s_process_time , "%u" , process_time );
321+
322+ sprintf (s_process_time , "%u" , process_time );
294323
295324 /* Build the path */
296325 strncpy (graphite_msg , gmetad_config .graphite_prefix , PATHSIZE );
@@ -302,14 +331,18 @@ write_data_to_carbon ( const char *source, const char *host, const char *metric,
302331
303332
304333 if (host ) {
305- int hostlen = strlen (host );
306- char hostcp [hostlen + 1 ];
307-
308- /* find and replace . for _ in the hostname*/
309- for (i = 0 ; i <=hostlen ; i ++ ) {
310- hostcp [i ] = ( host [i ] == '.' ) ? '_' : host [i ];
334+ int hostlen = strlen (host );
335+ char hostcp [hostlen + 1 ];
336+
337+ /* find and replace . for _ in the hostname*/
338+ for (i = 0 ; i <=hostlen ; i ++ ){
339+ if ( host [i ] == '.' ) {
340+ hostcp [i ]= '_' ;
341+ }else {
342+ hostcp [i ]= host [i ];
343+ }
311344 }
312- hostcp [i + 1 ]= 0 ;
345+ hostcp [i + 1 ]= 0 ;
313346
314347 strncat (graphite_msg , "." , PATHSIZE - strlen (graphite_msg ));
315348
@@ -321,6 +354,7 @@ write_data_to_carbon ( const char *source, const char *host, const char *metric,
321354 for ( ; graphite_msg [i ] != 0 ; i ++ )
322355 graphite_msg [i ] = tolower (graphite_msg [i ]);
323356 }
357+
324358 }
325359
326360 strncat (graphite_msg , "." , PATHSIZE - strlen (graphite_msg ));
@@ -331,8 +365,7 @@ write_data_to_carbon ( const char *source, const char *host, const char *metric,
331365 strncat (graphite_msg , s_process_time , PATHSIZE - strlen (graphite_msg ));
332366 strncat (graphite_msg , "\n" , PATHSIZE - strlen (graphite_msg ));
333367
334- graphite_msg [strlen (graphite_msg )+ 1 ] = 0 ;
368+ graphite_msg [strlen (graphite_msg )+ 1 ] = 0 ;
335369
336370 return push_data_to_carbon ( graphite_msg );
337371}
338-
0 commit comments