diff --git a/etc/telegraf.conf b/etc/telegraf.conf index b9e1f5a41..cea87da97 100644 --- a/etc/telegraf.conf +++ b/etc/telegraf.conf @@ -21,96 +21,96 @@ ## Environment variables can be used as tags, and throughout the config file # user = "$USER" -# Configuration for telegraf agent -[agent] - ## Default data collection interval for all inputs - interval = "10s" - ## Rounds collection interval to 'interval' - ## ie, if interval="10s" then always collect on :00, :10, :20, etc. - round_interval = true - - ## Telegraf will send metrics to outputs in batches of at most - ## metric_batch_size metrics. - ## This controls the size of writes that Telegraf sends to output plugins. - metric_batch_size = 1000 - - ## Maximum number of unwritten metrics per output. Increasing this value - ## allows for longer periods of output downtime without dropping metrics at the - ## cost of higher maximum memory usage. - metric_buffer_limit = 10000 - - ## Collection jitter is used to jitter the collection by a random amount. - ## Each plugin will sleep for a random time within jitter before collecting. - ## This can be used to avoid many plugins querying things like sysfs at the - ## same time, which can have a measurable effect on the system. - collection_jitter = "0s" - - ## Collection offset is used to shift the collection by the given amount. - ## This can be be used to avoid many plugins querying constraint devices - ## at the same time by manually scheduling them in time. - # collection_offset = "0s" - - ## Default flushing interval for all outputs. Maximum flush_interval will be - ## flush_interval + flush_jitter - flush_interval = "10s" - ## Jitter the flush interval by a random amount. This is primarily to avoid - ## large write spikes for users running a large number of telegraf instances. - ## ie, a jitter of 5s and interval 10s means flushes will happen every 10-15s - flush_jitter = "0s" - - ## Collected metrics are rounded to the precision specified. Precision is - ## specified as an interval with an integer + unit (e.g. 0s, 10ms, 2us, 4s). - ## Valid time units are "ns", "us" (or "µs"), "ms", "s". - ## - ## By default or when set to "0s", precision will be set to the same - ## timestamp order as the collection interval, with the maximum being 1s: - ## ie, when interval = "10s", precision will be "1s" - ## when interval = "250ms", precision will be "1ms" - ## - ## Precision will NOT be used for service inputs. It is up to each individual - ## service input to set the timestamp at the appropriate precision. - precision = "0s" - - ## Log at debug level. - # debug = false - ## Log only error level messages. - # quiet = false - - ## Log target controls the destination for logs and can be one of "file", - ## "stderr" or, on Windows, "eventlog". When set to "file", the output file - ## is determined by the "logfile" setting. - # logtarget = "file" - - ## Name of the file to be logged to when using the "file" logtarget. If set to - ## the empty string then logs are written to stderr. - # logfile = "" - - ## The logfile will be rotated after the time interval specified. When set - ## to 0 no time based rotation is performed. Logs are rotated only when - ## written to, if there is no log activity rotation may be delayed. - # logfile_rotation_interval = "0h" - - ## The logfile will be rotated when it becomes larger than the specified - ## size. When set to 0 no size based rotation is performed. - # logfile_rotation_max_size = "0MB" - - ## Maximum number of rotated archives to keep, any older logs are deleted. - ## If set to -1, no archives are removed. - # logfile_rotation_max_archives = 5 - - ## Pick a timezone to use when logging or type 'local' for local time. - ## Example: America/Chicago - # log_with_timezone = "" - - ## Override default hostname, if empty use os.Hostname() - hostname = "" - ## If set to true, do no set the "host" tag in the telegraf agent. - omit_hostname = false - - ## Method of translating SNMP objects. Can be "netsnmp" which - ## translates by calling external programs snmptranslate and snmptable, - ## or "gosmi" which translates using the built-in gosmi library. - # snmp_translator = "netsnmp" +# Configuration for telegraf agent +[agent] + ## Default data collection interval for all inputs + interval = "10s" + ## Rounds collection interval to 'interval' + ## ie, if interval="10s" then always collect on :00, :10, :20, etc. + round_interval = true + + ## Telegraf will send metrics to outputs in batches of at most + ## metric_batch_size metrics. + ## This controls the size of writes that Telegraf sends to output plugins. + metric_batch_size = 1000 + + ## Maximum number of unwritten metrics per output. Increasing this value + ## allows for longer periods of output downtime without dropping metrics at the + ## cost of higher maximum memory usage. + metric_buffer_limit = 10000 + + ## Collection jitter is used to jitter the collection by a random amount. + ## Each plugin will sleep for a random time within jitter before collecting. + ## This can be used to avoid many plugins querying things like sysfs at the + ## same time, which can have a measurable effect on the system. + collection_jitter = "0s" + + ## Collection offset is used to shift the collection by the given amount. + ## This can be be used to avoid many plugins querying constraint devices + ## at the same time by manually scheduling them in time. + # collection_offset = "0s" + + ## Default flushing interval for all outputs. Maximum flush_interval will be + ## flush_interval + flush_jitter + flush_interval = "10s" + ## Jitter the flush interval by a random amount. This is primarily to avoid + ## large write spikes for users running a large number of telegraf instances. + ## ie, a jitter of 5s and interval 10s means flushes will happen every 10-15s + flush_jitter = "0s" + + ## Collected metrics are rounded to the precision specified. Precision is + ## specified as an interval with an integer + unit (e.g. 0s, 10ms, 2us, 4s). + ## Valid time units are "ns", "us" (or "µs"), "ms", "s". + ## + ## By default or when set to "0s", precision will be set to the same + ## timestamp order as the collection interval, with the maximum being 1s: + ## ie, when interval = "10s", precision will be "1s" + ## when interval = "250ms", precision will be "1ms" + ## + ## Precision will NOT be used for service inputs. It is up to each individual + ## service input to set the timestamp at the appropriate precision. + precision = "0s" + + ## Log at debug level. + # debug = false + ## Log only error level messages. + # quiet = false + + ## Log target controls the destination for logs and can be one of "file", + ## "stderr" or, on Windows, "eventlog". When set to "file", the output file + ## is determined by the "logfile" setting. + # logtarget = "file" + + ## Name of the file to be logged to when using the "file" logtarget. If set to + ## the empty string then logs are written to stderr. + # logfile = "" + + ## The logfile will be rotated after the time interval specified. When set + ## to 0 no time based rotation is performed. Logs are rotated only when + ## written to, if there is no log activity rotation may be delayed. + # logfile_rotation_interval = "0h" + + ## The logfile will be rotated when it becomes larger than the specified + ## size. When set to 0 no size based rotation is performed. + # logfile_rotation_max_size = "0MB" + + ## Maximum number of rotated archives to keep, any older logs are deleted. + ## If set to -1, no archives are removed. + # logfile_rotation_max_archives = 5 + + ## Pick a timezone to use when logging or type 'local' for local time. + ## Example: America/Chicago + # log_with_timezone = "" + + ## Override default hostname, if empty use os.Hostname() + hostname = "" + ## If set to true, do no set the "host" tag in the telegraf agent. + omit_hostname = false + + ## Method of translating SNMP objects. Can be "netsnmp" which + ## translates by calling external programs snmptranslate and snmptable, + ## or "gosmi" which translates using the built-in gosmi library. + # snmp_translator = "netsnmp" ############################################################################### # OUTPUT PLUGINS # @@ -1677,6 +1677,23 @@ # ## Export metric collection time. # # export_timestamp = false +# # Configuration for the RedisTimeSeries server to send metrics to +# [[outputs.redistimeseries]] +# ## The address of the RedisTimeSeries server. +# address = "127.0.0.1:6379" +# ## password to login Redis +# password = "" +# +# ## username (optional) +# username = "" +# # redis database number (optional, must be an integer) +# database = 0 +# +# ## optional TLS configurations +# tls_ca = "/etc/telegraf/ca.pem +# tls_cert = "/etc/telegraf/cert.pem" +# tls_key = "/etc/telegraf/key.pem" +# insecure_skip_verify = false # # Configuration for Riemann to send metrics to # [[outputs.riemann]] @@ -6216,9 +6233,9 @@ # # A plugin to collect stats from Opensmtpd - a validating, recursive, and caching DNS resolver -# [[inputs.opensmtpd]] -# ## If running as a restricted user you can prepend sudo for additional access: -# #use_sudo = false +# [[inputs.opensmtpd]] +# ## If running as a restricted user you can prepend sudo for additional access: +# #use_sudo = false # # ## The default location of the smtpctl binary can be overridden with: # binary = "/usr/sbin/smtpctl" @@ -8403,35 +8420,35 @@ # # Read Intel RDT metrics # [[inputs.intel_rdt]] -# ## Optionally set sampling interval to Nx100ms. -# ## This value is propagated to pqos tool. Interval format is defined by pqos itself. -# ## If not provided or provided 0, will be set to 10 = 10x100ms = 1s. -# # sampling_interval = "10" +# ## Optionally set sampling interval to Nx100ms. +# ## This value is propagated to pqos tool. Interval format is defined by pqos itself. +# ## If not provided or provided 0, will be set to 10 = 10x100ms = 1s. +# # sampling_interval = "10" # -# ## Optionally specify the path to pqos executable. -# ## If not provided, auto discovery will be performed. -# # pqos_path = "/usr/local/bin/pqos" +# ## Optionally specify the path to pqos executable. +# ## If not provided, auto discovery will be performed. +# # pqos_path = "/usr/local/bin/pqos" # -# ## Optionally specify if IPC and LLC_Misses metrics shouldn't be propagated. -# ## If not provided, default value is false. -# # shortened_metrics = false +# ## Optionally specify if IPC and LLC_Misses metrics shouldn't be propagated. +# ## If not provided, default value is false. +# # shortened_metrics = false # -# ## Specify the list of groups of CPU core(s) to be provided as pqos input. -# ## Mandatory if processes aren't set and forbidden if processes are specified. -# ## e.g. ["0-3", "4,5,6"] or ["1-3,4"] -# # cores = ["0-3"] +# ## Specify the list of groups of CPU core(s) to be provided as pqos input. +# ## Mandatory if processes aren't set and forbidden if processes are specified. +# ## e.g. ["0-3", "4,5,6"] or ["1-3,4"] +# # cores = ["0-3"] # -# ## Specify the list of processes for which Metrics will be collected. -# ## Mandatory if cores aren't set and forbidden if cores are specified. -# ## e.g. ["qemu", "pmd"] -# # processes = ["process"] +# ## Specify the list of processes for which Metrics will be collected. +# ## Mandatory if cores aren't set and forbidden if cores are specified. +# ## e.g. ["qemu", "pmd"] +# # processes = ["process"] # -# ## Specify if the pqos process should be called with sudo. -# ## Mandatory if the telegraf process does not run as root. -# # use_sudo = false +# ## Specify if the pqos process should be called with sudo. +# ## Mandatory if the telegraf process does not run as root. +# # use_sudo = false -# # Subscribe and receive OpenConfig Telemetry data using JTI +# # Read JTI OpenConfig Telemetry from listed sensors # [[inputs.jti_openconfig_telemetry]] # ## List of device addresses to collect telemetry from # servers = ["localhost:1883"] diff --git a/go.mod b/go.mod index ea0fe6fc0..cb9948cd3 100644 --- a/go.mod +++ b/go.mod @@ -60,7 +60,6 @@ require ( github.com/go-ldap/ldap/v3 v3.4.1 github.com/go-logfmt/logfmt v0.5.1 github.com/go-ping/ping v0.0.0-20210201095549-52eed920f98c - github.com/go-redis/redis v6.15.9+incompatible github.com/go-redis/redis/v8 v8.11.5 github.com/go-sql-driver/mysql v1.6.0 github.com/go-stomp/stomp v2.1.4+incompatible @@ -174,6 +173,8 @@ require ( modernc.org/sqlite v1.17.3 ) +require github.com/go-redis/redis/v7 v7.4.1 + require ( cloud.google.com/go v0.102.1 // indirect cloud.google.com/go/compute v1.6.1 // indirect diff --git a/go.sum b/go.sum index f044abcfe..71269dacd 100644 --- a/go.sum +++ b/go.sum @@ -918,6 +918,8 @@ github.com/go-playground/locales v0.12.1/go.mod h1:IUMDtCfWo/w/mtMfIE/IG2K+Ey3yg github.com/go-playground/universal-translator v0.16.0/go.mod h1:1AnU7NaIRDWWzGEKwgtJRd2xk99HeFyHw3yid4rvQIY= github.com/go-redis/redis v6.15.9+incompatible h1:K0pv1D7EQUjfyoMql+r/jZqCLizCGKFlFgcHWWmHQjg= github.com/go-redis/redis v6.15.9+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA= +github.com/go-redis/redis/v7 v7.4.1 h1:PASvf36gyUpr2zdOUS/9Zqc80GbM+9BDyiJSJDDOrTI= +github.com/go-redis/redis/v7 v7.4.1/go.mod h1:JDNMw23GTyLNC4GZu9njt15ctBQVn7xjRfnwdHj/Dcg= github.com/go-redis/redis/v8 v8.0.0-beta.6/go.mod h1:g79Vpae8JMzg5qjk8BiwU9tK+HmU3iDVyS4UAJLFycI= github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI= github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo= diff --git a/plugins/inputs/redis/README.md b/plugins/inputs/redis/README.md index 2512499c0..939a6b8a8 100644 --- a/plugins/inputs/redis/README.md +++ b/plugins/inputs/redis/README.md @@ -28,7 +28,8 @@ The Redis input plugin gathers metrics from one or many Redis servers. # # Can be "string", "integer", or "float" # type = "string" - ## specify server password + ## specify server connection parameters + # username = "myuser" # password = "s#cr@t%" ## specify username for ACL auth (Redis 6.0+) diff --git a/plugins/inputs/redis_sentinel/redis_sentinel.go b/plugins/inputs/redis_sentinel/redis_sentinel.go index 0652cd472..25c624b69 100644 --- a/plugins/inputs/redis_sentinel/redis_sentinel.go +++ b/plugins/inputs/redis_sentinel/redis_sentinel.go @@ -11,7 +11,7 @@ import ( "strings" "sync" - "github.com/go-redis/redis" + "github.com/go-redis/redis/v7" "github.com/influxdata/telegraf" "github.com/influxdata/telegraf/plugins/common/tls" diff --git a/plugins/outputs/all/all.go b/plugins/outputs/all/all.go index 3ae87835f..4d5e9b56b 100644 --- a/plugins/outputs/all/all.go +++ b/plugins/outputs/all/all.go @@ -41,6 +41,7 @@ import ( _ "github.com/influxdata/telegraf/plugins/outputs/opentelemetry" _ "github.com/influxdata/telegraf/plugins/outputs/opentsdb" _ "github.com/influxdata/telegraf/plugins/outputs/prometheus_client" + _ "github.com/influxdata/telegraf/plugins/outputs/redistimeseries" _ "github.com/influxdata/telegraf/plugins/outputs/riemann" _ "github.com/influxdata/telegraf/plugins/outputs/riemann_legacy" _ "github.com/influxdata/telegraf/plugins/outputs/sensu" diff --git a/plugins/outputs/redistimeseries/README.md b/plugins/outputs/redistimeseries/README.md new file mode 100644 index 000000000..9dc27327a --- /dev/null +++ b/plugins/outputs/redistimeseries/README.md @@ -0,0 +1,24 @@ +# RedisTimeSeries Producer Output Plugin + +The RedisTimeSeries output plugin writes metrics to the RedisTimeSeries server. + +## Configuration + +```toml +[[outputs.redistimeseries]] + ## The address of the RedisTimeSeries server. + address = "127.0.0.1:6379" + ## password to login Redis + password = "" + + ## username (optional) + # username = "" + # redis database number (optional, must be an integer) + # database = 0 + + ## optional TLS configurations + # tls_ca = "/etc/telegraf/ca.pem" + # tls_cert = "/etc/telegraf/cert.pem" + # tls_key = "/etc/telegraf/key.pem" + # insecure_skip_verify = false +``` diff --git a/plugins/outputs/redistimeseries/redistimeseries.go b/plugins/outputs/redistimeseries/redistimeseries.go new file mode 100644 index 000000000..d6f5e520e --- /dev/null +++ b/plugins/outputs/redistimeseries/redistimeseries.go @@ -0,0 +1,91 @@ +package redistimeseries + +import ( + "errors" + "fmt" + + "github.com/go-redis/redis/v7" + "github.com/influxdata/telegraf" + "github.com/influxdata/telegraf/plugins/common/tls" + "github.com/influxdata/telegraf/plugins/outputs" +) + +const sampleConfig = ` + ## The address of the RedisTimeSeries server. + address = "127.0.0.1:6379" + + ## Redis ACL credentials + # username = "" + # password = "" + # database = 0 + + ## Optional TLS Config + # tls_ca = "/etc/telegraf/ca.pem" + # tls_cert = "/etc/telegraf/cert.pem" + # tls_key = "/etc/telegraf/key.pem" + # insecure_skip_verify = false +` + +type RedisTimeSeries struct { + Address string `toml:"address"` + Username string `toml:"username"` + Password string `toml:"password"` + Database int `toml:"database"` + Log telegraf.Logger `toml:"-"` + tls.ClientConfig + client *redis.Client +} + +func (r *RedisTimeSeries) Connect() error { + if r.Address == "" { + return errors.New("redis address must be specified") + } + r.client = redis.NewClient(&redis.Options{ + Addr: r.Address, + Password: r.Password, + Username: r.Username, + DB: r.Database, + }) + return r.client.Ping().Err() +} + +func (r *RedisTimeSeries) Close() error { + return r.client.Close() +} + +func (r *RedisTimeSeries) Description() string { + return "Plugin for sending metrics to RedisTimeSeries" +} + +func (r *RedisTimeSeries) SampleConfig() string { + return sampleConfig +} +func (r *RedisTimeSeries) Write(metrics []telegraf.Metric) error { + for _, m := range metrics { + now := m.Time().UnixNano() / 1000000 // in milliseconds + name := m.Name() + + var tags []interface{} + for k, v := range m.Tags() { + tags = append(tags, k, v) + } + + for fieldName, value := range m.Fields() { + key := name + "_" + fieldName + + addSlice := []interface{}{"TS.ADD", key, now, value} + addSlice = append(addSlice, tags...) + + if err := r.client.Do(addSlice...).Err(); err != nil { + return fmt.Errorf("adding sample failed: %v", err) + } + } + } + return nil +} + +func init() { + outputs.Add("redistimeseries", func() telegraf.Output { + return &RedisTimeSeries{} + }) +} diff --git a/plugins/outputs/redistimeseries/redistimeseries_test.go b/plugins/outputs/redistimeseries/redistimeseries_test.go new file mode 100644 index 000000000..dbfc6f152 --- /dev/null +++ b/plugins/outputs/redistimeseries/redistimeseries_test.go @@ -0,0 +1,26 @@ +package redistimeseries + +import ( + "github.com/influxdata/telegraf/testutil" + "github.com/stretchr/testify/require" + "testing" +) + +func TestConnectAndWrite(t *testing.T) { + if testing.Short() { + t.Skip("Skipping integration test in short mode") + } + + address := testutil.GetLocalHost() + ":6379" + redis := &RedisTimeSeries{ + Address: address, + } + + // Verify that we can connect to the RedisTimeSeries server + err := redis.Connect() + require.NoError(t, err) + + // Verify that we can successfully write data to the RedisTimeSeries server + err = redis.Write(testutil.MockMetrics()) + require.NoError(t, err) +}