Commit 899d1553 authored by Kamil Kisiel's avatar Kamil Kisiel

More documentation

parent 33570415
......@@ -14,43 +14,36 @@ func init() {
percentThresholds = []float64{90.0}
}
type MetricAggregatorStats struct {
// metricAggregatorStats is a bookkeeping structure for statistics about a MetricAggregator
type metricAggregatorStats struct {
BadLines int
LastMessage time.Time
GraphiteLastFlush time.Time
GraphiteLastError time.Time
}
func thresholdStats(vals []float64, threshold float64) (mean, upper float64) {
if count := len(vals); count > 1 {
idx := int(round(((100 - threshold) / 100) * float64(count)))
thresholdCount := count - idx
thresholdValues := vals[:thresholdCount]
mean = average(thresholdValues)
upper = thresholdValues[len(thresholdValues)-1]
} else {
mean = vals[0]
upper = vals[0]
}
return mean, upper
}
// MetricSender is an interface that can be implemented by objects which
// could be connected to a MetricAggregator
type MetricSender interface {
SendMetrics(MetricMap) error
}
// MetricAggregator is an object that aggregates statsd metrics.
// The function NewMetricAggregator should be used to create the objects.
//
// Incoming metrics should be sent to the MetricChan channel.
type MetricAggregator struct {
sync.Mutex
MetricChan chan Metric // Channel on which metrics are received
FlushInterval time.Duration // How often to flush metrics to the sender
Sender MetricSender
stats MetricAggregatorStats
Sender MetricSender // The sender to which metrics are flushed
stats metricAggregatorStats
counters MetricMap
gauges MetricMap
timers MetricListMap
}
// NewMetricAggregator creates a new MetricAggregator object
func NewMetricAggregator(sender MetricSender, flushInterval time.Duration) (a MetricAggregator) {
a = MetricAggregator{}
a.FlushInterval = flushInterval
......@@ -59,6 +52,7 @@ func NewMetricAggregator(sender MetricSender, flushInterval time.Duration) (a Me
return
}
// flush prepares the contents of a MetricAggregator for sending via the Sender
func (m *MetricAggregator) flush() (metrics MetricMap) {
metrics = make(MetricMap)
numStats := 0
......@@ -98,6 +92,7 @@ func (m *MetricAggregator) flush() (metrics MetricMap) {
return metrics
}
// Reset clears the contents of a MetricAggregator
func (a *MetricAggregator) Reset() {
// Reset counters
new_counters := make(MetricMap)
......@@ -121,6 +116,7 @@ func (a *MetricAggregator) Reset() {
a.gauges = new_gauges
}
// receiveMetric is called for each incoming metric on MetricChan
func (a *MetricAggregator) receiveMetric(m Metric) {
defer a.Unlock()
a.Lock()
......@@ -149,6 +145,8 @@ func (a *MetricAggregator) receiveMetric(m Metric) {
a.stats.LastMessage = time.Now()
}
// Aggregate starts the MetricAggregator so it begins consuming metrics from MetricChan
// and flushing them periodically via its Sender
func (m *MetricAggregator) Aggregate() {
m.counters = make(MetricMap)
m.gauges = make(MetricMap)
......
......@@ -7,23 +7,19 @@ import (
"time"
)
// Normalize a bucket name by replacing or translating invalid characters
// normalizeBucketName cleans up a bucket name by replacing or translating invalid characters
func normalizeBucketName(name string) string {
nospaces := regSpaces.ReplaceAllString(name, "_")
noslashes := regSlashes.ReplaceAllString(nospaces, "-")
return regInvalid.ReplaceAllString(noslashes, "")
}
// GraphiteClient is an object that is used to send messages to a Graphite server's UDP interface
type GraphiteClient struct {
conn *net.Conn
}
func NewGraphiteClient(addr string) (client GraphiteClient, err error) {
conn, err := net.Dial("tcp", addr)
client = GraphiteClient{&conn}
return
}
// SendMetrics sends the metrics in a MetricsMap to the Graphite server
func (client *GraphiteClient) SendMetrics(metrics MetricMap) (err error) {
buf := new(bytes.Buffer)
now := time.Now().Unix()
......@@ -37,3 +33,10 @@ func (client *GraphiteClient) SendMetrics(metrics MetricMap) (err error) {
}
return nil
}
// NewGraphiteClient constructs a GraphiteClient object by connecting to an address
func NewGraphiteClient(addr string) (client GraphiteClient, err error) {
conn, err := net.Dial("tcp", addr)
client = GraphiteClient{&conn}
return
}
......@@ -73,6 +73,7 @@ func (srv *MetricReceiver) handleMessage(msg []byte) {
}
}
// parseMessage parses a message string string in to a list of metrics
func parseMessage(msg string) ([]Metric, error) {
metricList := []Metric{}
......
......@@ -4,10 +4,12 @@ import (
"math"
)
// round rounds a number to its nearest integer value
func round(v float64) float64 {
return math.Floor(v + 0.5)
}
// average computes the average (mean) of a list of numbers
func average(vals []float64) float64 {
sum := 0.0
for _, v := range vals {
......@@ -15,3 +17,19 @@ func average(vals []float64) float64 {
}
return sum / float64(len(vals))
}
// thresholdStats calculates the mean and upper values of a list of values after a applying a minimum threshold
func thresholdStats(vals []float64, threshold float64) (mean, upper float64) {
if count := len(vals); count > 1 {
idx := int(round(((100 - threshold) / 100) * float64(count)))
thresholdCount := count - idx
thresholdValues := vals[:thresholdCount]
mean = average(thresholdValues)
upper = thresholdValues[len(thresholdValues)-1]
} else {
mean = vals[0]
upper = vals[0]
}
return mean, upper
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment