Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
aos
GitHub Repository: aos/grafana-agent
Path: blob/main/pkg/integrations/mssql/collector.go
5371 views
1
package mssql
2
3
import (
4
"context"
5
_ "embed"
6
"fmt"
7
8
"github.com/burningalchemist/sql_exporter"
9
"github.com/burningalchemist/sql_exporter/config"
10
"github.com/go-kit/log"
11
"github.com/go-kit/log/level"
12
"github.com/prometheus/client_golang/prometheus"
13
dto "github.com/prometheus/client_model/go"
14
"gopkg.in/yaml.v2"
15
)
16
17
// Embedded config.CollectorConfig as yaml.
18
// We do this so that we can unmarshal instead of creating a static instance in code;
19
// This is because there is special unmarshal logic for the CollectorConfig
20
// that sets some unexported fields.
21
//
22
//go:embed collector_config.yaml
23
var collectorConfigBytes []byte
24
25
// collectorConfig is a config that can be used to construct a
26
// sql_exporter.Target that scrapes metrics from an instance of mssql
27
var collectorConfig config.CollectorConfig
28
29
// initialize static collector config
30
func init() {
31
err := yaml.Unmarshal(collectorConfigBytes, &collectorConfig)
32
if err != nil {
33
panic(fmt.Errorf("failed to unmarshal mssql integration collector config: %w", err))
34
}
35
}
36
37
// targetCollectorAdapter adapts sql_exporter.Target to prometheus.Collector
38
type targetCollectorAdapter struct {
39
target sql_exporter.Target
40
logger log.Logger
41
}
42
43
// newTargetCollectorAdapter creates a new TargetCollectorAdapter
44
func newTargetCollectorAdapter(t sql_exporter.Target, l log.Logger) targetCollectorAdapter {
45
return targetCollectorAdapter{
46
target: t,
47
logger: l,
48
}
49
}
50
51
// Collect calls the collect function of the underlying sql_exporter.Target, converting each
52
// returned sql_exporter.Metric to a prometheus.Metric.
53
func (t targetCollectorAdapter) Collect(m chan<- prometheus.Metric) {
54
sqlMetrics := make(chan sql_exporter.Metric)
55
56
go func() {
57
t.target.Collect(context.Background(), sqlMetrics)
58
close(sqlMetrics)
59
}()
60
61
for metric := range sqlMetrics {
62
m <- sqlPrometheusMetricAdapter{
63
Metric: metric,
64
logger: t.logger,
65
}
66
}
67
}
68
69
// Describe is an empty method, which marks the prometheus.Collector as "unchecked"
70
func (t targetCollectorAdapter) Describe(chan<- *prometheus.Desc) {}
71
72
// sqlPrometheusMetricAdapter adapts sql_exporter.Metric to prometheus.Metric
73
type sqlPrometheusMetricAdapter struct {
74
sql_exporter.Metric
75
logger log.Logger
76
}
77
78
// Write writes the sql_exporter.Metric to the prometheus metric pb
79
func (s sqlPrometheusMetricAdapter) Write(m *dto.Metric) error {
80
return s.Metric.Write(m)
81
}
82
83
// Desc converts the underlying sql_exporter.Metric description to
84
// a prometheus.Desc.
85
func (s sqlPrometheusMetricAdapter) Desc() *prometheus.Desc {
86
sqlDesc := s.Metric.Desc()
87
88
if sqlDesc == nil {
89
// nil desc indicates that this metric has an invalid descriptor.
90
// we can get the error using the Write function.
91
err := s.Metric.Write(nil)
92
level.Error(s.logger).Log("msg", "Invalid metric description.", "err", err)
93
return prometheus.NewInvalidDesc(err)
94
}
95
96
constLabelsDtos := sqlDesc.ConstLabels()
97
constLabels := make(map[string]string, len(constLabelsDtos))
98
99
for _, l := range constLabelsDtos {
100
constLabels[l.GetName()] = l.GetValue()
101
}
102
103
return prometheus.NewDesc(
104
sqlDesc.Name(),
105
sqlDesc.Help(),
106
sqlDesc.Labels(),
107
constLabels,
108
)
109
}
110
111