Skip to content

Commit 7c702e4

Browse files
committed
Merge branch 'pr/846'
2 parents aa958d2 + 6f2d0db commit 7c702e4

File tree

3 files changed

+51
-1
lines changed

3 files changed

+51
-1
lines changed

src/collectd.conf.in

+1
Original file line numberDiff line numberDiff line change
@@ -1348,6 +1348,7 @@
13481348
# Host "localhost"
13491349
# Port "2003"
13501350
# Protocol "tcp"
1351+
# ReconnectInterval 0
13511352
# LogSendErrors true
13521353
# Prefix "collectd"
13531354
# Postfix "collectd"

src/collectd.conf.pod

+8
Original file line numberDiff line numberDiff line change
@@ -7277,6 +7277,14 @@ Service name or port number to connect to. Defaults to C<2003>.
72777277

72787278
Protocol to use when connecting to I<Graphite>. Defaults to C<tcp>.
72797279

7280+
=item B<ReconnectInterval> I<Seconds>
7281+
7282+
When set to non-zero, forces the connection to the Graphite backend to be
7283+
closed and re-opend periodically. This behavior is desirable in environments
7284+
where the connection to the Graphite backend is done through load balancers,
7285+
for example. When set to zero, the default, the connetion is kept open for as
7286+
long as possible.
7287+
72807288
=item B<LogSendErrors> B<false>|B<true>
72817289

72827290
If set to B<true> (the default), logs errors when sending data to I<Graphite>.

src/write_graphite.c

+42-1
Original file line numberDiff line numberDiff line change
@@ -94,8 +94,36 @@ struct wg_callback
9494
pthread_mutex_t send_lock;
9595
c_complain_t init_complaint;
9696
cdtime_t last_connect_time;
97+
98+
/* Force reconnect useful for load balanced environments */
99+
cdtime_t last_reconnect_time;
100+
cdtime_t reconnect_interval;
101+
_Bool reconnect_interval_reached;
97102
};
98103

104+
/* wg_force_reconnect_check closes cb->sock_fd when it was open for longer
105+
* than cb->reconnect_interval. Must hold cb->send_lock when calling. */
106+
static void wg_force_reconnect_check (struct wg_callback *cb)
107+
{
108+
cdtime_t now;
109+
110+
if (cb->reconnect_interval == 0)
111+
return;
112+
113+
/* check if address changes if addr_timeout */
114+
now = cdtime ();
115+
if ((now - cb->last_reconnect_time) < cb->reconnect_interval)
116+
return;
117+
118+
/* here we should close connection on next */
119+
close (cb->sock_fd);
120+
cb->sock_fd = -1;
121+
cb->last_reconnect_time = now;
122+
cb->reconnect_interval_reached = 1;
123+
124+
INFO ("write_graphite plugin: Connection closed after %.3f seconds.",
125+
CDTIME_T_TO_DOUBLE (now - cb->last_reconnect_time));
126+
}
99127

100128
/*
101129
* Functions
@@ -250,7 +278,13 @@ static int wg_callback_init (struct wg_callback *cb)
250278
cb->node, cb->service, cb->protocol);
251279
}
252280

253-
wg_reset_buffer (cb);
281+
/* wg_force_reconnect_check does not flush the buffer before closing a
282+
* sending socket, so only call wg_reset_buffer() if the socket was closed
283+
* for a different reason (tracked in cb->reconnect_interval_reached). */
284+
if (!cb->reconnect_interval_reached || (cb->send_buf_free == 0))
285+
wg_reset_buffer (cb);
286+
else
287+
cb->reconnect_interval_reached = 0;
254288

255289
return (0);
256290
}
@@ -326,6 +360,8 @@ static int wg_send_message (char const *message, struct wg_callback *cb)
326360

327361
pthread_mutex_lock (&cb->send_lock);
328362

363+
wg_force_reconnect_check (cb);
364+
329365
if (cb->sock_fd < 0)
330366
{
331367
status = wg_callback_init (cb);
@@ -462,6 +498,9 @@ static int wg_config_node (oconfig_item_t *ci)
462498
cb->node = strdup (WG_DEFAULT_NODE);
463499
cb->service = strdup (WG_DEFAULT_SERVICE);
464500
cb->protocol = strdup (WG_DEFAULT_PROTOCOL);
501+
cb->last_reconnect_time = cdtime();
502+
cb->reconnect_interval = 0;
503+
cb->reconnect_interval_reached = 0;
465504
cb->log_send_errors = WG_DEFAULT_LOG_SEND_ERRORS;
466505
cb->prefix = NULL;
467506
cb->postfix = NULL;
@@ -502,6 +541,8 @@ static int wg_config_node (oconfig_item_t *ci)
502541
status = -1;
503542
}
504543
}
544+
else if (strcasecmp ("ReconnectInterval", child->key) == 0)
545+
cf_util_get_cdtime (child, &cb->reconnect_interval);
505546
else if (strcasecmp ("LogSendErrors", child->key) == 0)
506547
cf_util_get_boolean (child, &cb->log_send_errors);
507548
else if (strcasecmp ("Prefix", child->key) == 0)

0 commit comments

Comments
 (0)