func TestGauge(t *testing.T) { g := NewGauge(api.Identifier{ Host: "example.com", Plugin: "golang", Type: "gauge", }) g.Set(42.0) want := api.ValueList{ Identifier: api.Identifier{ Host: "example.com", Plugin: "golang", Type: "gauge", }, Values: []api.Value{api.Gauge(42)}, } got := g.ValueList() if !reflect.DeepEqual(got, want) { t.Errorf("got %#v, want %#v", got, want) } s := expvar.Get("example.com/golang/gauge").String() if s != "42" { t.Errorf("got %q, want %q", s, "42") } }
func Example() { e := NewExecutor() // simple "value" callback answer := func() api.Value { return api.Gauge(42) } e.ValueCallback(answer, api.ValueList{ Identifier: api.Identifier{ Host: "example.com", Plugin: "golang", Type: "answer", TypeInstance: "live_universe_and_everything", }, Interval: time.Second, }) // "complex" void callback bicycles := func(interval time.Duration) { vl := api.ValueList{ Identifier: api.Identifier{ Host: "example.com", Plugin: "golang", Type: "bicycles", }, Interval: interval, Time: time.Now(), Values: make([]api.Value, 1), } data := []struct { TypeInstance string Value api.Gauge }{ {"beijing", api.Gauge(9000000)}, } for _, d := range data { vl.Values[0] = d.Value vl.Identifier.TypeInstance = d.TypeInstance Putval.Write(vl) } } e.VoidCallback(bicycles, time.Second) // blocks forever e.Run() }
// NewGauge initializes a new Gauge, registers it with the "expvar" package and // returns it. The initial value is NaN. func NewGauge(id api.Identifier) *Gauge { g := &Gauge{ id: id, value: api.Gauge(math.NaN()), } Publish(g) expvar.Publish(id.String(), g) return g }
func main() { flag.Parse() conn, err := network.Dial(*host, network.ClientOptions{}) if err != nil { fmt.Println(err) os.Exit(1) } defer conn.Close() rateLimiter := make(chan int, *rate) go func() { ticker := time.NewTicker(time.Second) for { select { case <-ticker.C: for i := 0; i < *rate; i++ { rateLimiter <- i } } } }() nSent := 0 for { if nSent >= *total && *total > 0 { break } <-rateLimiter vl := api.ValueList{ Identifier: api.Identifier{ Host: "tagvalue" + strconv.Itoa(int(rand.Int31n(int32(*tagVariance)))), Plugin: "golang" + strconv.Itoa(int(rand.Int31n(int32(*nMeasurments)))), Type: "gauge", }, Time: time.Now(), Interval: 10 * time.Second, Values: []api.Value{api.Gauge(42.0)}, } ctx := context.TODO() if err := conn.Write(ctx, &vl); err != nil { fmt.Println(err) os.Exit(1) } conn.Flush() nSent = nSent + 1 } fmt.Println("Number of points sent:", nSent) }
func TestWriteValues(t *testing.T) { b := &Buffer{buffer: new(bytes.Buffer), size: DefaultBufferSize} b.writeValues([]api.Value{ api.Gauge(42), api.Derive(31337), api.Gauge(math.NaN()), }) want := []byte{0, 6, // pkg type 0, 33, // pkg len 0, 3, // num values 1, 2, 1, // gauge, derive, gauge 0, 0, 0, 0, 0, 0, 0x45, 0x40, // 42.0 0, 0, 0, 0, 0, 0, 0x7a, 0x69, // 31337 0, 0, 0, 0, 0, 0, 0xf8, 0x7f, // NaN } got := b.buffer.Bytes() if !reflect.DeepEqual(got, want) { t.Errorf("got %v, want %v", got, want) } }
func parseValues(b []byte) ([]api.Value, error) { buffer := bytes.NewBuffer(b) var n uint16 if err := binary.Read(buffer, binary.BigEndian, &n); err != nil { return nil, err } if int(n*9) != buffer.Len() { return nil, ErrInvalid } types := make([]byte, n) values := make([]api.Value, n) if _, err := buffer.Read(types); err != nil { return nil, err } for i, typ := range types { switch typ { case dsTypeGauge: var v float64 if err := binary.Read(buffer, binary.LittleEndian, &v); err != nil { return nil, err } values[i] = api.Gauge(v) case dsTypeDerive: var v int64 if err := binary.Read(buffer, binary.BigEndian, &v); err != nil { return nil, err } values[i] = api.Derive(v) case dsTypeCounter: var v uint64 if err := binary.Read(buffer, binary.BigEndian, &v); err != nil { return nil, err } values[i] = api.Counter(v) default: return nil, ErrInvalid } } return values, nil }
func dispatch(key string, now time.Time, value float64, prefix string) { vl := api.ValueList{ Identifier: api.Identifier{ Host: exec.Hostname(), Plugin: fmt.Sprintf("%snet", prefix), PluginInstance: key}, Time: now, Interval: exec.Interval(), Values: []api.Value{api.Gauge(value)}, } exec.Putval.Write(vl) for _, client := range clients { if err := client.Write(vl); err != nil { log.Printf("[WARN] unable to write to client:%s, err:%s", client, err.Error()) } } }
func ExampleClient() { conn, err := Dial(net.JoinHostPort("example.com", DefaultService), ClientOptions{}) if err != nil { log.Fatal(err) } defer conn.Close() vl := api.ValueList{ Identifier: api.Identifier{ Host: "example.com", Plugin: "golang", Type: "gauge", }, Time: time.Now(), Interval: 10 * time.Second, Values: []api.Value{api.Gauge(42.0)}, } if err := conn.Write(vl); err != nil { log.Fatal(err) } }
// Set sets g to v. func (g *Gauge) Set(v float64) { g.mu.Lock() defer g.mu.Unlock() g.value = api.Gauge(v) }
func TestNewName(t *testing.T) { cases := []struct { vl api.ValueList index int want string }{ {api.ValueList{ Identifier: api.Identifier{ Plugin: "cpu", Type: "cpu", }, DSNames: []string{"value"}, Values: []api.Value{api.Derive(0)}, }, 0, "collectd_cpu"}, {api.ValueList{ Identifier: api.Identifier{ Plugin: "dns", Type: "dns_qtype", }, DSNames: []string{"value"}, Values: []api.Value{api.Derive(0)}, }, 0, "collectd_dns_dns_qtype"}, {api.ValueList{ Identifier: api.Identifier{ Plugin: "df", Type: "df", }, DSNames: []string{"used", "free"}, Values: []api.Value{api.Gauge(0), api.Gauge(1)}, }, 0, "collectd_df_used"}, {api.ValueList{ Identifier: api.Identifier{ Plugin: "df", Type: "df", }, DSNames: []string{"used", "free"}, Values: []api.Value{api.Gauge(0), api.Gauge(1)}, }, 1, "collectd_df_free"}, {api.ValueList{ Identifier: api.Identifier{ Plugin: "cpu", Type: "percent", }, DSNames: []string{"value"}, Values: []api.Value{api.Gauge(0)}, }, 0, "collectd_cpu_percent"}, {api.ValueList{ Identifier: api.Identifier{ Plugin: "interface", Type: "if_octets", }, DSNames: []string{"rx", "tx"}, Values: []api.Value{api.Counter(0), api.Counter(1)}, }, 0, "collectd_interface_if_octets_rx_total"}, {api.ValueList{ Identifier: api.Identifier{ Plugin: "interface", Type: "if_octets", }, DSNames: []string{"rx", "tx"}, Values: []api.Value{api.Counter(0), api.Counter(1)}, }, 1, "collectd_interface_if_octets_tx_total"}, } for _, c := range cases { got := newName(c.vl, c.index) if got != c.want { t.Errorf("newName(%v): got %q, want %q", c.vl, got, c.want) } } }
func TestWrite(t *testing.T) { cases := []struct { ValueList api.ValueList Graphite *Graphite Want string }{ { // case 0 ValueList: api.ValueList{ Identifier: api.Identifier{ Host: "example.com", Plugin: "golang", PluginInstance: "example", Type: "gauge", TypeInstance: "answer", }, Time: time.Unix(1426975989, 1), Interval: 10 * time.Second, Values: []api.Value{api.Gauge(42)}, }, Graphite: &Graphite{ Prefix: "-->", Suffix: "<--", EscapeChar: "_", SeparateInstances: false, AlwaysAppendDS: true, }, Want: "-->example_com<--.golang-example.gauge-answer.value 42 1426975989\r\n", }, { // case 1 ValueList: api.ValueList{ Identifier: api.Identifier{ Host: "example.com", Plugin: "golang", PluginInstance: "example", Type: "gauge", TypeInstance: "answer", }, Time: time.Unix(1426975989, 1), Interval: 10 * time.Second, Values: []api.Value{api.Derive(1337)}, }, Graphite: &Graphite{ Prefix: "collectd.", Suffix: "", EscapeChar: "@", SeparateInstances: true, AlwaysAppendDS: false, }, Want: "[email protected] 1337 1426975989\r\n", }, { // case 2 ValueList: api.ValueList{ Identifier: api.Identifier{ Host: "example.com", Plugin: "golang", Type: "gauge", }, Time: time.Unix(1426975989, 1), Interval: 10 * time.Second, Values: []api.Value{api.Gauge(42), api.Derive(1337)}, }, Graphite: &Graphite{ Prefix: "collectd.", Suffix: "", EscapeChar: "_", SeparateInstances: true, AlwaysAppendDS: false, }, Want: "collectd.example_com.golang.gauge.0 42 1426975989\r\n" + "collectd.example_com.golang.gauge.1 1337 1426975989\r\n", }, } for i, c := range cases { buf := &bytes.Buffer{} c.Graphite.W = buf if err := c.Graphite.Write(c.ValueList); err != nil { t.Errorf("case %d: got %v, want %v", i, err, nil) } got := buf.String() if got != c.Want { t.Errorf("got %q, want %q", got, c.Want) } } }