diff --git a/pkg/metrics/receiver/graphite.go b/pkg/metrics/receiver/graphite.go new file mode 100644 index 00000000000..7e81cba6ef1 --- /dev/null +++ b/pkg/metrics/receiver/graphite.go @@ -0,0 +1,44 @@ +package receiver + +import ( + "bytes" + "fmt" + "github.com/grafana/grafana/pkg/log" + "net" + "time" +) + +type GraphiteSender struct { + Host string + Port string + Protocol string + Prefix string +} + +func (this *GraphiteSender) Send(metrics map[string]interface{}) error { + log.Debug("GraphiteSender: Sending metrics to graphite") + + address := fmt.Sprintf("%s:%s", this.Host, this.Port) + conn, err := net.DialTimeout(this.Protocol, address, time.Second*5) + + if err != nil { + return fmt.Errorf("Graphite Sender: Failed to connec to %s!", err) + } + + buf := bytes.NewBufferString("") + now := time.Now().Unix() + for key, value := range metrics { + metricName := this.Prefix + key + line := fmt.Sprintf("%s %d %d\n", metricName, value, now) + log.Debug("SendMetric: sending %s", line) + buf.WriteString(line) + } + + _, err = conn.Write(buf.Bytes()) + + if err != nil { + return fmt.Errorf("Graphite Sender: Failed to send metrics!", err) + } + + return nil +} diff --git a/pkg/metrics/report_usage.go b/pkg/metrics/report_usage.go index 85a87155f6d..6f1a6ca521e 100644 --- a/pkg/metrics/report_usage.go +++ b/pkg/metrics/report_usage.go @@ -9,23 +9,58 @@ import ( "github.com/grafana/grafana/pkg/bus" "github.com/grafana/grafana/pkg/log" + "github.com/grafana/grafana/pkg/metrics/receiver" m "github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/plugins" "github.com/grafana/grafana/pkg/setting" ) +type MetricSender interface { + Send(metrics map[string]interface{}) error +} + func StartUsageReportLoop() chan struct{} { M_Instance_Start.Inc(1) - ticker := time.NewTicker(time.Hour * 24) + hourTicker := time.NewTicker(time.Hour * 24) + secondTicker := time.NewTicker(time.Second * 10) + + sender := &receiver.GraphiteSender{ + Host: "localhost", + Port: "2003", + Protocol: "tcp", + Prefix: "grafana.", + } + for { select { - case <-ticker.C: + case <-hourTicker.C: sendUsageStats() + case <-secondTicker.C: + sendMetricUsage(sender) } } } +func sendMetricUsage(sender MetricSender) { + metrics := map[string]interface{}{} + + MetricStats.Each(func(name string, i interface{}) { + switch metric := i.(type) { + case Counter: + if metric.Count() > 0 { + metrics[name+".count"] = metric.Count() + metric.Clear() + } + } + }) + + err := sender.Send(metrics) + if err != nil { + log.Error(1, "Failed to send metrics:", err) + } +} + func sendUsageStats() { log.Trace("Sending anonymous usage stats to stats.grafana.org")