0 | 0 |
package cloudwatch
|
1 | 1 |
|
2 | 2 |
import (
|
|
3 |
"fmt"
|
3 | 4 |
"sync"
|
4 | |
|
5 | 5 |
"time"
|
6 | |
|
7 | |
"fmt"
|
8 | 6 |
|
9 | 7 |
"github.com/aws/aws-sdk-go/aws"
|
10 | 8 |
"github.com/aws/aws-sdk-go/service/cloudwatch"
|
11 | 9 |
"github.com/aws/aws-sdk-go/service/cloudwatch/cloudwatchiface"
|
|
10 |
|
12 | 11 |
"github.com/go-kit/kit/log"
|
13 | 12 |
"github.com/go-kit/kit/metrics"
|
14 | 13 |
"github.com/go-kit/kit/metrics/generic"
|
|
23 | 22 |
mtx sync.RWMutex
|
24 | 23 |
namespace string
|
25 | 24 |
svc cloudwatchiface.CloudWatchAPI
|
26 | |
counters map[string]*Counter
|
27 | |
gauges map[string]*Gauge
|
28 | |
histograms map[string]*Histogram
|
|
25 |
counters map[string]*counter
|
|
26 |
gauges map[string]*gauge
|
|
27 |
histograms map[string]*histogram
|
29 | 28 |
logger log.Logger
|
30 | 29 |
}
|
31 | 30 |
|
32 | 31 |
// New returns a CloudWatch object that may be used to create metrics. Namespace is
|
33 | 32 |
// applied to all created metrics and maps to the CloudWatch namespace.
|
34 | 33 |
// Callers must ensure that regular calls to Send are performed, either manually or with one of the helper methods.
|
35 | |
func New(namespace string, logger log.Logger, svc cloudwatchiface.CloudWatchAPI) *CloudWatch {
|
|
34 |
func New(namespace string, svc cloudwatchiface.CloudWatchAPI, logger log.Logger) *CloudWatch {
|
36 | 35 |
return &CloudWatch{
|
37 | 36 |
namespace: namespace,
|
38 | 37 |
svc: svc,
|
39 | |
counters: map[string]*Counter{},
|
40 | |
gauges: map[string]*Gauge{},
|
41 | |
histograms: map[string]*Histogram{},
|
|
38 |
counters: map[string]*counter{},
|
|
39 |
gauges: map[string]*gauge{},
|
|
40 |
histograms: map[string]*histogram{},
|
42 | 41 |
logger: logger,
|
43 | 42 |
}
|
44 | 43 |
}
|
45 | 44 |
|
46 | 45 |
// NewCounter returns a counter. Observations are aggregated and emitted once
|
47 | 46 |
// per write invocation.
|
48 | |
func (cw *CloudWatch) NewCounter(name string) *Counter {
|
49 | |
c := NewCounter(name)
|
|
47 |
func (cw *CloudWatch) NewCounter(name string) metrics.Counter {
|
50 | 48 |
cw.mtx.Lock()
|
|
49 |
defer cw.mtx.Unlock()
|
|
50 |
c := &counter{c: generic.NewCounter(name)}
|
51 | 51 |
cw.counters[name] = c
|
52 | |
cw.mtx.Unlock()
|
53 | 52 |
return c
|
54 | 53 |
}
|
55 | 54 |
|
56 | 55 |
// NewGauge returns a gauge. Observations are aggregated and emitted once per
|
57 | 56 |
// write invocation.
|
58 | |
func (cw *CloudWatch) NewGauge(name string) *Gauge {
|
59 | |
g := NewGauge(name)
|
|
57 |
func (cw *CloudWatch) NewGauge(name string) metrics.Gauge {
|
60 | 58 |
cw.mtx.Lock()
|
|
59 |
defer cw.mtx.Unlock()
|
|
60 |
g := &gauge{g: generic.NewGauge(name)}
|
61 | 61 |
cw.gauges[name] = g
|
62 | |
cw.mtx.Unlock()
|
63 | 62 |
return g
|
64 | 63 |
}
|
65 | 64 |
|
66 | 65 |
// NewHistogram returns a histogram. Observations are aggregated and emitted as
|
67 | 66 |
// per-quantile gauges, once per write invocation. 50 is a good default value
|
68 | 67 |
// for buckets.
|
69 | |
func (cw *CloudWatch) NewHistogram(name string, buckets int) *Histogram {
|
70 | |
h := NewHistogram(name, buckets)
|
|
68 |
func (cw *CloudWatch) NewHistogram(name string, buckets int) metrics.Histogram {
|
71 | 69 |
cw.mtx.Lock()
|
|
70 |
defer cw.mtx.Unlock()
|
|
71 |
h := &histogram{h: generic.NewHistogram(name, buckets)}
|
72 | 72 |
cw.histograms[name] = h
|
73 | |
cw.mtx.Unlock()
|
74 | 73 |
return h
|
75 | 74 |
}
|
76 | 75 |
|
|
86 | 85 |
}
|
87 | 86 |
}
|
88 | 87 |
|
89 | |
// Send will fire an api request to CloudWatch with the latest stats for
|
90 | |
// all metrics.
|
|
88 |
// Send will fire an API request to CloudWatch with the latest stats for
|
|
89 |
// all metrics. It is preferred that the WriteLoop method is used.
|
91 | 90 |
func (cw *CloudWatch) Send() error {
|
92 | 91 |
cw.mtx.RLock()
|
93 | 92 |
defer cw.mtx.RUnlock()
|
94 | 93 |
now := time.Now()
|
95 | 94 |
|
96 | |
datums := []*cloudwatch.MetricDatum{}
|
|
95 |
var datums []*cloudwatch.MetricDatum
|
97 | 96 |
|
98 | 97 |
for name, c := range cw.counters {
|
99 | 98 |
datums = append(datums, &cloudwatch.MetricDatum{
|
|
139 | 138 |
return err
|
140 | 139 |
}
|
141 | 140 |
|
142 | |
// Counter is a CloudWatch counter metric.
|
143 | |
type Counter struct {
|
|
141 |
// counter is a CloudWatch counter metric.
|
|
142 |
type counter struct {
|
144 | 143 |
c *generic.Counter
|
145 | 144 |
}
|
146 | 145 |
|
147 | |
// NewCounter returns a new usable counter metric.
|
148 | |
func NewCounter(name string) *Counter {
|
149 | |
return &Counter{
|
150 | |
c: generic.NewCounter(name),
|
151 | |
}
|
152 | |
}
|
153 | |
|
154 | 146 |
// With implements counter
|
155 | |
func (c *Counter) With(labelValues ...string) metrics.Counter {
|
|
147 |
func (c *counter) With(labelValues ...string) metrics.Counter {
|
156 | 148 |
c.c = c.c.With(labelValues...).(*generic.Counter)
|
157 | 149 |
return c
|
158 | 150 |
}
|
159 | 151 |
|
160 | 152 |
// Add implements counter.
|
161 | |
func (c *Counter) Add(delta float64) {
|
|
153 |
func (c *counter) Add(delta float64) {
|
162 | 154 |
c.c.Add(delta)
|
163 | 155 |
}
|
164 | 156 |
|
165 | |
// Gauge is a CloudWatch gauge metric.
|
166 | |
type Gauge struct {
|
|
157 |
// gauge is a CloudWatch gauge metric.
|
|
158 |
type gauge struct {
|
167 | 159 |
g *generic.Gauge
|
168 | 160 |
}
|
169 | 161 |
|
170 | |
// NewGauge returns a new usable gauge metric
|
171 | |
func NewGauge(name string) *Gauge {
|
172 | |
return &Gauge{
|
173 | |
g: generic.NewGauge(name),
|
174 | |
}
|
175 | |
}
|
176 | |
|
177 | 162 |
// With implements gauge
|
178 | |
func (g *Gauge) With(labelValues ...string) metrics.Gauge {
|
|
163 |
func (g *gauge) With(labelValues ...string) metrics.Gauge {
|
179 | 164 |
g.g = g.g.With(labelValues...).(*generic.Gauge)
|
180 | 165 |
return g
|
181 | 166 |
}
|
182 | 167 |
|
183 | 168 |
// Set implements gauge
|
184 | |
func (g *Gauge) Set(value float64) {
|
|
169 |
func (g *gauge) Set(value float64) {
|
185 | 170 |
g.g.Set(value)
|
186 | 171 |
}
|
187 | 172 |
|
188 | 173 |
// Add implements gauge
|
189 | |
func (g *Gauge) Add(delta float64) {
|
|
174 |
func (g *gauge) Add(delta float64) {
|
190 | 175 |
g.g.Add(delta)
|
191 | 176 |
}
|
192 | 177 |
|
193 | |
// Histogram is a CloudWatch histogram metric
|
194 | |
type Histogram struct {
|
|
178 |
// histogram is a CloudWatch histogram metric
|
|
179 |
type histogram struct {
|
195 | 180 |
h *generic.Histogram
|
196 | 181 |
}
|
197 | 182 |
|
198 | |
// NewHistogram returns a new usable histogram metric
|
199 | |
func NewHistogram(name string, buckets int) *Histogram {
|
200 | |
return &Histogram{
|
201 | |
h: generic.NewHistogram(name, buckets),
|
202 | |
}
|
203 | |
}
|
204 | |
|
205 | 183 |
// With implements histogram
|
206 | |
func (h *Histogram) With(labelValues ...string) metrics.Histogram {
|
|
184 |
func (h *histogram) With(labelValues ...string) metrics.Histogram {
|
207 | 185 |
h.h = h.h.With(labelValues...).(*generic.Histogram)
|
208 | 186 |
return h
|
209 | 187 |
}
|
210 | 188 |
|
211 | 189 |
// Observe implements histogram
|
212 | |
func (h *Histogram) Observe(value float64) {
|
|
190 |
func (h *histogram) Observe(value float64) {
|
213 | 191 |
h.h.Observe(value)
|
214 | 192 |
}
|
215 | 193 |
|