#include <amqp.h>
#include <amqp_framing.h>
+#ifdef HAVE_AMQP_TCP_SOCKET_H
+# include <amqp_tcp_socket.h>
+#endif
+#ifdef HAVE_AMQP_SOCKET_H
+# include <amqp_socket.h>
+#endif
+#ifdef HAVE_AMQP_TCP_SOCKET
+#if defined HAVE_DECL_AMQP_SOCKET_CLOSE && !HAVE_DECL_AMQP_SOCKET_CLOSE
+/* rabbitmq-c does not currently ship amqp_socket.h
+ * and, thus, does not define this function. */
+int amqp_socket_close(amqp_socket_t *);
+#endif
+#endif
+
/* Defines for the delivery mode. I have no idea why they're not defined by the
* library.. */
#define CAMQP_DM_VOLATILE 1
char *prefix;
char *postfix;
char escape_char;
+ unsigned int graphite_flags;
/* subscribe only */
char *exchange_type;
switch (r.reply_type)
{
case AMQP_RESPONSE_NORMAL:
- sstrncpy (buffer, "Success", sizeof (buffer));
+ sstrncpy (buffer, "Success", buffer_size);
break;
case AMQP_RESPONSE_NONE:
- sstrncpy (buffer, "Missing RPC reply type", sizeof (buffer));
+ sstrncpy (buffer, "Missing RPC reply type", buffer_size);
break;
case AMQP_RESPONSE_LIBRARY_EXCEPTION:
return (sstrerror (r.library_error, buffer, buffer_size));
#endif
else
- sstrncpy (buffer, "End of stream", sizeof (buffer));
+ sstrncpy (buffer, "End of stream", buffer_size);
break;
case AMQP_RESPONSE_SERVER_EXCEPTION:
/* type = */ amqp_cstring_bytes (conf->exchange_type),
/* passive = */ 0,
/* durable = */ 0,
+#if defined(AMQP_VERSION) && AMQP_VERSION >= 0x00060000
+ /* auto delete = */ 0,
+ /* internal = */ 0,
+#endif
/* arguments = */ argument_table);
if ((ed_ret == NULL) && camqp_is_error (conf))
{
static int camqp_connect (camqp_config_t *conf) /* {{{ */
{
amqp_rpc_reply_t reply;
- int sockfd;
int status;
+#ifdef HAVE_AMQP_TCP_SOCKET
+ amqp_socket_t *socket;
+#else
+ int sockfd;
+#endif
if (conf->connection != NULL)
return (0);
return (ENOMEM);
}
+#ifdef HAVE_AMQP_TCP_SOCKET
+# define CLOSE_SOCKET() /* amqp_destroy_connection() closes the socket for us */
+ /* TODO: add support for SSL using amqp_ssl_socket_new
+ * and related functions */
+ socket = amqp_tcp_socket_new (conf->connection);
+ if (! socket)
+ {
+ ERROR ("amqp plugin: amqp_tcp_socket_new failed.");
+ amqp_destroy_connection (conf->connection);
+ conf->connection = NULL;
+ return (ENOMEM);
+ }
+
+ status = amqp_socket_open (socket, CONF(conf, host), conf->port);
+ if (status < 0)
+ {
+ char errbuf[1024];
+ status *= -1;
+ ERROR ("amqp plugin: amqp_socket_open failed: %s",
+ sstrerror (status, errbuf, sizeof (errbuf)));
+ amqp_destroy_connection (conf->connection);
+ conf->connection = NULL;
+ return (status);
+ }
+#else /* HAVE_AMQP_TCP_SOCKET */
+# define CLOSE_SOCKET() close(sockfd)
+ /* this interface is deprecated as of rabbitmq-c 0.4 */
sockfd = amqp_open_socket (CONF(conf, host), conf->port);
if (sockfd < 0)
{
return (status);
}
amqp_set_sockfd (conf->connection, sockfd);
+#endif
reply = amqp_login (conf->connection, CONF(conf, vhost),
/* channel max = */ 0,
ERROR ("amqp plugin: amqp_login (vhost = %s, user = %s) failed.",
CONF(conf, vhost), CONF(conf, user));
amqp_destroy_connection (conf->connection);
- close (sockfd);
+ CLOSE_SOCKET ();
conf->connection = NULL;
return (1);
}
ERROR ("amqp plugin: amqp_channel_open failed.");
amqp_connection_close (conf->connection, AMQP_REPLY_SUCCESS);
amqp_destroy_connection (conf->connection);
- close(sockfd);
+ CLOSE_SOCKET ();
conf->connection = NULL;
return (1);
}
camqp_config_t *conf = user_data;
int status;
+ cdtime_t interval = plugin_get_interval ();
+
while (subscriber_threads_running)
{
amqp_frame_t frame;
struct timespec ts_interval;
ERROR ("amqp plugin: camqp_connect failed. "
"Will sleep for %.3f seconds.",
- CDTIME_T_TO_DOUBLE (interval_g));
- CDTIME_T_TO_TIMESPEC (interval_g, &ts_interval);
+ CDTIME_T_TO_DOUBLE (interval));
+ CDTIME_T_TO_TIMESPEC (interval, &ts_interval);
nanosleep (&ts_interval, /* remaining = */ NULL);
continue;
}
struct timespec ts_interval;
ERROR ("amqp plugin: amqp_simple_wait_frame failed. "
"Will sleep for %.3f seconds.",
- CDTIME_T_TO_DOUBLE (interval_g));
+ CDTIME_T_TO_DOUBLE (interval));
camqp_close_connection (conf);
- CDTIME_T_TO_TIMESPEC (interval_g, &ts_interval);
+ CDTIME_T_TO_TIMESPEC (interval, &ts_interval);
nanosleep (&ts_interval, /* remaining = */ NULL);
continue;
}
continue;
}
- status = camqp_read_header (conf);
+ camqp_read_header (conf);
amqp_maybe_release_buffers (conf->connection);
} /* while (subscriber_threads_running) */
camqp_config_free (conf);
pthread_exit (NULL);
+ return (NULL);
} /* }}} void *camqp_subscribe_thread */
static int camqp_subscribe_init (camqp_config_t *conf) /* {{{ */
tmp = subscriber_threads + subscriber_threads_num;
memset (tmp, 0, sizeof (*tmp));
- status = pthread_create (tmp, /* attr = */ NULL,
+ status = plugin_thread_create (tmp, /* attr = */ NULL,
camqp_subscribe_thread, conf);
if (status != 0)
{
else if (conf->format == CAMQP_FORMAT_GRAPHITE)
{
status = format_graphite (buffer, sizeof (buffer), ds, vl,
- conf->prefix, conf->postfix, conf->escape_char);
+ conf->prefix, conf->postfix, conf->escape_char,
+ conf->graphite_flags);
if (status != 0)
{
ERROR ("amqp plugin: format_graphite failed with status %i.",
/* publish only */
conf->delivery_mode = CAMQP_DM_VOLATILE;
conf->store_rates = 0;
+ conf->graphite_flags = 0;
/* publish & graphite only */
conf->prefix = NULL;
conf->postfix = NULL;
conf->delivery_mode = CAMQP_DM_VOLATILE;
}
else if ((strcasecmp ("StoreRates", child->key) == 0) && publish)
+ {
status = cf_util_get_boolean (child, &conf->store_rates);
+ (void) cf_util_get_flag (child, &conf->graphite_flags,
+ GRAPHITE_STORE_RATES);
+ }
else if ((strcasecmp ("Format", child->key) == 0) && publish)
status = camqp_config_set_format (child, conf);
+ else if ((strcasecmp ("GraphiteSeparateInstances", child->key) == 0) && publish)
+ status = cf_util_get_flag (child, &conf->graphite_flags,
+ GRAPHITE_SEPARATE_INSTANCES);
+ else if ((strcasecmp ("GraphiteAlwaysAppendDS", child->key) == 0) && publish)
+ status = cf_util_get_flag (child, &conf->graphite_flags,
+ GRAPHITE_ALWAYS_APPEND_DS);
else if ((strcasecmp ("GraphitePrefix", child->key) == 0) && publish)
status = cf_util_get_string (child, &conf->prefix);
else if ((strcasecmp ("GraphitePostfix", child->key) == 0) && publish)