Allow configuration of amqp exchange type, durability, and arguments
This commit is contained in:
parent
fcea745e99
commit
e3f1d28908
|
@ -17,23 +17,36 @@ The following defaults are known to work with RabbitMQ:
|
||||||
[[inputs.amqp_consumer]]
|
[[inputs.amqp_consumer]]
|
||||||
## AMQP url
|
## AMQP url
|
||||||
url = "amqp://localhost:5672/influxdb"
|
url = "amqp://localhost:5672/influxdb"
|
||||||
## AMQP exchange
|
|
||||||
|
## Exchange to declare and consume from.
|
||||||
exchange = "telegraf"
|
exchange = "telegraf"
|
||||||
## Exchange passive mode
|
|
||||||
exchange_passive = false
|
## Exchange type; common types are "direct", "fanout", "topic", "header", "x-consistent-hash".
|
||||||
|
# exchange_type = "topic"
|
||||||
|
|
||||||
|
## If true, exchange will be passively declared.
|
||||||
|
# exchange_passive = false
|
||||||
|
|
||||||
|
## Exchange durability can be either "transient" or "durable".
|
||||||
|
# exchange_durability = "durable"
|
||||||
|
|
||||||
|
## Additional exchange arguments.
|
||||||
|
# exchange_args = { }
|
||||||
|
# exchange_args = {"hash_propery" = "timestamp"}
|
||||||
|
|
||||||
## AMQP queue name
|
## AMQP queue name
|
||||||
queue = "telegraf"
|
queue = "telegraf"
|
||||||
## Binding Key
|
## Binding Key
|
||||||
binding_key = "#"
|
binding_key = "#"
|
||||||
|
|
||||||
## Controls how many messages the server will try to keep on the network
|
## Maximum number of messages server should give to the worker.
|
||||||
## for consumers before receiving delivery acks.
|
prefetch_count = 50
|
||||||
#prefetch_count = 50
|
|
||||||
|
|
||||||
## Auth method. PLAIN and EXTERNAL are supported.
|
## Auth method. PLAIN and EXTERNAL are supported
|
||||||
## Using EXTERNAL requires enabling the rabbitmq_auth_mechanism_ssl plugin as
|
## Using EXTERNAL requires enabling the rabbitmq_auth_mechanism_ssl plugin as
|
||||||
## described here: https://www.rabbitmq.com/plugins.html
|
## described here: https://www.rabbitmq.com/plugins.html
|
||||||
# auth_method = "PLAIN"
|
# auth_method = "PLAIN"
|
||||||
|
|
||||||
## Optional TLS Config
|
## Optional TLS Config
|
||||||
# tls_ca = "/etc/telegraf/ca.pem"
|
# tls_ca = "/etc/telegraf/ca.pem"
|
||||||
# tls_cert = "/etc/telegraf/cert.pem"
|
# tls_cert = "/etc/telegraf/cert.pem"
|
||||||
|
|
|
@ -18,10 +18,13 @@ import (
|
||||||
// AMQPConsumer is the top level struct for this plugin
|
// AMQPConsumer is the top level struct for this plugin
|
||||||
type AMQPConsumer struct {
|
type AMQPConsumer struct {
|
||||||
URL string
|
URL string
|
||||||
// AMQP exchange
|
|
||||||
Exchange string
|
Exchange string `toml:"exchange"`
|
||||||
// Exchange passive mode
|
ExchangeType string `toml:"exchange_type"`
|
||||||
ExchangePassive bool
|
ExchangeDurability string `toml:"exchange_durability"`
|
||||||
|
ExchangePassive bool `toml:"exchange_passive"`
|
||||||
|
ExchangeArguments map[string]string `toml:"exchange_arguments"`
|
||||||
|
|
||||||
// Queue Name
|
// Queue Name
|
||||||
Queue string
|
Queue string
|
||||||
// Binding Key
|
// Binding Key
|
||||||
|
@ -50,7 +53,11 @@ func (a *externalAuth) Response() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
DefaultAuthMethod = "PLAIN"
|
DefaultAuthMethod = "PLAIN"
|
||||||
|
|
||||||
|
DefaultExchangeType = "topic"
|
||||||
|
DefaultExchangeDurability = "durable"
|
||||||
|
|
||||||
DefaultPrefetchCount = 50
|
DefaultPrefetchCount = 50
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -58,10 +65,23 @@ func (a *AMQPConsumer) SampleConfig() string {
|
||||||
return `
|
return `
|
||||||
## AMQP url
|
## AMQP url
|
||||||
url = "amqp://localhost:5672/influxdb"
|
url = "amqp://localhost:5672/influxdb"
|
||||||
## AMQP exchange
|
|
||||||
|
## Exchange to declare and consume from.
|
||||||
exchange = "telegraf"
|
exchange = "telegraf"
|
||||||
## Exchange passive mode
|
|
||||||
exchange_passive = false
|
## Exchange type; common types are "direct", "fanout", "topic", "header", "x-consistent-hash".
|
||||||
|
# exchange_type = "topic"
|
||||||
|
|
||||||
|
## If true, exchange will be passively declared.
|
||||||
|
# exchange_passive = false
|
||||||
|
|
||||||
|
## Exchange durability can be either "transient" or "durable".
|
||||||
|
# exchange_durability = "durable"
|
||||||
|
|
||||||
|
## Additional exchange arguments.
|
||||||
|
# exchange_args = { }
|
||||||
|
# exchange_args = {"hash_propery" = "timestamp"}
|
||||||
|
|
||||||
## AMQP queue name
|
## AMQP queue name
|
||||||
queue = "telegraf"
|
queue = "telegraf"
|
||||||
## Binding Key
|
## Binding Key
|
||||||
|
@ -178,29 +198,28 @@ func (a *AMQPConsumer) connect(amqpConf *amqp.Config) (<-chan amqp.Delivery, err
|
||||||
return nil, fmt.Errorf("Failed to open a channel: %s", err)
|
return nil, fmt.Errorf("Failed to open a channel: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if a.ExchangePassive == true {
|
var exchangeDurable = true
|
||||||
err = ch.ExchangeDeclarePassive(
|
switch a.ExchangeDurability {
|
||||||
a.Exchange, // name
|
case "transient":
|
||||||
"topic", // type
|
exchangeDurable = false
|
||||||
true, // durable
|
default:
|
||||||
false, // auto-deleted
|
exchangeDurable = true
|
||||||
false, // internal
|
|
||||||
false, // no-wait
|
|
||||||
nil, // arguments
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
err = ch.ExchangeDeclare(
|
|
||||||
a.Exchange, // name
|
|
||||||
"topic", // type
|
|
||||||
true, // durable
|
|
||||||
false, // auto-deleted
|
|
||||||
false, // internal
|
|
||||||
false, // no-wait
|
|
||||||
nil, // arguments
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
exchangeArgs := make(amqp.Table, len(a.ExchangeArguments))
|
||||||
|
for k, v := range a.ExchangeArguments {
|
||||||
|
exchangeArgs[k] = v
|
||||||
|
}
|
||||||
|
|
||||||
|
err = declareExchange(
|
||||||
|
ch,
|
||||||
|
a.Exchange,
|
||||||
|
a.ExchangeType,
|
||||||
|
a.ExchangePassive,
|
||||||
|
exchangeDurable,
|
||||||
|
exchangeArgs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("Failed to declare an exchange: %s", err)
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
q, err := ch.QueueDeclare(
|
q, err := ch.QueueDeclare(
|
||||||
|
@ -252,6 +271,42 @@ func (a *AMQPConsumer) connect(amqpConf *amqp.Config) (<-chan amqp.Delivery, err
|
||||||
return msgs, err
|
return msgs, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func declareExchange(
|
||||||
|
channel *amqp.Channel,
|
||||||
|
exchangeName string,
|
||||||
|
exchangeType string,
|
||||||
|
exchangePassive bool,
|
||||||
|
exchangeDurable bool,
|
||||||
|
exchangeArguments amqp.Table,
|
||||||
|
) error {
|
||||||
|
var err error
|
||||||
|
if exchangePassive {
|
||||||
|
err = channel.ExchangeDeclarePassive(
|
||||||
|
exchangeName,
|
||||||
|
exchangeType,
|
||||||
|
exchangeDurable,
|
||||||
|
false, // delete when unused
|
||||||
|
false, // internal
|
||||||
|
false, // no-wait
|
||||||
|
exchangeArguments,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
err = channel.ExchangeDeclare(
|
||||||
|
exchangeName,
|
||||||
|
exchangeType,
|
||||||
|
exchangeDurable,
|
||||||
|
false, // delete when unused
|
||||||
|
false, // internal
|
||||||
|
false, // no-wait
|
||||||
|
exchangeArguments,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("error declaring exchange: %v", err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// Read messages from queue and add them to the Accumulator
|
// Read messages from queue and add them to the Accumulator
|
||||||
func (a *AMQPConsumer) process(msgs <-chan amqp.Delivery, acc telegraf.Accumulator) {
|
func (a *AMQPConsumer) process(msgs <-chan amqp.Delivery, acc telegraf.Accumulator) {
|
||||||
defer a.wg.Done()
|
defer a.wg.Done()
|
||||||
|
@ -283,8 +338,10 @@ func (a *AMQPConsumer) Stop() {
|
||||||
func init() {
|
func init() {
|
||||||
inputs.Add("amqp_consumer", func() telegraf.Input {
|
inputs.Add("amqp_consumer", func() telegraf.Input {
|
||||||
return &AMQPConsumer{
|
return &AMQPConsumer{
|
||||||
AuthMethod: DefaultAuthMethod,
|
AuthMethod: DefaultAuthMethod,
|
||||||
PrefetchCount: DefaultPrefetchCount,
|
ExchangeType: DefaultExchangeType,
|
||||||
|
ExchangeDurability: DefaultExchangeDurability,
|
||||||
|
PrefetchCount: DefaultPrefetchCount,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,13 +21,28 @@ For an introduction to AMQP see:
|
||||||
|
|
||||||
### Configuration:
|
### Configuration:
|
||||||
|
|
||||||
```
|
```toml
|
||||||
# Configuration for the AMQP server to send metrics to
|
# Configuration for the AMQP server to send metrics to
|
||||||
[[outputs.amqp]]
|
[[outputs.amqp]]
|
||||||
## AMQP url
|
## AMQP url
|
||||||
url = "amqp://localhost:5672/influxdb"
|
url = "amqp://localhost:5672/influxdb"
|
||||||
## AMQP exchange
|
|
||||||
|
## Exchange to declare and publish to.
|
||||||
exchange = "telegraf"
|
exchange = "telegraf"
|
||||||
|
|
||||||
|
## Exchange type; common types are "direct", "fanout", "topic", "header", "x-consistent-hash".
|
||||||
|
# exchange_type = "topic"
|
||||||
|
|
||||||
|
## If true, exchange will be passively declared.
|
||||||
|
# exchange_passive = false
|
||||||
|
|
||||||
|
## Exchange durability can be either "transient" or "durable".
|
||||||
|
# exchange_durability = "durable"
|
||||||
|
|
||||||
|
## Additional exchange arguments.
|
||||||
|
# exchange_args = { }
|
||||||
|
# exchange_args = {"hash_propery" = "timestamp"}
|
||||||
|
|
||||||
## Auth method. PLAIN and EXTERNAL are supported
|
## Auth method. PLAIN and EXTERNAL are supported
|
||||||
## Using EXTERNAL requires enabling the rabbitmq_auth_mechanism_ssl plugin as
|
## Using EXTERNAL requires enabling the rabbitmq_auth_mechanism_ssl plugin as
|
||||||
## described here: https://www.rabbitmq.com/plugins.html
|
## described here: https://www.rabbitmq.com/plugins.html
|
||||||
|
@ -40,7 +55,7 @@ For an introduction to AMQP see:
|
||||||
routing_tag = "host"
|
routing_tag = "host"
|
||||||
## Delivery Mode controls if a published message is persistent
|
## Delivery Mode controls if a published message is persistent
|
||||||
## Valid options are "transient" and "persistent". default: "transient"
|
## Valid options are "transient" and "persistent". default: "transient"
|
||||||
# delivery_mode = "transient"
|
delivery_mode = "transient"
|
||||||
|
|
||||||
## InfluxDB retention policy
|
## InfluxDB retention policy
|
||||||
# retention_policy = "default"
|
# retention_policy = "default"
|
||||||
|
|
|
@ -26,8 +26,13 @@ type client struct {
|
||||||
type AMQP struct {
|
type AMQP struct {
|
||||||
// AMQP brokers to send metrics to
|
// AMQP brokers to send metrics to
|
||||||
URL string
|
URL string
|
||||||
// AMQP exchange
|
|
||||||
Exchange string
|
Exchange string `toml:"exchange"`
|
||||||
|
ExchangeType string `toml:"exchange_type"`
|
||||||
|
ExchangeDurability string `toml:"exchange_durability"`
|
||||||
|
ExchangePassive bool `toml:"exchange_passive"`
|
||||||
|
ExchangeArguments map[string]string `toml:"exchange_arguments"`
|
||||||
|
|
||||||
// AMQP Auth method
|
// AMQP Auth method
|
||||||
AuthMethod string
|
AuthMethod string
|
||||||
// Routing Key (static)
|
// Routing Key (static)
|
||||||
|
@ -65,7 +70,11 @@ func (a *externalAuth) Response() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
DefaultAuthMethod = "PLAIN"
|
DefaultAuthMethod = "PLAIN"
|
||||||
|
|
||||||
|
DefaultExchangeType = "topic"
|
||||||
|
DefaultExchangeDurability = "durable"
|
||||||
|
|
||||||
DefaultRetentionPolicy = "default"
|
DefaultRetentionPolicy = "default"
|
||||||
DefaultDatabase = "telegraf"
|
DefaultDatabase = "telegraf"
|
||||||
)
|
)
|
||||||
|
@ -73,8 +82,23 @@ const (
|
||||||
var sampleConfig = `
|
var sampleConfig = `
|
||||||
## AMQP url
|
## AMQP url
|
||||||
url = "amqp://localhost:5672/influxdb"
|
url = "amqp://localhost:5672/influxdb"
|
||||||
## AMQP exchange
|
|
||||||
|
## Exchange to declare and publish to.
|
||||||
exchange = "telegraf"
|
exchange = "telegraf"
|
||||||
|
|
||||||
|
## Exchange type; common types are "direct", "fanout", "topic", "header", "x-consistent-hash".
|
||||||
|
# exchange_type = "topic"
|
||||||
|
|
||||||
|
## If true, exchange will be passively declared.
|
||||||
|
# exchange_passive = false
|
||||||
|
|
||||||
|
## Exchange durability can be either "transient" or "durable".
|
||||||
|
# exchange_durability = "durable"
|
||||||
|
|
||||||
|
## Additional exchange arguments.
|
||||||
|
# exchange_args = { }
|
||||||
|
# exchange_args = {"hash_propery" = "timestamp"}
|
||||||
|
|
||||||
## Auth method. PLAIN and EXTERNAL are supported
|
## Auth method. PLAIN and EXTERNAL are supported
|
||||||
## Using EXTERNAL requires enabling the rabbitmq_auth_mechanism_ssl plugin as
|
## Using EXTERNAL requires enabling the rabbitmq_auth_mechanism_ssl plugin as
|
||||||
## described here: https://www.rabbitmq.com/plugins.html
|
## described here: https://www.rabbitmq.com/plugins.html
|
||||||
|
@ -166,17 +190,28 @@ func (q *AMQP) Connect() error {
|
||||||
return fmt.Errorf("Failed to open a channel: %s", err)
|
return fmt.Errorf("Failed to open a channel: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = channel.ExchangeDeclare(
|
var exchangeDurable = true
|
||||||
q.Exchange, // name
|
switch q.ExchangeDurability {
|
||||||
"topic", // type
|
case "transient":
|
||||||
true, // durable
|
exchangeDurable = false
|
||||||
false, // delete when unused
|
default:
|
||||||
false, // internal
|
exchangeDurable = true
|
||||||
false, // no-wait
|
}
|
||||||
nil, // arguments
|
|
||||||
)
|
exchangeArgs := make(amqp.Table, len(q.ExchangeArguments))
|
||||||
|
for k, v := range q.ExchangeArguments {
|
||||||
|
exchangeArgs[k] = v
|
||||||
|
}
|
||||||
|
|
||||||
|
err = declareExchange(
|
||||||
|
channel,
|
||||||
|
q.Exchange,
|
||||||
|
q.ExchangeType,
|
||||||
|
q.ExchangePassive,
|
||||||
|
exchangeDurable,
|
||||||
|
exchangeArgs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Failed to declare an exchange: %s", err)
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
q.setClient(&client{
|
q.setClient(&client{
|
||||||
|
@ -203,6 +238,42 @@ func (q *AMQP) Connect() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func declareExchange(
|
||||||
|
channel *amqp.Channel,
|
||||||
|
exchangeName string,
|
||||||
|
exchangeType string,
|
||||||
|
exchangePassive bool,
|
||||||
|
exchangeDurable bool,
|
||||||
|
exchangeArguments amqp.Table,
|
||||||
|
) error {
|
||||||
|
var err error
|
||||||
|
if exchangePassive {
|
||||||
|
err = channel.ExchangeDeclarePassive(
|
||||||
|
exchangeName,
|
||||||
|
exchangeType,
|
||||||
|
exchangeDurable,
|
||||||
|
false, // delete when unused
|
||||||
|
false, // internal
|
||||||
|
false, // no-wait
|
||||||
|
exchangeArguments,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
err = channel.ExchangeDeclare(
|
||||||
|
exchangeName,
|
||||||
|
exchangeType,
|
||||||
|
exchangeDurable,
|
||||||
|
false, // delete when unused
|
||||||
|
false, // internal
|
||||||
|
false, // no-wait
|
||||||
|
exchangeArguments,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("error declaring exchange: %v", err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (q *AMQP) Close() error {
|
func (q *AMQP) Close() error {
|
||||||
c := q.getClient()
|
c := q.getClient()
|
||||||
if c == nil {
|
if c == nil {
|
||||||
|
@ -292,10 +363,12 @@ func (q *AMQP) setClient(c *client) {
|
||||||
func init() {
|
func init() {
|
||||||
outputs.Add("amqp", func() telegraf.Output {
|
outputs.Add("amqp", func() telegraf.Output {
|
||||||
return &AMQP{
|
return &AMQP{
|
||||||
AuthMethod: DefaultAuthMethod,
|
AuthMethod: DefaultAuthMethod,
|
||||||
Database: DefaultDatabase,
|
ExchangeType: DefaultExchangeType,
|
||||||
RetentionPolicy: DefaultRetentionPolicy,
|
ExchangeDurability: DefaultExchangeDurability,
|
||||||
Timeout: internal.Duration{Duration: time.Second * 5},
|
Database: DefaultDatabase,
|
||||||
|
RetentionPolicy: DefaultRetentionPolicy,
|
||||||
|
Timeout: internal.Duration{Duration: time.Second * 5},
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue