mirror of https://github.com/grafana/grafana
parent
1a05ae2eaa
commit
e0c6048820
@ -0,0 +1,82 @@ |
||||
// includes code from
|
||||
// https://raw.githubusercontent.com/rcrowley/go-metrics/master/sample.go
|
||||
// Copyright 2012 Richard Crowley. All rights reserved.
|
||||
|
||||
package metrics |
||||
|
||||
import "sync/atomic" |
||||
|
||||
// Gauges hold an int64 value that can be set arbitrarily.
|
||||
type Gauge interface { |
||||
Metric |
||||
|
||||
Update(int64) |
||||
Value() int64 |
||||
} |
||||
|
||||
func NewGauge(meta *MetricMeta) Gauge { |
||||
if UseNilMetrics { |
||||
return NilGauge{} |
||||
} |
||||
return &StandardGauge{ |
||||
MetricMeta: meta, |
||||
value: 0, |
||||
} |
||||
} |
||||
|
||||
func RegGauge(meta *MetricMeta) Gauge { |
||||
g := NewGauge(meta) |
||||
MetricStats.Register(g) |
||||
return g |
||||
} |
||||
|
||||
// GaugeSnapshot is a read-only copy of another Gauge.
|
||||
type GaugeSnapshot struct { |
||||
*MetricMeta |
||||
value int64 |
||||
} |
||||
|
||||
// Snapshot returns the snapshot.
|
||||
func (g GaugeSnapshot) Snapshot() Metric { return g } |
||||
|
||||
// Update panics.
|
||||
func (GaugeSnapshot) Update(int64) { |
||||
panic("Update called on a GaugeSnapshot") |
||||
} |
||||
|
||||
// Value returns the value at the time the snapshot was taken.
|
||||
func (g GaugeSnapshot) Value() int64 { return g.value } |
||||
|
||||
// NilGauge is a no-op Gauge.
|
||||
type NilGauge struct{ *MetricMeta } |
||||
|
||||
// Snapshot is a no-op.
|
||||
func (NilGauge) Snapshot() Metric { return NilGauge{} } |
||||
|
||||
// Update is a no-op.
|
||||
func (NilGauge) Update(v int64) {} |
||||
|
||||
// Value is a no-op.
|
||||
func (NilGauge) Value() int64 { return 0 } |
||||
|
||||
// StandardGauge is the standard implementation of a Gauge and uses the
|
||||
// sync/atomic package to manage a single int64 value.
|
||||
type StandardGauge struct { |
||||
*MetricMeta |
||||
value int64 |
||||
} |
||||
|
||||
// Snapshot returns a read-only copy of the gauge.
|
||||
func (g *StandardGauge) Snapshot() Metric { |
||||
return GaugeSnapshot{MetricMeta: g.MetricMeta, value: g.value} |
||||
} |
||||
|
||||
// Update updates the gauge's value.
|
||||
func (g *StandardGauge) Update(v int64) { |
||||
atomic.StoreInt64(&g.value, v) |
||||
} |
||||
|
||||
// Value returns the gauge's current value.
|
||||
func (g *StandardGauge) Value() int64 { |
||||
return atomic.LoadInt64(&g.value) |
||||
} |
@ -1,130 +0,0 @@ |
||||
package metrics |
||||
|
||||
import ( |
||||
"net/url" |
||||
"time" |
||||
|
||||
"github.com/grafana/grafana/pkg/log" |
||||
"github.com/grafana/grafana/pkg/setting" |
||||
"github.com/influxdata/influxdb/client" |
||||
) |
||||
|
||||
type InfluxPublisher struct { |
||||
database string |
||||
tags map[string]string |
||||
prefix string |
||||
client *client.Client |
||||
prevCounts map[string]int64 |
||||
} |
||||
|
||||
func CreateInfluxPublisher() (*InfluxPublisher, error) { |
||||
influxSection, err := setting.Cfg.GetSection("metrics.influxdb") |
||||
if err != nil { |
||||
return nil, nil |
||||
} |
||||
|
||||
publisher := &InfluxPublisher{ |
||||
tags: make(map[string]string), |
||||
} |
||||
|
||||
urlStr := influxSection.Key("url").MustString("localhost:2003") |
||||
urlParsed, err := url.Parse(urlStr) |
||||
|
||||
if err != nil { |
||||
log.Error(3, "Metics: InfluxPublisher: failed to init influxdb publisher", err) |
||||
return nil, nil |
||||
} |
||||
|
||||
publisher.database = influxSection.Key("database").MustString("grafana_metrics") |
||||
publisher.prefix = influxSection.Key("prefix").MustString("prefix") |
||||
publisher.prevCounts = make(map[string]int64) |
||||
|
||||
username := influxSection.Key("User").MustString("grafana") |
||||
password := influxSection.Key("Password").MustString("grafana") |
||||
|
||||
publisher.client, err = client.NewClient(client.Config{ |
||||
URL: *urlParsed, |
||||
Username: username, |
||||
Password: password, |
||||
}) |
||||
|
||||
tagsSec, err := setting.Cfg.GetSection("metrics.influxdb.tags") |
||||
if err != nil { |
||||
log.Error(3, "Metics: InfluxPublisher: failed to init influxdb settings no metrics.influxdb.tags section") |
||||
return nil, nil |
||||
} |
||||
|
||||
for _, key := range tagsSec.Keys() { |
||||
publisher.tags[key.Name()] = key.String() |
||||
} |
||||
|
||||
if err != nil { |
||||
log.Error(3, "Metics: InfluxPublisher: failed to init influxdb publisher", err) |
||||
} |
||||
|
||||
return publisher, nil |
||||
} |
||||
|
||||
func (this *InfluxPublisher) Publish(metrics []Metric) { |
||||
bp := client.BatchPoints{ |
||||
Time: time.Now(), |
||||
Database: this.database, |
||||
Tags: map[string]string{}, |
||||
} |
||||
|
||||
for key, value := range this.tags { |
||||
bp.Tags[key] = value |
||||
} |
||||
|
||||
for _, m := range metrics { |
||||
switch metric := m.(type) { |
||||
case Counter: |
||||
this.addPoint(&bp, metric, "count", metric.Count()) |
||||
case Timer: |
||||
percentiles := metric.Percentiles([]float64{0.25, 0.75, 0.90, 0.99}) |
||||
this.addPoint(&bp, metric, "count", metric.Count()) |
||||
this.addPoint(&bp, metric, "min", metric.Min()) |
||||
this.addPoint(&bp, metric, "max", metric.Max()) |
||||
this.addPoint(&bp, metric, "mean", metric.Mean()) |
||||
this.addPoint(&bp, metric, "std", metric.StdDev()) |
||||
this.addPoint(&bp, metric, "p25", percentiles[0]) |
||||
this.addPoint(&bp, metric, "p75", percentiles[1]) |
||||
this.addPoint(&bp, metric, "p90", percentiles[2]) |
||||
this.addPoint(&bp, metric, "p99", percentiles[2]) |
||||
} |
||||
} |
||||
|
||||
_, err := this.client.Write(bp) |
||||
if err != nil { |
||||
log.Error(3, "Metrics: InfluxPublisher: publish error", err) |
||||
} |
||||
} |
||||
|
||||
func (this *InfluxPublisher) addPoint(bp *client.BatchPoints, metric Metric, metricTag string, value interface{}) { |
||||
tags := metric.GetTagsCopy() |
||||
tags["metric"] = metricTag |
||||
|
||||
bp.Points = append(bp.Points, client.Point{ |
||||
Measurement: metric.Name(), |
||||
Tags: tags, |
||||
Fields: map[string]interface{}{"value": value}, |
||||
}) |
||||
} |
||||
|
||||
func (this *InfluxPublisher) addCountPoint(bp *client.BatchPoints, metric Metric, value int64) { |
||||
tags := metric.GetTagsCopy() |
||||
tags["metric"] = "count" |
||||
|
||||
name := metric.Name() |
||||
delta := value |
||||
if last, ok := this.prevCounts[name]; ok { |
||||
delta = calculateDelta(last, value) |
||||
} |
||||
this.prevCounts[name] = value |
||||
|
||||
bp.Points = append(bp.Points, client.Point{ |
||||
Measurement: name, |
||||
Tags: tags, |
||||
Fields: map[string]interface{}{"value": delta}, |
||||
}) |
||||
} |
Loading…
Reference in new issue