mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
feat(instrumentation): work on settings model for internal metrics publishing, #4696
This commit is contained in:
@@ -9,40 +9,36 @@ import (
|
||||
|
||||
"github.com/grafana/grafana/pkg/bus"
|
||||
"github.com/grafana/grafana/pkg/log"
|
||||
"github.com/grafana/grafana/pkg/metrics/senders"
|
||||
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 Init() {
|
||||
go instrumentationLoop()
|
||||
}
|
||||
|
||||
func StartUsageReportLoop() chan struct{} {
|
||||
func instrumentationLoop() chan struct{} {
|
||||
M_Instance_Start.Inc(1)
|
||||
|
||||
hourTicker := time.NewTicker(time.Hour * 24)
|
||||
secondTicker := time.NewTicker(time.Second * 10)
|
||||
settings := readSettings()
|
||||
|
||||
sender := &receiver.GraphiteSender{
|
||||
Host: "localhost",
|
||||
Port: "2003",
|
||||
Protocol: "tcp",
|
||||
Prefix: "grafana.",
|
||||
}
|
||||
onceEveryDayTick := time.NewTicker(time.Hour * 24)
|
||||
secondTicker := time.NewTicker(time.Second * time.Duration(settings.IntervalSeconds))
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-hourTicker.C:
|
||||
case <-onceEveryDayTick.C:
|
||||
sendUsageStats()
|
||||
case <-secondTicker.C:
|
||||
sendMetricUsage(sender)
|
||||
if settings.Enabled {
|
||||
sendMetrics(settings)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func sendMetricUsage(sender MetricSender) {
|
||||
func sendMetrics(settings *MetricSettings) {
|
||||
metrics := map[string]interface{}{}
|
||||
|
||||
MetricStats.Each(func(name string, i interface{}) {
|
||||
@@ -63,13 +59,16 @@ func sendMetricUsage(sender MetricSender) {
|
||||
}
|
||||
})
|
||||
|
||||
err := sender.Send(metrics)
|
||||
if err != nil {
|
||||
log.Error(1, "Failed to send metrics:", err)
|
||||
for _, publisher := range settings.Publishers {
|
||||
publisher.Publish(metrics)
|
||||
}
|
||||
}
|
||||
|
||||
func sendUsageStats() {
|
||||
if !setting.ReportingEnabled {
|
||||
return
|
||||
}
|
||||
|
||||
log.Trace("Sending anonymous usage stats to stats.grafana.org")
|
||||
|
||||
version := strings.Replace(setting.BuildVersion, ".", "_", -1)
|
||||
55
pkg/metrics/publishers/graphite.go
Normal file
55
pkg/metrics/publishers/graphite.go
Normal file
@@ -0,0 +1,55 @@
|
||||
package publishers
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"net"
|
||||
"time"
|
||||
|
||||
"github.com/grafana/grafana/pkg/log"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
)
|
||||
|
||||
type GraphitePublisher struct {
|
||||
Address string
|
||||
Protocol string
|
||||
Prefix string
|
||||
}
|
||||
|
||||
func CreateGraphitePublisher() (*GraphitePublisher, error) {
|
||||
graphiteSection, err := setting.Cfg.GetSection("metrics.graphite")
|
||||
if err != nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
graphiteReceiver := &GraphitePublisher{}
|
||||
graphiteReceiver.Protocol = "tcp"
|
||||
graphiteReceiver.Address = graphiteSection.Key("address").MustString("localhost:2003")
|
||||
graphiteReceiver.Prefix = graphiteSection.Key("prefix").MustString("service.grafana.%(instance_name)s")
|
||||
|
||||
return graphiteReceiver, nil
|
||||
}
|
||||
|
||||
func (this *GraphitePublisher) Publish(metrics map[string]interface{}) {
|
||||
conn, err := net.DialTimeout(this.Protocol, this.Address, time.Second*5)
|
||||
|
||||
if err != nil {
|
||||
log.Error(3, "Metrics: GraphitePublisher: Failed to connect to %s!", err)
|
||||
return
|
||||
}
|
||||
|
||||
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)
|
||||
buf.WriteString(line)
|
||||
}
|
||||
|
||||
log.Trace("Metrics: GraphitePublisher.Publish() \n%s", buf)
|
||||
_, err = conn.Write(buf.Bytes())
|
||||
|
||||
if err != nil {
|
||||
log.Error(3, "Metrics: GraphitePublisher: Failed to send metrics! %s", err)
|
||||
}
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
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! %s", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
47
pkg/metrics/settings.go
Normal file
47
pkg/metrics/settings.go
Normal file
@@ -0,0 +1,47 @@
|
||||
package metrics
|
||||
|
||||
import (
|
||||
"github.com/grafana/grafana/pkg/log"
|
||||
"github.com/grafana/grafana/pkg/metrics/publishers"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
)
|
||||
|
||||
type MetricPublisher interface {
|
||||
Publish(metrics map[string]interface{})
|
||||
}
|
||||
|
||||
type MetricSettings struct {
|
||||
Enabled bool
|
||||
IntervalSeconds int64
|
||||
|
||||
Publishers []MetricPublisher
|
||||
}
|
||||
|
||||
func readSettings() *MetricSettings {
|
||||
var settings = &MetricSettings{
|
||||
Enabled: false,
|
||||
Publishers: make([]MetricPublisher, 0),
|
||||
}
|
||||
|
||||
var section, err = setting.Cfg.GetSection("metrics")
|
||||
if err != nil {
|
||||
log.Fatal(3, "Unable to find metrics config section")
|
||||
return nil
|
||||
}
|
||||
|
||||
settings.Enabled = section.Key("enabled").MustBool(false)
|
||||
settings.IntervalSeconds = section.Key("interval_seconds").MustInt64(10)
|
||||
|
||||
if !settings.Enabled {
|
||||
return settings
|
||||
}
|
||||
|
||||
if graphitePublisher, err := publishers.CreateGraphitePublisher(); err != nil {
|
||||
log.Error(3, "Metrics: Failed to init Graphite metric publisher", err)
|
||||
} else if graphitePublisher != nil {
|
||||
log.Info("Metrics: Internal metrics publisher Graphite initialized")
|
||||
settings.Publishers = append(settings.Publishers, graphitePublisher)
|
||||
}
|
||||
|
||||
return settings
|
||||
}
|
||||
Reference in New Issue
Block a user