Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support setting timestamp on metric #20

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ Application Options:
--azure.servicediscovery.cache= Duration for caching Azure ServiceDiscovery of workspaces to reduce API
calls (time.Duration) (default: 30m) [$AZURE_SERVICEDISCOVERY_CACHE]
--metrics.resourceid.lowercase Publish lowercase Azure Resoruce ID in metrics [$METRIC_RESOURCEID_LOWERCASE]
--metrics.set-timestamp Set timestamp on scraped metrics [$METRIC_SET_TIMESTAMP]
--metrics.template= Template for metric name (default: {name}) [$METRIC_TEMPLATE]
--metrics.help= Metric help (with template support) (default: Azure monitor insight metric)
[$METRIC_HELP]
Expand Down
1 change: 1 addition & 0 deletions config/opts.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ type (

Metrics struct {
ResourceIdLowercase bool `long:"metrics.resourceid.lowercase" env:"METRIC_RESOURCEID_LOWERCASE" description:"Publish lowercase Azure Resoruce ID in metrics"`
SetTimestamp bool `long:"metrics.set-timestamp" env:"METRIC_SET_TIMESTAMP" description:"Set timestamp on scraped metrics"`
Template string `long:"metrics.template" env:"METRIC_TEMPLATE" description:"Template for metric name" default:"{name}"`
Help string `long:"metrics.help" env:"METRIC_HELP" description:"Metric help (with template support)" default:"Azure monitor insight metric"`
}
Expand Down
5 changes: 4 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,10 @@ require (
google.golang.org/protobuf v1.27.1 // indirect
)

require github.com/webdevops/go-prometheus-common v0.0.0-20220214222004-cea8f38b44b7
require (
github.com/google/go-cmp v0.5.5
github.com/webdevops/go-prometheus-common v0.0.0-20220214222004-cea8f38b44b7
)

require (
github.com/Azure/go-autorest v14.2.0+incompatible // indirect
Expand Down
68 changes: 68 additions & 0 deletions metrics/collector.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package metrics

import (
"time"

"github.com/prometheus/client_golang/prometheus"
)

type metricListCollectorDetails struct {
gauge prometheus.Gauge
desc *prometheus.Desc
ts time.Time
}

type metricListCollector struct {
details []*metricListCollectorDetails
}

func NewMetricListCollector(list *MetricList) *metricListCollector {
collector := &metricListCollector{
details: []*metricListCollectorDetails{},
}

if list == nil {
return collector
}

// create prometheus metrics and set rows
for _, metricName := range list.GetMetricNames() {
gaugeVec := prometheus.NewGaugeVec(
prometheus.GaugeOpts{
Name: metricName,
Help: list.GetMetricHelp(metricName),
},
list.GetMetricLabelNames(metricName),
)

for _, metric := range list.GetUniqueMetricList(metricName) {
gauge := gaugeVec.With(metric.Labels)
gauge.Set(metric.Value)

desc := prometheus.NewDesc(metricName, list.GetMetricHelp(metricName), []string{}, metric.Labels)

details := &metricListCollectorDetails{
gauge,
desc,
metric.Timestamp,
}

collector.details = append(collector.details, details)
}
}

return collector
}

func (c *metricListCollector) Describe(ch chan<- *prometheus.Desc) {
for _, detail := range c.details {
ch <- detail.desc
}
}

func (c *metricListCollector) Collect(ch chan<- prometheus.Metric) {
for _, detail := range c.details {
s := prometheus.NewMetricWithTimestamp(detail.ts, detail.gauge)
ch <- s
}
}
33 changes: 21 additions & 12 deletions metrics/insights.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
package metrics

import (
"regexp"
"strings"
"time"

"github.com/Azure/azure-sdk-for-go/services/preview/monitor/mgmt/2018-03-01/insights"
"github.com/Azure/go-autorest/autorest/azure"
"github.com/Azure/go-autorest/autorest/to"
"github.com/prometheus/client_golang/prometheus"
"regexp"
"strings"
)

var (
Expand All @@ -26,10 +28,11 @@ type (
}

PrometheusMetricResult struct {
Name string
Labels prometheus.Labels
Value float64
Help string
Name string
Labels prometheus.Labels
Value float64
Timestamp time.Time
Help string
}
)

Expand Down Expand Up @@ -70,17 +73,18 @@ func (p *MetricProber) FetchMetricsFromTarget(client *insights.MetricsClient, ta
return ret, err
}

func (r *AzureInsightMetricsResult) buildMetric(labels prometheus.Labels, value float64) (metric PrometheusMetricResult) {
func (r *AzureInsightMetricsResult) buildMetric(labels prometheus.Labels, value float64, timestamp time.Time) (metric PrometheusMetricResult) {
// copy map to ensure we don't keep references
metricLabels := prometheus.Labels{}
for labelName, labelValue := range labels {
metricLabels[labelName] = labelValue
}

metric = PrometheusMetricResult{
Name: r.settings.MetricTemplate,
Labels: metricLabels,
Value: value,
Name: r.settings.MetricTemplate,
Labels: metricLabels,
Value: value,
Timestamp: timestamp,
}

// fallback if template is empty (should not be)
Expand Down Expand Up @@ -140,8 +144,8 @@ func (r *AzureInsightMetricsResult) buildMetric(labels prometheus.Labels, value
func (r *AzureInsightMetricsResult) SendMetricToChannel(channel chan<- PrometheusMetricResult) {
if r.Result.Value != nil {
// DEBUGGING
//data, _ := json.Marshal(r.Result)
//fmt.Println(string(data))
// data, _ := json.Marshal(r.Result)
// fmt.Println(string(data))

for _, metric := range *r.Result.Value {
if metric.Timeseries != nil {
Expand Down Expand Up @@ -203,6 +207,7 @@ func (r *AzureInsightMetricsResult) SendMetricToChannel(channel chan<- Prometheu
channel <- r.buildMetric(
metricLabels,
*timeseriesData.Total,
timeseriesData.TimeStamp.Time,
)
}

Expand All @@ -211,6 +216,7 @@ func (r *AzureInsightMetricsResult) SendMetricToChannel(channel chan<- Prometheu
channel <- r.buildMetric(
metricLabels,
*timeseriesData.Minimum,
timeseriesData.TimeStamp.Time,
)
}

Expand All @@ -219,6 +225,7 @@ func (r *AzureInsightMetricsResult) SendMetricToChannel(channel chan<- Prometheu
channel <- r.buildMetric(
metricLabels,
*timeseriesData.Maximum,
timeseriesData.TimeStamp.Time,
)
}

Expand All @@ -227,6 +234,7 @@ func (r *AzureInsightMetricsResult) SendMetricToChannel(channel chan<- Prometheu
channel <- r.buildMetric(
metricLabels,
*timeseriesData.Average,
timeseriesData.TimeStamp.Time,
)
}

Expand All @@ -235,6 +243,7 @@ func (r *AzureInsightMetricsResult) SendMetricToChannel(channel chan<- Prometheu
channel <- r.buildMetric(
metricLabels,
*timeseriesData.Count,
timeseriesData.TimeStamp.Time,
)
}
}
Expand Down
36 changes: 33 additions & 3 deletions metrics/metrics.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
package metrics

import "github.com/prometheus/client_golang/prometheus"
import (
"time"

"github.com/google/go-cmp/cmp"
"github.com/prometheus/client_golang/prometheus"
)

const (
MetricHelpDefault = "Azure monitor insight metric"
Expand All @@ -13,8 +18,9 @@ type (
}

MetricRow struct {
Labels prometheus.Labels
Value float64
Labels prometheus.Labels
Value float64
Timestamp time.Time
}
)

Expand Down Expand Up @@ -55,6 +61,30 @@ func (l *MetricList) GetMetricList(name string) []MetricRow {
return l.List[name]
}

func (l *MetricList) GetUniqueMetricList(name string) []MetricRow {
rows := []MetricRow{}

for _, row := range l.List[name] {
existed := false

for idx, existedRow := range rows {
if cmp.Equal(row.Labels, existedRow.Labels) {
existed = true

if row.Timestamp.After(existedRow.Timestamp) {
rows[idx] = row
}
}
}

if !existed {
rows = append(rows, row)
}
}

return rows
}

func (l *MetricList) GetMetricLabelNames(name string) []string {
var list []string
uniqueLabelMap := map[string]string{}
Expand Down
10 changes: 8 additions & 2 deletions metrics/prober.go
Original file line number Diff line number Diff line change
Expand Up @@ -211,15 +211,21 @@ func (p *MetricProber) collectMetricsFromTargets() {

for result := range metricsChannel {
metric := MetricRow{
Labels: result.Labels,
Value: result.Value,
Labels: result.Labels,
Value: result.Value,
Timestamp: result.Timestamp,
}
p.metricList.Add(result.Name, metric)
p.metricList.SetMetricHelp(result.Name, result.Help)
}
}

func (p *MetricProber) publishMetricList() {
if p.Conf.Metrics.SetTimestamp {
p.prometheus.registry.MustRegister(NewMetricListCollector(p.metricList))
return
}

if p.metricList == nil {
return
}
Expand Down