Skip to content

add telemetry #144

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

Merged
merged 22 commits into from
Mar 26, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
7056a23
feat: add metrics file support and telemetry tracking for lint rule e…
juev Mar 7, 2025
09d957b
feat: update README and add metrics printing for linting results
juev Mar 7, 2025
289a031
refactor: remove metrics file handling from flags and manager
juev Mar 25, 2025
e592b17
feat: refactor metrics handling to use singleton pattern and improve …
juev Mar 25, 2025
683b47a
fix: remove unnecessary newline in error handling in service.go
juev Mar 25, 2025
cd2d273
feat: enhance metrics handling for linter warnings and refactor relat…
juev Mar 25, 2025
0a673ec
fix: optimize error handling in GetLinterWarningsCountLabels and clea…
juev Mar 25, 2025
8a13e8c
fix: filter out non-warning errors in error processing logic
juev Mar 25, 2025
5451019
feat: move linter warning metrics increment to dedicated processing f…
juev Mar 25, 2025
3c25629
feat: invoke dedicated processing for linter warnings count metrics
juev Mar 25, 2025
59c8d07
feat: add linter warnings metrics collection and processing logic
juev Mar 25, 2025
8af65bb
Update cmd/dmt/main.go
juev Mar 25, 2025
23335b7
chore: remove unused slices import from main.go
juev Mar 25, 2025
d290455
feat: implement Prometheus metrics conversion and storage management
juev Mar 26, 2025
7b09f19
feat: refactor metrics handling and improve Prometheus client initial…
juev Mar 26, 2025
f75dc54
refactor: optimize label handling for Prometheus metrics conversion
juev Mar 26, 2025
677695e
refactor: rename Prometheus metrics service constructor to follow nam…
juev Mar 26, 2025
8ad7c9f
chore: add Apache 2.0 license header to storage.go
juev Mar 26, 2025
48c8c40
feat: add DMT runtime duration metrics tracking
juev Mar 26, 2025
b30cd6b
refactor: update metrics client initialization and streamline DMT inf…
juev Mar 26, 2025
79d30fa
chore: add Apache 2.0 license header to convert.go
juev Mar 26, 2025
68aa45c
Merge branch 'main' into feature/telemetry
juev Mar 26, 2025
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
12 changes: 7 additions & 5 deletions cmd/dmt/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,16 +40,18 @@ func runLint(dir string) {
cfg, err := config.NewDefaultRootConfig(dir)
logger.CheckErr(err)

// init metrics storage
metrics.GetClient(dir)

mng := manager.NewManager(dir, cfg)
mng.Run()
mng.PrintResult()

metricsClient, err := metrics.NewPrometheusMetricsService(os.Getenv("DMT_METRICS_URL"), os.Getenv("DMT_METRICS_TOKEN"))
if err != nil {
logger.ErrorF("Failed to create metrics client: %v", err)
}
metrics.SetDmtInfo()
metrics.SetLinterWarningsMetrics(cfg.GlobalSettings)
metrics.SetDmtRuntimeDuration()

metricsClient.AddMetrics(metrics.GetInfo(dir))
metricsClient := metrics.GetClient(dir)
metricsClient.Send(context.Background())

if mng.HasCriticalErrors() {
Expand Down
2 changes: 2 additions & 0 deletions internal/manager/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import (
"github.com/deckhouse/dmt/internal/flags"
"github.com/deckhouse/dmt/internal/fsutils"
"github.com/deckhouse/dmt/internal/logger"
"github.com/deckhouse/dmt/internal/metrics"
"github.com/deckhouse/dmt/internal/module"
"github.com/deckhouse/dmt/internal/values"
"github.com/deckhouse/dmt/pkg"
Expand Down Expand Up @@ -207,6 +208,7 @@ func (m *Manager) PrintResult() {

if err.Level == pkg.Warn {
msgColor = color.FgHiYellow
metrics.IncDmtLinterWarningsCount(err.LinterID, err.RuleID)
}

// header
Expand Down
201 changes: 201 additions & 0 deletions internal/metrics/convert.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
/*
Copyright 2025 Flant JSC

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package metrics

import (
"fmt"
"slices"
"time"

"github.com/deckhouse/dmt/internal/promremote"
)

// GetTimeSeries converts Prometheus metric families to a map of promremote.TimeSeries
// where the key is the metric name and the value is a slice of time series for that metric
func (p *PrometheusMetricsService) GetTimeSeries() []promremote.TimeSeries {
var series []promremote.TimeSeries

metricFamilies, err := p.Gatherer.Gather()
if err != nil {
return nil
}
// Store timestamp for consistent use across series
timestamp := time.Now()

for _, metricFamily := range metricFamilies {
metricName := metricFamily.GetName()
for _, metric := range metricFamily.Metric {
// Create labels from the metric's label pairs
labels := make([]promremote.Label, 0, len(metric.Label)+1) // +1 for the name label
for _, labelPair := range metric.Label {
labels = append(labels, promremote.Label{
Name: labelPair.GetName(),
Value: labelPair.GetValue(),
})
}

// Extract value based on metric type
switch {
case metric.GetCounter() != nil:
// Add counter as a single time series
counterLabels := slices.Clone(labels)
counterLabels = append(counterLabels, promremote.Label{
Name: "__name__",
Value: metricName,
})

series = append(series, promremote.TimeSeries{
Labels: counterLabels,
Datapoint: promremote.Datapoint{
Timestamp: timestamp,
Value: metric.GetCounter().GetValue(),
},
})

case metric.GetGauge() != nil:
// Add gauge as a single time series
gaugeLabels := slices.Clone(labels)
gaugeLabels = append(gaugeLabels, promremote.Label{
Name: "__name__",
Value: metricName,
})

series = append(series, promremote.TimeSeries{
Labels: gaugeLabels,
Datapoint: promremote.Datapoint{
Timestamp: timestamp,
Value: metric.GetGauge().GetValue(),
},
})

case metric.GetHistogram() != nil:
histogram := metric.GetHistogram()

// 1. Add sum time series
sumLabels := slices.Clone(labels)
sumLabels = append(sumLabels, promremote.Label{
Name: "__name__",
Value: metricName + "_sum",
})

series = append(series, promremote.TimeSeries{
Labels: sumLabels,
Datapoint: promremote.Datapoint{
Timestamp: timestamp,
Value: histogram.GetSampleSum(),
},
})

// 2. Add count time series
countLabels := slices.Clone(labels)
countLabels = append(countLabels, promremote.Label{
Name: "__name__",
Value: metricName + "_count",
})

series = append(series, promremote.TimeSeries{
Labels: countLabels,
Datapoint: promremote.Datapoint{
Timestamp: timestamp,
Value: float64(histogram.GetSampleCount()),
},
})

// 3. Add bucket time series
for _, bucket := range histogram.GetBucket() {
bucketLabels := slices.Clone(labels)
bucketLabels = append(bucketLabels,
promremote.Label{
Name: "le",
Value: fmt.Sprintf("%g", bucket.GetUpperBound()),
},
promremote.Label{
Name: "__name__",
Value: metricName + "_bucket",
},
)

series = append(series, promremote.TimeSeries{
Labels: bucketLabels,
Datapoint: promremote.Datapoint{
Timestamp: timestamp,
Value: float64(bucket.GetCumulativeCount()),
},
})
}

case metric.GetSummary() != nil:
summary := metric.GetSummary()

// 1. Add sum time series
sumLabels := slices.Clone(labels)
sumLabels = append(sumLabels, promremote.Label{
Name: "__name__",
Value: metricName + "_sum",
})

series = append(series, promremote.TimeSeries{
Labels: sumLabels,
Datapoint: promremote.Datapoint{
Timestamp: timestamp,
Value: summary.GetSampleSum(),
},
})

// 2. Add count time series
countLabels := slices.Clone(labels)
countLabels = append(countLabels, promremote.Label{
Name: "__name__",
Value: metricName + "_count",
})

series = append(series, promremote.TimeSeries{
Labels: countLabels,
Datapoint: promremote.Datapoint{
Timestamp: timestamp,
Value: float64(summary.GetSampleCount()),
},
})

// 3. Add quantile time series
for _, quantile := range summary.GetQuantile() {
quantileLabels := slices.Clone(labels)
quantileLabels = append(quantileLabels,
promremote.Label{
Name: "quantile",
Value: fmt.Sprintf("%g", quantile.GetQuantile()),
},
promremote.Label{
Name: "__name__",
Value: metricName,
},
)

series = append(series, promremote.TimeSeries{
Labels: quantileLabels,
Datapoint: promremote.Datapoint{
Timestamp: timestamp,
Value: quantile.GetValue(),
},
})
}
}
}
}

return series
}
Loading