From e7ca9113bc94926c3f132b6388865f86df858c89 Mon Sep 17 00:00:00 2001 From: nicolas Date: Tue, 11 Aug 2015 17:50:36 +0200 Subject: [PATCH 1/3] Add filtering options to select plugin at startup --- agent.go | 36 ++++- agent_test.go | 44 +++++- cmd/telegraf/telegraf.go | 3 +- testdata/telegraf-agent.toml | 269 +++++++++++++++++++++++++++++++++++ 4 files changed, 343 insertions(+), 9 deletions(-) create mode 100644 testdata/telegraf-agent.toml diff --git a/agent.go b/agent.go index 1d704323c..2c9b778b1 100644 --- a/agent.go +++ b/agent.go @@ -99,8 +99,14 @@ func (a *Agent) Connect() error { } // LoadPlugins loads the agent's plugins -func (a *Agent) LoadPlugins() ([]string, error) { +func (a *Agent) LoadPlugins(pluginsFilter string) ([]string, error) { var names []string + var filters []string + + pluginsFilter = strings.TrimSpace(pluginsFilter) + if pluginsFilter != "" { + filters = strings.Split(":"+pluginsFilter+":", ":") + } for _, name := range a.Config.PluginsDeclared() { creator, ok := plugins.Plugins[name] @@ -108,15 +114,31 @@ func (a *Agent) LoadPlugins() ([]string, error) { return nil, fmt.Errorf("Undefined but requested plugin: %s", name) } - plugin := creator() - config, err := a.Config.ApplyPlugin(name, plugin) - if err != nil { - return nil, err + isPluginEnabled := false + if len(filters)>0 { + for _, runeValue := range filters { + if runeValue != "" && strings.ToLower(runeValue) == strings.ToLower(name) { + fmt.Printf("plugin [%s] is enabled (filter options)\n", name) + isPluginEnabled = true + break + } + } + } else { + // if no filter, we ALWAYS accept the plugin + isPluginEnabled = true } - a.plugins = append(a.plugins, &runningPlugin{name, plugin, config}) - names = append(names, name) + if isPluginEnabled { + plugin := creator() + config, err := a.Config.ApplyPlugin(name, plugin) + if err != nil { + return nil, err + } + + a.plugins = append(a.plugins, &runningPlugin{name, plugin, config}) + names = append(names, name) + } } sort.Strings(names) diff --git a/agent_test.go b/agent_test.go index 8811fa810..21c03552e 100644 --- a/agent_test.go +++ b/agent_test.go @@ -1,5 +1,47 @@ package telegraf +import ( + "testing" + "github.com/stretchr/testify/assert" + +// needing to load the plugins + _ "github.com/influxdb/telegraf/plugins/all" +) + +func TestAgent_LoadPlugin(t *testing.T) { + + // load a dedicated configuration file + config, _ := LoadConfig("./testdata/telegraf-agent.toml") + a, _ := NewAgent(config) + + pluginsEnabled, _ := a.LoadPlugins("mysql") + assert.Equal(t, 1, len(pluginsEnabled)) + + pluginsEnabled, _ = a.LoadPlugins("foo") + assert.Equal(t, 0, len(pluginsEnabled)) + + pluginsEnabled, _ = a.LoadPlugins("mysql:foo") + assert.Equal(t, 1, len(pluginsEnabled)) + + pluginsEnabled, _ = a.LoadPlugins("mysql:redis") + assert.Equal(t, 2, len(pluginsEnabled)) + + pluginsEnabled, _ = a.LoadPlugins(":mysql:foo:redis:bar") + assert.Equal(t, 2, len(pluginsEnabled)) + + pluginsEnabled, _ = a.LoadPlugins("") + assert.Equal(t, 24, len(pluginsEnabled)) + + pluginsEnabled, _ = a.LoadPlugins(" ") + assert.Equal(t, 24, len(pluginsEnabled)) + + pluginsEnabled, _ = a.LoadPlugins(" ") + assert.Equal(t, 24, len(pluginsEnabled)) + + pluginsEnabled, _ = a.LoadPlugins("\n\t") + assert.Equal(t, 24, len(pluginsEnabled)) +} + /* func TestAgent_DrivesMetrics(t *testing.T) { var ( @@ -58,4 +100,4 @@ func TestAgent_AppliesTags(t *testing.T) { err := a.crank() require.NoError(t, err) } -*/ +*/ \ No newline at end of file diff --git a/cmd/telegraf/telegraf.go b/cmd/telegraf/telegraf.go index 365dd20d3..f611d04ca 100644 --- a/cmd/telegraf/telegraf.go +++ b/cmd/telegraf/telegraf.go @@ -18,6 +18,7 @@ var fConfig = flag.String("config", "", "configuration file to load") var fVersion = flag.Bool("version", false, "display the version") var fSampleConfig = flag.Bool("sample-config", false, "print out full sample configuration") var fPidfile = flag.String("pidfile", "", "file to write our pid to") +var fPLuginsFilter = flag.String("filter", "", "filter the plugins to enable, separator is :") // Telegraf version var Version = "unreleased" @@ -61,7 +62,7 @@ func main() { ag.Debug = true } - plugins, err := ag.LoadPlugins() + plugins, err := ag.LoadPlugins(*fPLuginsFilter) if err != nil { log.Fatal(err) } diff --git a/testdata/telegraf-agent.toml b/testdata/telegraf-agent.toml new file mode 100644 index 000000000..b58995594 --- /dev/null +++ b/testdata/telegraf-agent.toml @@ -0,0 +1,269 @@ +# Telegraf configuration + +# If this file is missing an [agent] section, you must first generate a +# valid config with 'telegraf -sample-config > telegraf.toml' + +# Telegraf is entirely plugin driven. All metrics are gathered from the +# declared plugins. + +# Even if a plugin has no configuration, it must be declared in here +# to be active. Declaring a plugin means just specifying the name +# as a section with no variables. To deactivate a plugin, comment +# out the name and any variables. + +# Use 'telegraf -config telegraf.toml -test' to see what metrics a config +# file would generate. + +# One rule that plugins conform to is wherever a connection string +# can be passed, the values '' and 'localhost' are treated specially. +# They indicate to the plugin to use their own builtin configuration to +# connect to the local system. + +# NOTE: The configuration has a few required parameters. They are marked +# with 'required'. Be sure to edit those to make this configuration work. + +# Configuration for influxdb server to send metrics to +[influxdb] +# The full HTTP endpoint URL for your InfluxDB instance +url = "http://localhost:8086" # required. + +# The target database for metrics. This database must already exist +database = "telegraf" # required. + +# Connection timeout (for the connection with InfluxDB), formatted as a string. +# Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h". +# If not provided, will default to 0 (no timeout) +# timeout = "5s" + +# username = "telegraf" +# password = "metricsmetricsmetricsmetrics" + +# Set the user agent for the POSTs (can be useful for log differentiation) +# user_agent = "telegraf" +# tags = { "dc": "us-east-1" } + +# Tags can also be specified via a normal map, but only one form at a time: + +# [influxdb.tags] +# dc = "us-east-1" + +# Configuration for telegraf itself +# [agent] +# interval = "10s" +# debug = false +# hostname = "prod3241" + +# PLUGINS + +# Read metrics about cpu usage +[cpu] + # no configuration + +# Read metrics about disk usage by mount point +[disk] + # no configuration + +# Read metrics from one or many disque servers +[disque] + +# An array of URI to gather stats about. Specify an ip or hostname +# with optional port and password. ie disque://localhost, disque://10.10.3.33:18832, +# 10.0.0.1:10000, etc. +# +# If no servers are specified, then localhost is used as the host. +servers = ["localhost"] + +# Read metrics about docker containers +[docker] + # no configuration + +# Read stats from one or more Elasticsearch servers or clusters +[elasticsearch] + +# specify a list of one or more Elasticsearch servers +servers = ["http://localhost:9200"] + +# set local to false when you want to read the indices stats from all nodes +# within the cluster +local = true + +# Read flattened metrics from one or more commands that output JSON to stdout +[exec] + +# specify commands via an array of tables +[[exec.commands]] +# the command to run +command = "/usr/bin/mycollector --foo=bar" + +# name of the command (used as a prefix for measurements) +name = "mycollector" + +# Read metrics of haproxy, via socket or csv stats page +[haproxy] + +# An array of address to gather stats about. Specify an ip on hostname +# with optional port. ie localhost, 10.10.3.33:1936, etc. +# +# If no servers are specified, then default to 127.0.0.1:1936 +servers = ["http://myhaproxy.com:1936", "http://anotherhaproxy.com:1936"] +# Or you can also use local socket(not work yet) +# servers = ["socket:/run/haproxy/admin.sock"] + +# Read metrics about disk IO by device +[io] + # no configuration + +# read metrics from a Kafka topic +[kafka] + +# topic to consume +topic = "topic_with_metrics" + +# the name of the consumer group +consumerGroupName = "telegraf_metrics_consumers" + +# an array of Zookeeper connection strings +zookeeperPeers = ["localhost:2181"] + +# Batch size of points sent to InfluxDB +batchSize = 1000 + +# Read metrics from a LeoFS Server via SNMP +[leofs] + +# An array of URI to gather stats about LeoFS. +# Specify an ip or hostname with port. ie 127.0.0.1:4020 +# +# If no servers are specified, then 127.0.0.1 is used as the host and 4020 as the port. +servers = ["127.0.0.1:4021"] + +# Read metrics from local Lustre service on OST, MDS +[lustre2] + +# An array of /proc globs to search for Lustre stats +# If not specified, the default will work on Lustre 2.5.x +# +# ost_procfiles = ["/proc/fs/lustre/obdfilter/*/stats", "/proc/fs/lustre/osd-ldiskfs/*/stats"] +# mds_procfiles = ["/proc/fs/lustre/mdt/*/md_stats"] + +# Read metrics about memory usage +[mem] + # no configuration + +# Read metrics from one or many memcached servers +[memcached] + +# An array of address to gather stats about. Specify an ip on hostname +# with optional port. ie localhost, 10.0.0.1:11211, etc. +# +# If no servers are specified, then localhost is used as the host. +servers = ["localhost"] + +# Read metrics from one or many MongoDB servers +[mongodb] + +# An array of URI to gather stats about. Specify an ip or hostname +# with optional port add password. ie mongodb://user:auth_key@10.10.3.30:27017, +# mongodb://10.10.3.33:18832, 10.0.0.1:10000, etc. +# +# If no servers are specified, then 127.0.0.1 is used as the host and 27107 as the port. +servers = ["127.0.0.1:27017"] + +# Read metrics from one or many mysql servers +[mysql] + +# specify servers via a url matching: +# [username[:password]@][protocol[(address)]]/[?tls=[true|false|skip-verify]] +# e.g. root:root@http://10.0.0.18/?tls=false +# +# If no servers are specified, then localhost is used as the host. +servers = ["localhost"] + +# Read metrics about network interface usage +[net] + +# By default, telegraf gathers stats from any up interface (excluding loopback) +# Setting interfaces will tell it to gather these explicit interfaces, +# regardless of status. +# +# interfaces = ["eth0", ... ] + +# Read Nginx's basic status information (ngx_http_stub_status_module) +[nginx] + +# An array of Nginx stub_status URI to gather stats. +urls = ["localhost/status"] + +# Read metrics from one or many postgresql servers +[postgresql] + +# specify servers via an array of tables +[[postgresql.servers]] + +# specify address via a url matching: +# postgres://[pqgotest[:password]]@localhost?sslmode=[disable|verify-ca|verify-full] +# or a simple string: +# host=localhost user=pqotest password=... sslmode=... +# +# All connection parameters are optional. By default, the host is localhost +# and the user is the currently running user. For localhost, we default +# to sslmode=disable as well. +# + +address = "sslmode=disable" + +# A list of databases to pull metrics about. If not specified, metrics for all +# databases are gathered. + +# databases = ["app_production", "blah_testing"] + +# [[postgresql.servers]] +# address = "influx@remoteserver" + +# Read metrics from one or many prometheus clients +[prometheus] + +# An array of urls to scrape metrics from. +urls = ["http://localhost:9100/metrics"] + +# Read metrics from one or many RabbitMQ servers via the management API +[rabbitmq] + +# Specify servers via an array of tables +[[rabbitmq.servers]] +# url = "http://localhost:15672" +# username = "guest" +# password = "guest" + +# A list of nodes to pull metrics about. If not specified, metrics for +# all nodes are gathered. +# nodes = ["rabbit@node1", "rabbit@node2"] + +# Read metrics from one or many redis servers +[redis] + +# An array of URI to gather stats about. Specify an ip or hostname +# with optional port add password. ie redis://localhost, redis://10.10.3.33:18832, +# 10.0.0.1:10000, etc. +# +# If no servers are specified, then localhost is used as the host. +servers = ["localhost"] + +# Read metrics from one or many RethinkDB servers +[rethinkdb] + +# An array of URI to gather stats about. Specify an ip or hostname +# with optional port add password. ie rethinkdb://user:auth_key@10.10.3.30:28105, +# rethinkdb://10.10.3.33:18832, 10.0.0.1:10000, etc. +# +# If no servers are specified, then 127.0.0.1 is used as the host and 28015 as the port. +servers = ["127.0.0.1:28015"] + +# Read metrics about swap memory usage +[swap] + # no configuration + +# Read metrics about system load +[system] + # no configuration + From 5691253acd2abebf2f97eaef44488e5802f6d5cd Mon Sep 17 00:00:00 2001 From: Nicolas Date: Tue, 11 Aug 2015 18:18:52 +0200 Subject: [PATCH 2/3] Update Readme with new option filter and add usage chapter with --help --- README.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/README.md b/README.md index 217313e02..0ab29f284 100644 --- a/README.md +++ b/README.md @@ -36,8 +36,21 @@ brew install telegraf * Edit the configuration to match your needs * Run `telegraf -config telegraf.toml -test` to output one full measurement sample to STDOUT * Run `telegraf -config telegraf.toml` to gather and send metrics to InfluxDB +* Run `telegraf -config telegraf.toml -filter system:swap` to enable only two plugins described into config file +### Telegraf Usage +```telegraf --help``` + +* -config="": configuration file to load +* -debug=false: show metrics as they're generated to stdout +* -filter="": filter the plugins to enable, separator is : +* -httptest.serve="": if non-empty, httptest.NewServer serves on this address and blocks +* -pidfile="": file to write our pid to +* -sample-config=false: print out full sample configuration +* -test=false: gather metrics, print them out, and exit +* -version=false: display the version + ## Telegraf Options Telegraf has a few options you can configure under the `agent` section of the From abdef7c3267bbfc44cf1aeb5c774d2e31d6929c9 Mon Sep 17 00:00:00 2001 From: nicolas Date: Tue, 11 Aug 2015 19:01:37 +0200 Subject: [PATCH 3/3] Go FMT missing... --- agent.go | 3 +-- agent_test.go | 6 +++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/agent.go b/agent.go index 2c9b778b1..ce8bb9b2b 100644 --- a/agent.go +++ b/agent.go @@ -114,9 +114,8 @@ func (a *Agent) LoadPlugins(pluginsFilter string) ([]string, error) { return nil, fmt.Errorf("Undefined but requested plugin: %s", name) } - isPluginEnabled := false - if len(filters)>0 { + if len(filters) > 0 { for _, runeValue := range filters { if runeValue != "" && strings.ToLower(runeValue) == strings.ToLower(name) { fmt.Printf("plugin [%s] is enabled (filter options)\n", name) diff --git a/agent_test.go b/agent_test.go index 21c03552e..e65cb7ae9 100644 --- a/agent_test.go +++ b/agent_test.go @@ -1,10 +1,10 @@ package telegraf import ( - "testing" "github.com/stretchr/testify/assert" + "testing" -// needing to load the plugins + // needing to load the plugins _ "github.com/influxdb/telegraf/plugins/all" ) @@ -100,4 +100,4 @@ func TestAgent_AppliesTags(t *testing.T) { err := a.crank() require.NoError(t, err) } -*/ \ No newline at end of file +*/