feat: add functionality to get values from redis commands (#8196)

This commit is contained in:
Yoofi Quansah 2020-09-30 09:36:45 -07:00 committed by GitHub
parent 06c62f263c
commit 2332e28802
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 97 additions and 3 deletions

2
go.mod
View File

@ -50,7 +50,7 @@ require (
github.com/glinton/ping v0.1.4-0.20200311211934-5ac87da8cd96
github.com/go-logfmt/logfmt v0.4.0
github.com/go-ole/go-ole v1.2.1 // indirect
github.com/go-redis/redis v6.12.0+incompatible
github.com/go-redis/redis v6.15.9+incompatible
github.com/go-sql-driver/mysql v1.5.0
github.com/goburrow/modbus v0.1.0
github.com/goburrow/serial v0.1.0 // indirect

4
go.sum
View File

@ -214,8 +214,8 @@ github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+
github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg=
github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc=
github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I=
github.com/go-redis/redis v6.12.0+incompatible h1:s+64XI+z/RXqGHz2fQSgRJOEwqqSXeX3dliF7iVkMbE=
github.com/go-redis/redis v6.12.0+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
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-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs=
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=

View File

@ -14,6 +14,11 @@
## If no servers are specified, then localhost is used as the host.
## If no port is specified, 6379 is used
servers = ["tcp://localhost:6379"]
## Optional. Specify redis commands to retrieve values
# [[inputs.redis.commands]]
# command = ["get", "sample-key"]
# field = "sample-key-value"
# type = "string"
## specify server password
# password = "s#cr@t%"

View File

@ -17,7 +17,14 @@ import (
"github.com/influxdata/telegraf/plugins/inputs"
)
type RedisCommand struct {
Command []interface{}
Field string
Type string
}
type Redis struct {
Commands []*RedisCommand
Servers []string
Password string
tls.ClientConfig
@ -29,6 +36,7 @@ type Redis struct {
}
type Client interface {
Do(returnType string, args ...interface{}) (interface{}, error)
Info() *redis.StringCmd
BaseTags() map[string]string
}
@ -38,6 +46,21 @@ type RedisClient struct {
tags map[string]string
}
func (r *RedisClient) Do(returnType string, args ...interface{}) (interface{}, error) {
rawVal := r.client.Do(args...)
switch returnType {
case "integer":
return rawVal.Int64()
case "string":
return rawVal.String()
case "float":
return rawVal.Float64()
default:
return rawVal.String()
}
}
func (r *RedisClient) Info() *redis.StringCmd {
return r.client.Info("ALL")
}
@ -64,6 +87,12 @@ var sampleConfig = `
## If no port is specified, 6379 is used
servers = ["tcp://localhost:6379"]
## Optional. Specify redis commands to retrieve values
# [[inputs.redis.commands]]
# command = ["get", "sample-key"]
# field = "sample-key-value"
# type = "string"
## specify server password
# password = "s#cr@t%"
@ -179,6 +208,7 @@ func (r *Redis) Gather(acc telegraf.Accumulator) error {
go func(client Client) {
defer wg.Done()
acc.AddError(r.gatherServer(client, acc))
acc.AddError(r.gatherCommandValues(client, acc))
}(client)
}
@ -186,6 +216,22 @@ func (r *Redis) Gather(acc telegraf.Accumulator) error {
return nil
}
func (r *Redis) gatherCommandValues(client Client, acc telegraf.Accumulator) error {
fields := make(map[string]interface{})
for _, command := range r.Commands {
val, err := client.Do(command.Type, command.Command...)
if err != nil {
return err
}
fields[command.Field] = val
}
acc.AddFields("redis_commands", fields, client.BaseTags())
return nil
}
func (r *Redis) gatherServer(client Client, acc telegraf.Accumulator) error {
info, err := client.Info().Result()
if err != nil {

View File

@ -7,11 +7,27 @@ import (
"testing"
"time"
"github.com/go-redis/redis"
"github.com/influxdata/telegraf/testutil"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
type testClient struct {
}
func (t *testClient) BaseTags() map[string]string {
return map[string]string{"host": "redis.net"}
}
func (t *testClient) Info() *redis.StringCmd {
return nil
}
func (t *testClient) Do(returnType string, args ...interface{}) (interface{}, error) {
return 2, nil
}
func TestRedisConnect(t *testing.T) {
if testing.Short() {
t.Skip("Skipping integration test in short mode")
@ -30,6 +46,33 @@ func TestRedisConnect(t *testing.T) {
require.NoError(t, err)
}
func TestRedis_Commands(t *testing.T) {
const redisListKey = "test-list-length"
var acc testutil.Accumulator
tc := &testClient{}
rc := &RedisCommand{
Command: []interface{}{"llen", "test-list"},
Field: redisListKey,
Type: "integer",
}
r := &Redis{
Commands: []*RedisCommand{rc},
clients: []Client{tc},
}
err := r.gatherCommandValues(tc, &acc)
require.NoError(t, err)
fields := map[string]interface{}{
redisListKey: 2,
}
acc.AssertContainsFields(t, "redis_commands", fields)
}
func TestRedis_ParseMetrics(t *testing.T) {
var acc testutil.Accumulator
tags := map[string]string{"host": "redis.net"}