Skip to content

Commit 3da4cbd

Browse files
committed
Add missing labals
1 parent f49ceb0 commit 3da4cbd

File tree

3 files changed

+239
-234
lines changed

3 files changed

+239
-234
lines changed

collectors/monitoring_collector.go

Lines changed: 4 additions & 233 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import (
1313
"google.golang.org/api/monitoring/v3"
1414

1515
"github.com/frodenas/stackdriver_exporter/utils"
16-
"sort"
1716
)
1817

1918
type MonitoringCollector struct {
@@ -28,6 +27,7 @@ type MonitoringCollector struct {
2827
lastScrapeErrorMetric prometheus.Gauge
2928
lastScrapeTimestampMetric prometheus.Gauge
3029
lastScrapeDurationSecondsMetric prometheus.Gauge
30+
collectorFillMissingLabels bool
3131
}
3232

3333
func NewMonitoringCollector(
@@ -36,6 +36,7 @@ func NewMonitoringCollector(
3636
metricsInterval time.Duration,
3737
metricsOffset time.Duration,
3838
monitoringService *monitoring.Service,
39+
collectorFillMissingLabels bool,
3940
) (*MonitoringCollector, error) {
4041
apiCallsTotalMetric := prometheus.NewCounter(
4142
prometheus.CounterOpts{
@@ -109,6 +110,7 @@ func NewMonitoringCollector(
109110
lastScrapeErrorMetric: lastScrapeErrorMetric,
110111
lastScrapeTimestampMetric: lastScrapeTimestampMetric,
111112
lastScrapeDurationSecondsMetric: lastScrapeDurationSecondsMetric,
113+
collectorFillMissingLabels: collectorFillMissingLabels,
112114
}
113115

114116
return monitoringCollector, nil
@@ -236,7 +238,7 @@ func (c *MonitoringCollector) reportTimeSeriesMetrics(
236238
timeSeriesMetrics := &TimeSeriesMetrics{
237239
metricDescriptor: metricDescriptor,
238240
ch: ch,
239-
fillMissingLabels: true, //TODO: this can be configurable
241+
fillMissingLabels: c.collectorFillMissingLabels,
240242
constMetrics: make(map[string][]ConstMetric),
241243
histogramMetrics: make(map[string][]HistogramMetric),
242244
}
@@ -362,234 +364,3 @@ func (c *MonitoringCollector) generateHistogramBuckets(
362364
}
363365
return buckets, nil
364366
}
365-
366-
func buildFQName(timeSeries *monitoring.TimeSeries) string {
367-
// The metric name to report is composed by the 3 parts:
368-
// 1. namespace is a constant prefix (stackdriver)
369-
// 2. subsystem is the monitored resource type (ie gce_instance)
370-
// 3. name is the metric type (ie compute.googleapis.com/instance/cpu/usage_time)
371-
return prometheus.BuildFQName("stackdriver", utils.NormalizeMetricName(timeSeries.Resource.Type), utils.NormalizeMetricName(timeSeries.Metric.Type))
372-
}
373-
374-
type TimeSeriesMetrics struct {
375-
metricDescriptor *monitoring.MetricDescriptor
376-
ch chan<- prometheus.Metric
377-
378-
fillMissingLabels bool
379-
constMetrics map[string][]ConstMetric
380-
histogramMetrics map[string][]HistogramMetric
381-
}
382-
383-
func (t *TimeSeriesMetrics) NewMetricDesc(fqName string, labelKeys []string) *prometheus.Desc {
384-
return prometheus.NewDesc(
385-
fqName,
386-
t.metricDescriptor.Description,
387-
labelKeys,
388-
prometheus.Labels{},
389-
)
390-
}
391-
392-
type ConstMetric struct {
393-
fqName string
394-
labelKeys []string
395-
valueType prometheus.ValueType
396-
value float64
397-
labelValues []string
398-
399-
keysHash uint64
400-
}
401-
402-
type HistogramMetric struct {
403-
fqName string
404-
labelKeys []string
405-
dist *monitoring.Distribution
406-
buckets map[float64]uint64
407-
labelValues []string
408-
409-
keysHash uint64
410-
}
411-
412-
func (t *TimeSeriesMetrics) CollectNewConstHistogram(timeSeries *monitoring.TimeSeries, labelKeys []string, dist *monitoring.Distribution, buckets map[float64]uint64, labelValues []string) {
413-
fqName := buildFQName(timeSeries)
414-
415-
if t.fillMissingLabels {
416-
vs, ok := t.histogramMetrics[fqName]
417-
if !ok {
418-
vs = make([]HistogramMetric, 0)
419-
}
420-
v := HistogramMetric{
421-
fqName: fqName,
422-
labelKeys: labelKeys,
423-
dist: dist,
424-
buckets: buckets,
425-
labelValues: labelValues,
426-
427-
keysHash: hashLabelKeys(labelKeys),
428-
}
429-
t.histogramMetrics[fqName] = append(vs, v)
430-
return
431-
}
432-
433-
metric := prometheus.MustNewConstHistogram(
434-
t.NewMetricDesc(fqName, labelKeys),
435-
uint64(dist.Count),
436-
dist.Mean*float64(dist.Count), // Stackdriver does not provide the sum, but we can fake it
437-
buckets,
438-
labelValues...,
439-
)
440-
t.ch <- metric
441-
}
442-
443-
func (t *TimeSeriesMetrics) CollectNewConstMetric(timeSeries *monitoring.TimeSeries, labelKeys []string, metricValueType prometheus.ValueType, metricValue float64, labelValues []string) {
444-
fqName := buildFQName(timeSeries)
445-
446-
if t.fillMissingLabels {
447-
vs, ok := t.constMetrics[fqName]
448-
if !ok {
449-
vs = make([]ConstMetric, 0)
450-
}
451-
v := ConstMetric{
452-
fqName: fqName,
453-
labelKeys: labelKeys,
454-
valueType: metricValueType,
455-
value: metricValue,
456-
labelValues: labelValues,
457-
458-
keysHash: hashLabelKeys(labelKeys),
459-
}
460-
t.constMetrics[fqName] = append(vs, v)
461-
return
462-
}
463-
464-
metric := prometheus.MustNewConstMetric(
465-
t.NewMetricDesc(fqName, labelKeys),
466-
metricValueType,
467-
metricValue,
468-
labelValues...,
469-
)
470-
t.ch <- metric
471-
}
472-
473-
func hashLabelKeys(labelKeys []string) uint64 {
474-
dh := hashNew()
475-
sortedKeys := make([]string, len(labelKeys))
476-
copy(sortedKeys, labelKeys)
477-
sort.Strings(sortedKeys)
478-
for _, key := range sortedKeys {
479-
dh = hashAdd(dh, key)
480-
dh = hashAddByte(dh, separatorByte)
481-
}
482-
return dh
483-
}
484-
485-
func (t *TimeSeriesMetrics) Complete() {
486-
t.CompleteConstMetrics()
487-
t.CompleteHistogramMetrics()
488-
}
489-
490-
func (t *TimeSeriesMetrics) CompleteConstMetrics() {
491-
for _, vs := range t.constMetrics {
492-
if len(vs) > 1 {
493-
var needFill bool
494-
for i := 1; i < len(vs); i++ {
495-
if vs[0].keysHash != vs[i].keysHash {
496-
needFill = true
497-
}
498-
}
499-
if needFill {
500-
vs = fillConstMetricsLabels(vs)
501-
}
502-
}
503-
504-
for _, v := range vs {
505-
metric := prometheus.MustNewConstMetric(
506-
t.NewMetricDesc(v.fqName, v.labelKeys),
507-
v.valueType,
508-
v.value,
509-
v.labelValues...,
510-
)
511-
t.ch <- metric
512-
}
513-
}
514-
}
515-
516-
func (t *TimeSeriesMetrics) CompleteHistogramMetrics() {
517-
for _, vs := range t.histogramMetrics {
518-
if len(vs) > 1 {
519-
var needFill bool
520-
for i := 1; i < len(vs); i++ {
521-
if vs[0].keysHash != vs[i].keysHash {
522-
needFill = true
523-
}
524-
}
525-
if needFill {
526-
vs = fillHistogramMetricsLabels(vs)
527-
}
528-
}
529-
530-
for _, v := range vs {
531-
metric := prometheus.MustNewConstHistogram(
532-
t.NewMetricDesc(v.fqName, v.labelKeys),
533-
uint64(v.dist.Count),
534-
v.dist.Mean*float64(v.dist.Count), // Stackdriver does not provide the sum, but we can fake it
535-
v.buckets,
536-
v.labelValues...,
537-
)
538-
t.ch <- metric
539-
}
540-
}
541-
}
542-
543-
func fillConstMetricsLabels(metrics []ConstMetric) []ConstMetric {
544-
allKeys := make(map[string]struct{})
545-
for _, metric := range metrics {
546-
for _, key := range metric.labelKeys {
547-
allKeys[key] = struct{}{}
548-
}
549-
}
550-
result := make([]ConstMetric, len(metrics))
551-
for i, metric := range metrics {
552-
if len(metric.labelKeys) != len(allKeys) {
553-
metricKeys := make(map[string]struct{})
554-
for _, key := range metric.labelKeys {
555-
metricKeys[key] = struct{}{}
556-
}
557-
for key := range allKeys {
558-
if _, ok := metricKeys[key]; !ok {
559-
metric.labelKeys = append(metric.labelKeys, key)
560-
metric.labelValues = append(metric.labelValues, "")
561-
}
562-
}
563-
}
564-
result[i] = metric
565-
}
566-
567-
return result
568-
}
569-
570-
func fillHistogramMetricsLabels(metrics []HistogramMetric) []HistogramMetric {
571-
allKeys := make(map[string]struct{})
572-
for _, metric := range metrics {
573-
for _, key := range metric.labelKeys {
574-
allKeys[key] = struct{}{}
575-
}
576-
}
577-
result := make([]HistogramMetric, len(metrics))
578-
for i, metric := range metrics {
579-
if len(metric.labelKeys) != len(allKeys) {
580-
metricKeys := make(map[string]struct{})
581-
for _, key := range metric.labelKeys {
582-
metricKeys[key] = struct{}{}
583-
}
584-
for key := range allKeys {
585-
if _, ok := metricKeys[key]; !ok {
586-
metric.labelKeys = append(metric.labelKeys, key)
587-
metric.labelValues = append(metric.labelValues, "")
588-
}
589-
}
590-
}
591-
result[i] = metric
592-
}
593-
594-
return result
595-
}

0 commit comments

Comments
 (0)