From 0d5e5a2fbede19338e77d2d5e903dfe927d4d2ce Mon Sep 17 00:00:00 2001 From: Anton Novojilov Date: Wed, 23 Dec 2015 00:04:35 +0100 Subject: [PATCH] Added collector feature + Added changelog --- changelog.md | 10 +++++++ librato.go | 80 ++++++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 81 insertions(+), 9 deletions(-) create mode 100644 changelog.md diff --git a/changelog.md b/changelog.md new file mode 100644 index 0000000..7029f5d --- /dev/null +++ b/changelog.md @@ -0,0 +1,10 @@ +## Changelog + +#### v1.1 + +* Added `Collector` for collecting metrics for some period +* Some minor improvements + +#### v1 + +Initial public release diff --git a/librato.go b/librato.go index b91b7af..74283d4 100644 --- a/librato.go +++ b/librato.go @@ -22,7 +22,8 @@ import ( // ////////////////////////////////////////////////////////////////////////////////// // -const VERSION = "1.0" +// VERSION contains current version of librato package and used as part of User-Agent +const VERSION = "1.1" // ////////////////////////////////////////////////////////////////////////////////// // @@ -54,6 +55,16 @@ type Metrics struct { ErrorHandler func(errs []error) } +// Collector struct +type Collector struct { + period time.Duration + lastSendingDate int64 + collectFunc func() []Measurement + + // Function executed if we have errors while sending data to Librato + ErrorHandler func(errs []error) +} + // Gauge struct type Gauge struct { @@ -251,6 +262,24 @@ func NewMetrics(period time.Duration, maxQueueSize int) (*Metrics, error) { return metrics, nil } +// NewCollector create new metrics struct for async metrics collecting and sending +func NewCollector(period time.Duration, collectFunc func() []Measurement) *Collector { + collector := &Collector{ + period: period, + lastSendingDate: -1, + collectFunc: collectFunc, + } + + if sources == nil { + sources = make([]DataSource, 0) + go sendingLoop() + } + + sources = append(sources, collector) + + return collector +} + // AddMetric synchronously send metric to librato func AddMetric(m Measurement) []error { err := m.Validate() @@ -343,7 +372,30 @@ func (mt *Metrics) Send() []error { mt.lastSendingDate = time.Now().Unix() - return mt.sendData() + data := convertMeasurementSlice(mt.queue) + + mt.queue = make([]Measurement, 0) + + return execRequest(req.POST, APIEndpoint+"/v1/metrics/", data) +} + +// Send sends metrics data to Librato service +func (cl *Collector) Send() []error { + if Mail == "" || Token == "" { + return []error{errors.New("Access credentials is not set")} + } + + ms := cl.collectFunc() + + if ms == nil || len(ms) == 0 { + return []error{} + } + + cl.lastSendingDate = time.Now().Unix() + + data := convertMeasurementSlice(ms) + + return execRequest(req.POST, APIEndpoint+"/v1/metrics/", data) } // ////////////////////////////////////////////////////////////////////////////////// // @@ -379,13 +431,23 @@ func (mt *Metrics) execErrorHandler(errs []error) { mt.ErrorHandler(errs) } -// sendData send json encoded metrics data to Librato service -func (mt *Metrics) sendData() []error { - data := convertQueue(mt.queue) +// getPeriod return sending period +func (cl *Collector) getPeriod() time.Duration { + return cl.period +} - mt.queue = make([]Measurement, 0) +// getLastSendingDate return last sending date +func (cl *Collector) getLastSendingDate() int64 { + return cl.lastSendingDate +} - return execRequest(req.POST, APIEndpoint+"/v1/metrics/", data) +// execErrorHandler exec error handler if present +func (cl *Collector) execErrorHandler(errs []error) { + if cl.ErrorHandler == nil { + return + } + + cl.ErrorHandler(errs) } // ////////////////////////////////////////////////////////////////////////////////// // @@ -428,9 +490,9 @@ func sendingLoop() { } } -// convertQueue convert slice with measurements to struct +// convertMeasurementSlice convert slice with measurements to struct // with counters and gauges slices -func convertQueue(queue []Measurement) *mesData { +func convertMeasurementSlice(queue []Measurement) *mesData { result := &mesData{} now := time.Now().Unix()