diff --git a/README.md b/README.md index dc9bb9d85..60644bfd8 100644 --- a/README.md +++ b/README.md @@ -292,7 +292,7 @@ actual query results so that you can compare across databases that the results are the same. Using the flag `-print-responses` will return the results. -## Appendix I: Query types +## Appendix I: Query types ### Devops / cpu-only |Query type|Description| diff --git a/cmd/tsbs_generate_data/devops/cpu.go b/cmd/tsbs_generate_data/devops/cpu.go index f2907eb28..26ae5d778 100644 --- a/cmd/tsbs_generate_data/devops/cpu.go +++ b/cmd/tsbs_generate_data/devops/cpu.go @@ -1,7 +1,6 @@ package devops import ( - "math" "math/rand" "time" @@ -10,8 +9,8 @@ import ( ) var ( - CPUByteString = []byte("cpu") // heap optimization - CPUFields = []labeledDistributionMaker{ + labelCPU = []byte("cpu") // heap optimization + CPUFields = []labeledDistributionMaker{ {[]byte("usage_user"), func() common.Distribution { return common.CWD(cpuND, 0.0, 100.0, rand.Float64()*100.0) }}, {[]byte("usage_system"), func() common.Distribution { return common.CWD(cpuND, 0.0, 100.0, rand.Float64()*100.0) }}, {[]byte("usage_idle"), func() common.Distribution { return common.CWD(cpuND, 0.0, 100.0, rand.Float64()*100.0) }}, @@ -43,21 +42,10 @@ func newSingleCPUMeasurement(start time.Time) *CPUMeasurement { } func newCPUMeasurementNumDistributions(start time.Time, numDistributions int) *CPUMeasurement { - sub := newSubsystemMeasurement(start, numDistributions) - for i := 0; i < numDistributions; i++ { - sub.distributions[i] = CPUFields[i].distributionMaker() - } + sub := newSubsystemMeasurementWithDistributionMakers(start, CPUFields) return &CPUMeasurement{sub} } func (m *CPUMeasurement) ToPoint(p *serialize.Point) { - p.SetMeasurementName(CPUByteString) - p.SetTimestamp(&m.timestamp) - - for i := range m.distributions { - // Use ints for CPU metrics. - // The full float64 precision in the distributions list is bad for compression on some systems (e.g., ZFS). - // Anything above int precision is also not that common or useful for a devops CPU monitoring use case. - p.AppendField(CPUFields[i].label, math.Round(m.distributions[i].Get())) - } + m.toPointAllInt64(p, labelCPU, CPUFields) } diff --git a/cmd/tsbs_generate_data/devops/disk.go b/cmd/tsbs_generate_data/devops/disk.go index 3de186a3e..60f7c3ca4 100644 --- a/cmd/tsbs_generate_data/devops/disk.go +++ b/cmd/tsbs_generate_data/devops/disk.go @@ -15,7 +15,7 @@ const ( ) var ( - DiskByteString = []byte("disk") // heap optimization + labelDisk = []byte("disk") // heap optimization TotalByteString = []byte("total") FreeByteString = []byte("free") UsedByteString = []byte("used") @@ -56,7 +56,7 @@ func NewDiskMeasurement(start time.Time) *DiskMeasurement { } func (m *DiskMeasurement) ToPoint(p *serialize.Point) { - p.SetMeasurementName(DiskByteString) + p.SetMeasurementName(labelDisk) p.SetTimestamp(&m.timestamp) p.AppendTag(DiskTags[0], m.path) diff --git a/cmd/tsbs_generate_data/devops/diskio.go b/cmd/tsbs_generate_data/devops/diskio.go index b146d5cca..5eee39204 100644 --- a/cmd/tsbs_generate_data/devops/diskio.go +++ b/cmd/tsbs_generate_data/devops/diskio.go @@ -10,7 +10,7 @@ import ( ) var ( - DiskIOByteString = []byte("diskio") // heap optimization + labelDiskIO = []byte("diskio") // heap optimization SerialByteString = []byte("serial") // Reuse NormalDistributions as arguments to other distributions. This is @@ -37,11 +37,7 @@ type DiskIOMeasurement struct { } func NewDiskIOMeasurement(start time.Time) *DiskIOMeasurement { - sub := newSubsystemMeasurement(start, len(DiskIOFields)) - for i := range DiskIOFields { - sub.distributions[i] = DiskIOFields[i].distributionMaker() - } - + sub := newSubsystemMeasurementWithDistributionMakers(start, DiskIOFields) serial := []byte(fmt.Sprintf("%03d-%03d-%03d", rand.Intn(1000), rand.Intn(1000), rand.Intn(1000))) return &DiskIOMeasurement{ subsystemMeasurement: sub, @@ -50,12 +46,6 @@ func NewDiskIOMeasurement(start time.Time) *DiskIOMeasurement { } func (m *DiskIOMeasurement) ToPoint(p *serialize.Point) { - p.SetMeasurementName(DiskIOByteString) - p.SetTimestamp(&m.timestamp) - + m.toPointAllInt64(p, labelDiskIO, DiskIOFields) p.AppendTag(SerialByteString, m.serial) - - for i := range m.distributions { - p.AppendField(DiskIOFields[i].label, int64(m.distributions[i].Get())) - } } diff --git a/cmd/tsbs_generate_data/devops/kernel.go b/cmd/tsbs_generate_data/devops/kernel.go index 40db13efa..a45c00607 100644 --- a/cmd/tsbs_generate_data/devops/kernel.go +++ b/cmd/tsbs_generate_data/devops/kernel.go @@ -9,7 +9,7 @@ import ( ) var ( - KernelByteString = []byte("kernel") // heap optimization + labelKernel = []byte("kernel") // heap optimization BootTimeByteString = []byte("boot_time") // Reuse NormalDistributions as arguments to other distributions. This is @@ -32,11 +32,7 @@ type KernelMeasurement struct { } func NewKernelMeasurement(start time.Time) *KernelMeasurement { - sub := newSubsystemMeasurement(start, len(KernelFields)) - for i := range KernelFields { - sub.distributions[i] = KernelFields[i].distributionMaker() - } - + sub := newSubsystemMeasurementWithDistributionMakers(start, KernelFields) bootTime := rand.Int63n(240) return &KernelMeasurement{ subsystemMeasurement: sub, @@ -45,11 +41,6 @@ func NewKernelMeasurement(start time.Time) *KernelMeasurement { } func (m *KernelMeasurement) ToPoint(p *serialize.Point) { - p.SetMeasurementName(KernelByteString) - p.SetTimestamp(&m.timestamp) - p.AppendField(BootTimeByteString, m.bootTime) - for i := range m.distributions { - p.AppendField(KernelFields[i].label, int64(m.distributions[i].Get())) - } + m.toPointAllInt64(p, labelKernel, KernelFields) } diff --git a/cmd/tsbs_generate_data/devops/measurement.go b/cmd/tsbs_generate_data/devops/measurement.go index 15233181a..0a9790c31 100644 --- a/cmd/tsbs_generate_data/devops/measurement.go +++ b/cmd/tsbs_generate_data/devops/measurement.go @@ -4,6 +4,7 @@ import ( "time" "bitbucket.org/440-labs/tsbs/cmd/tsbs_generate_data/common" + "bitbucket.org/440-labs/tsbs/cmd/tsbs_generate_data/serialize" ) type subsystemMeasurement struct { @@ -18,6 +19,14 @@ func newSubsystemMeasurement(start time.Time, numDistributions int) *subsystemMe } } +func newSubsystemMeasurementWithDistributionMakers(start time.Time, makers []labeledDistributionMaker) *subsystemMeasurement { + m := newSubsystemMeasurement(start, len(makers)) + for i := 0; i < len(makers); i++ { + m.distributions[i] = makers[i].distributionMaker() + } + return m +} + func (m *subsystemMeasurement) Tick(d time.Duration) { m.timestamp = m.timestamp.Add(d) for i := range m.distributions { @@ -25,6 +34,28 @@ func (m *subsystemMeasurement) Tick(d time.Duration) { } } +func (m *subsystemMeasurement) toPoint(p *serialize.Point, measurementName []byte, labels []labeledDistributionMaker) { + p.SetMeasurementName(measurementName) + p.SetTimestamp(&m.timestamp) + + for i, d := range m.distributions { + p.AppendField(labels[i].label, d.Get()) + } +} + +// toPointAllInt64 fills in a serialize.Point with a given measurementName and +// all vales from the distributions stored as int64. The labels for each field +// are given by the supplied []labeledDistributionMaker, assuming that the distributions +// are in the same order. +func (m *subsystemMeasurement) toPointAllInt64(p *serialize.Point, measurementName []byte, labels []labeledDistributionMaker) { + p.SetMeasurementName(measurementName) + p.SetTimestamp(&m.timestamp) + + for i, d := range m.distributions { + p.AppendField(labels[i].label, int64(d.Get())) + } +} + type labeledDistributionMaker struct { label []byte distributionMaker func() common.Distribution diff --git a/cmd/tsbs_generate_data/devops/measurement_test.go b/cmd/tsbs_generate_data/devops/measurement_test.go new file mode 100644 index 000000000..760911fb4 --- /dev/null +++ b/cmd/tsbs_generate_data/devops/measurement_test.go @@ -0,0 +1,155 @@ +package devops + +import ( + "bytes" + "math" + "strconv" + "strings" + "testing" + "time" + + "bitbucket.org/440-labs/tsbs/cmd/tsbs_generate_data/common" + "bitbucket.org/440-labs/tsbs/cmd/tsbs_generate_data/serialize" +) + +type monotonicDistribution struct { + state float64 +} + +func (d *monotonicDistribution) Advance() { + d.state++ +} + +func (d *monotonicDistribution) Get() float64 { + return d.state +} + +func TestNewSubsystemMeasurement(t *testing.T) { + cases := []struct { + desc string + numDistros int + }{ + { + desc: "no distros", + numDistros: 0, + }, + { + desc: "one distro", + numDistros: 1, + }, + { + desc: "three distros", + numDistros: 3, + }, + } + + for _, c := range cases { + now := time.Now() + m := newSubsystemMeasurement(now, c.numDistros) + if !m.timestamp.Equal(now) { + t.Errorf("%s: incorrect timestamp set: got %v want %v", c.desc, m.timestamp, now) + } + if got := len(m.distributions); got != c.numDistros { + t.Errorf("%s: incorrect number of distros: got %d want %d", c.desc, got, c.numDistros) + } + } +} + +func TestNewSubsystemMeasurementWithDistributionMakers(t *testing.T) { + makers := []labeledDistributionMaker{ + {[]byte("foo"), func() common.Distribution { return &monotonicDistribution{state: 0.0} }}, + {[]byte("bar"), func() common.Distribution { return &monotonicDistribution{state: 1.0} }}, + } + now := time.Now() + m := newSubsystemMeasurementWithDistributionMakers(now, makers) + if !m.timestamp.Equal(now) { + t.Errorf("incorrect timestamp set: got %v want %v", m.timestamp, now) + } + + if got := len(m.distributions); got != len(makers) { + t.Errorf("incorrect number of distros: got %d want %d", got, len(makers)) + } + + for i := 0; i < 2; i++ { + md := m.distributions[i].(*monotonicDistribution) + if got := md.state; got != float64(i) { + t.Errorf("distribution %d has wrong state: got %f want %f", i, got, float64(i)) + } + } +} + +func TestSubsytemMeasurementTick(t *testing.T) { + now := time.Now() + numDistros := 3 + m := newSubsystemMeasurement(now, numDistros) + for i := 0; i < numDistros; i++ { + m.distributions[i] = &monotonicDistribution{state: float64(i)} + } + m.Tick(time.Nanosecond) + if got := m.timestamp.UnixNano(); got != now.UnixNano()+1 { + t.Errorf("tick did not increase timestamp correct: got %d want %d", got, now.UnixNano()+1) + } + for i := 0; i < numDistros; i++ { + if got := m.distributions[i].Get(); got != float64(i+1) { + t.Errorf("tick did not advance distro %d: got %f want %f", i, got, float64(i+1)) + } + } +} + +const ( + toPointState = 0.5 + toPointLabel = "foo" + toPointFieldLabel = "foo1" +) + +func TestToPoint(t *testing.T) { + now := time.Now() + m, makers := setupToPoint(now) + p := serialize.NewPoint() + m.toPoint(p, []byte(toPointLabel), makers) + testCommonToPoint(t, p, toPointState+1.0) +} + +func TestToPointAllInt64(t *testing.T) { + now := time.Now() + m, makers := setupToPoint(now) + p := serialize.NewPoint() + m.toPointAllInt64(p, []byte(toPointLabel), makers) + testCommonToPoint(t, p, math.Floor(toPointState+1.0)) +} + +func setupToPoint(start time.Time) (*subsystemMeasurement, []labeledDistributionMaker) { + makers := []labeledDistributionMaker{ + {[]byte(toPointFieldLabel), func() common.Distribution { return &monotonicDistribution{state: toPointState} }}, + } + m := newSubsystemMeasurementWithDistributionMakers(start, makers) + m.Tick(time.Nanosecond) + return m, makers +} + +func testCommonToPoint(t *testing.T, p *serialize.Point, fieldVal float64) { + // serialize the point to check output + b := new(bytes.Buffer) + serializer := &serialize.InfluxSerializer{} + serializer.Serialize(p, b) + + if got := string(p.MeasurementName()); got != toPointLabel { + t.Errorf("measurement name incorrect: got %s want %s", got, toPointLabel) + } + + output := b.String() + + args := strings.Split(output, " ") + fieldArgs := strings.Split(args[1], "=") + fieldArgs[1] = strings.Replace(fieldArgs[1], "i", "", -1) + if got := fieldArgs[0]; got != toPointFieldLabel { + t.Errorf("incorrect field label: got %s want %s", got, toPointFieldLabel) + } + if got, err := strconv.ParseFloat(fieldArgs[1], 64); err != nil || got != fieldVal { + if err != nil { + t.Errorf("could not parse field value as float64: %v", err) + } else { + t.Errorf("incorrect field value: got %f want %f", got, fieldVal) + } + } +} diff --git a/cmd/tsbs_generate_data/devops/mem.go b/cmd/tsbs_generate_data/devops/mem.go index f1100a768..fe230e115 100644 --- a/cmd/tsbs_generate_data/devops/mem.go +++ b/cmd/tsbs_generate_data/devops/mem.go @@ -10,7 +10,7 @@ import ( ) var ( - MemoryByteString = []byte("mem") // heap optimization + labelMem = []byte("mem") // heap optimization // Choices for modeling a host's memory capacity. MemoryMaxBytesChoices = []int64{8 << 30, 12 << 30, 16 << 30} @@ -56,7 +56,7 @@ func NewMemMeasurement(start time.Time) *MemMeasurement { } func (m *MemMeasurement) ToPoint(p *serialize.Point) { - p.SetMeasurementName(MemoryByteString) + p.SetMeasurementName(labelMem) p.SetTimestamp(&m.timestamp) total := m.bytesTotal diff --git a/cmd/tsbs_generate_data/devops/net.go b/cmd/tsbs_generate_data/devops/net.go index 712224434..a6eafb90c 100644 --- a/cmd/tsbs_generate_data/devops/net.go +++ b/cmd/tsbs_generate_data/devops/net.go @@ -10,10 +10,8 @@ import ( ) var ( - NetByteString = []byte("net") // heap optimization - NetTags = [][]byte{ - []byte("interface"), - } + labelNet = []byte("net") // heap optimization + labelNetTagInterface = []byte("interface") // Reuse NormalDistributions as arguments to other distributions. This is // safe to do because the higher-level distribution advances the ND and @@ -39,11 +37,7 @@ type NetMeasurement struct { } func NewNetMeasurement(start time.Time) *NetMeasurement { - sub := newSubsystemMeasurement(start, len(NetFields)) - for i := range NetFields { - sub.distributions[i] = NetFields[i].distributionMaker() - } - + sub := newSubsystemMeasurementWithDistributionMakers(start, NetFields) interfaceName := []byte(fmt.Sprintf("eth%d", rand.Intn(4))) return &NetMeasurement{ subsystemMeasurement: sub, @@ -52,12 +46,6 @@ func NewNetMeasurement(start time.Time) *NetMeasurement { } func (m *NetMeasurement) ToPoint(p *serialize.Point) { - p.SetMeasurementName(NetByteString) - p.SetTimestamp(&m.timestamp) - - p.AppendTag(NetTags[0], m.interfaceName) - - for i := range m.distributions { - p.AppendField(RedisFields[i].label, int64(m.distributions[i].Get())) - } + m.toPointAllInt64(p, labelNet, NetFields) + p.AppendTag(labelNetTagInterface, m.interfaceName) } diff --git a/cmd/tsbs_generate_data/devops/nginx.go b/cmd/tsbs_generate_data/devops/nginx.go index 017c0077b..cc2060346 100644 --- a/cmd/tsbs_generate_data/devops/nginx.go +++ b/cmd/tsbs_generate_data/devops/nginx.go @@ -10,12 +10,9 @@ import ( ) var ( - NginxByteString = []byte("nginx") // heap optimization - - NginxTags = [][]byte{ - []byte("port"), - []byte("server"), - } + labelNginx = []byte("nginx") // heap optimization + labelNginxTagPort = []byte("port") + labelNginxTagServer = []byte("server") // Reuse NormalDistributions as arguments to other distributions. This is // safe to do because the higher-level distribution advances the ND and @@ -39,11 +36,7 @@ type NginxMeasurement struct { } func NewNginxMeasurement(start time.Time) *NginxMeasurement { - sub := newSubsystemMeasurement(start, len(NginxFields)) - for i := range NginxFields { - sub.distributions[i] = NginxFields[i].distributionMaker() - } - + sub := newSubsystemMeasurementWithDistributionMakers(start, NginxFields) serverName := []byte(fmt.Sprintf("nginx_%d", rand.Intn(100000))) port := []byte(fmt.Sprintf("%d", rand.Intn(20000)+1024)) return &NginxMeasurement{ @@ -54,13 +47,7 @@ func NewNginxMeasurement(start time.Time) *NginxMeasurement { } func (m *NginxMeasurement) ToPoint(p *serialize.Point) { - p.SetMeasurementName(NginxByteString) - p.SetTimestamp(&m.timestamp) - - p.AppendTag(NginxTags[0], m.port) - p.AppendTag(NginxTags[1], m.serverName) - - for i := range m.distributions { - p.AppendField(NginxFields[i].label, int64(m.distributions[i].Get())) - } + m.toPointAllInt64(p, labelNginx, NginxFields) + p.AppendTag(labelNginxTagPort, m.port) + p.AppendTag(labelNginxTagServer, m.serverName) } diff --git a/cmd/tsbs_generate_data/devops/postgresql.go b/cmd/tsbs_generate_data/devops/postgresql.go index da6a6df80..b5b2160ad 100644 --- a/cmd/tsbs_generate_data/devops/postgresql.go +++ b/cmd/tsbs_generate_data/devops/postgresql.go @@ -8,7 +8,7 @@ import ( ) var ( - PostgresqlByteString = []byte("postgresl") // heap optimization + labelPostgresql = []byte("postgresl") // heap optimization // Reuse NormalDistributions as arguments to other distributions. This is // safe to do because the higher-level distribution advances the ND and @@ -41,19 +41,10 @@ type PostgresqlMeasurement struct { } func NewPostgresqlMeasurement(start time.Time) *PostgresqlMeasurement { - sub := newSubsystemMeasurement(start, len(PostgresqlFields)) - for i := range PostgresqlFields { - sub.distributions[i] = PostgresqlFields[i].distributionMaker() - } - + sub := newSubsystemMeasurementWithDistributionMakers(start, PostgresqlFields) return &PostgresqlMeasurement{sub} } func (m *PostgresqlMeasurement) ToPoint(p *serialize.Point) { - p.SetMeasurementName(PostgresqlByteString) - p.SetTimestamp(&m.timestamp) - - for i := range m.distributions { - p.AppendField(PostgresqlFields[i].label, int64(m.distributions[i].Get())) - } + m.toPointAllInt64(p, labelPostgresql, PostgresqlFields) } diff --git a/cmd/tsbs_generate_data/devops/rand.go b/cmd/tsbs_generate_data/devops/rand.go index 6e2838739..6a6ac1026 100644 --- a/cmd/tsbs_generate_data/devops/rand.go +++ b/cmd/tsbs_generate_data/devops/rand.go @@ -8,7 +8,7 @@ import ( ) var ( - RandByteString = []byte("rand") // heap optimization + labelRand = []byte("rand") // heap optimization RandFields = []labeledDistributionMaker{ {[]byte("usage_user"), func() common.Distribution { return common.UD(0.0, 100.0) }}, @@ -29,18 +29,10 @@ type RandMeasurement struct { } func NewRandMeasurement(start time.Time) *RandMeasurement { - sub := newSubsystemMeasurement(start, len(RandFields)) - for i := range RandFields { - sub.distributions[i] = common.UD(0.0, 100.0) - } + sub := newSubsystemMeasurementWithDistributionMakers(start, RandFields) return &RandMeasurement{sub} } func (m *RandMeasurement) ToPoint(p *serialize.Point) { - p.SetMeasurementName(RandByteString) - p.SetTimestamp(&m.timestamp) - - for i := range m.distributions { - p.AppendField(RandFields[i].label, m.distributions[i].Get()) - } + m.toPoint(p, labelRand, RandFields) } diff --git a/cmd/tsbs_generate_data/devops/redis.go b/cmd/tsbs_generate_data/devops/redis.go index 7844c48be..416a77ec3 100644 --- a/cmd/tsbs_generate_data/devops/redis.go +++ b/cmd/tsbs_generate_data/devops/redis.go @@ -10,16 +10,12 @@ import ( ) var ( - RedisByteString = []byte("redis") // heap optimization + labelRedis = []byte("redis") // heap optimization + labelRedisTagPort = []byte("port") + labelRedisTagServer = []byte("server") + labelRedisFieldUptime = []byte("uptime_in_seconds") - RedisUptime = []byte("uptime_in_seconds") - - SixteenGB = float64(16 * 1024 * 1024 * 1024) - - RedisTags = [][]byte{ - []byte("port"), - []byte("server"), - } + sixteenGB = float64(16 * 1024 * 1024 * 1024) // Reuse NormalDistributions as arguments to other distributions. This is // safe to do because the higher-level distribution advances the ND and @@ -38,10 +34,10 @@ var ( {[]byte("instantaneous_input_kbps"), func() common.Distribution { return common.WD(common.ND(1, 1), 0) }}, {[]byte("instantaneous_output_kbps"), func() common.Distribution { return common.WD(common.ND(1, 1), 0) }}, {[]byte("connected_clients"), func() common.Distribution { return common.CWD(redisHighND, 0, 10000, 0) }}, - {[]byte("used_memory"), func() common.Distribution { return common.CWD(redisHighND, 0, SixteenGB, SixteenGB/2) }}, - {[]byte("used_memory_rss"), func() common.Distribution { return common.CWD(redisHighND, 0, SixteenGB, SixteenGB/2) }}, - {[]byte("used_memory_peak"), func() common.Distribution { return common.CWD(redisHighND, 0, SixteenGB, SixteenGB/2) }}, - {[]byte("used_memory_lua"), func() common.Distribution { return common.CWD(redisHighND, 0, SixteenGB, SixteenGB/2) }}, + {[]byte("used_memory"), func() common.Distribution { return common.CWD(redisHighND, 0, sixteenGB, sixteenGB/2) }}, + {[]byte("used_memory_rss"), func() common.Distribution { return common.CWD(redisHighND, 0, sixteenGB, sixteenGB/2) }}, + {[]byte("used_memory_peak"), func() common.Distribution { return common.CWD(redisHighND, 0, sixteenGB, sixteenGB/2) }}, + {[]byte("used_memory_lua"), func() common.Distribution { return common.CWD(redisHighND, 0, sixteenGB, sixteenGB/2) }}, {[]byte("rdb_changes_since_last_save"), func() common.Distribution { return common.CWD(redisHighND, 0, 10000, 0) }}, {[]byte("sync_full"), func() common.Distribution { return common.CWD(redisLowND, 0, 1000, 0) }}, @@ -71,11 +67,7 @@ type RedisMeasurement struct { } func NewRedisMeasurement(start time.Time) *RedisMeasurement { - sub := newSubsystemMeasurement(start, len(RedisFields)) - for i := range RedisFields { - sub.distributions[i] = RedisFields[i].distributionMaker() - } - + sub := newSubsystemMeasurementWithDistributionMakers(start, RedisFields) serverName := []byte(fmt.Sprintf("redis_%d", rand.Intn(100000))) port := []byte(fmt.Sprintf("%d", rand.Intn(20000)+1024)) return &RedisMeasurement{ @@ -92,14 +84,8 @@ func (m *RedisMeasurement) Tick(d time.Duration) { } func (m *RedisMeasurement) ToPoint(p *serialize.Point) { - p.SetMeasurementName(RedisByteString) - p.SetTimestamp(&m.timestamp) - - p.AppendTag(RedisTags[0], m.port) - p.AppendTag(RedisTags[1], m.serverName) - - p.AppendField(RedisUptime, int64(m.uptime.Seconds())) - for i := range m.distributions { - p.AppendField(RedisFields[i].label, int64(m.distributions[i].Get())) - } + p.AppendField(labelRedisFieldUptime, int64(m.uptime.Seconds())) + m.toPointAllInt64(p, labelRedis, RedisFields) + p.AppendTag(labelRedisTagPort, m.port) + p.AppendTag(labelRedisTagServer, m.serverName) }