Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
aos
GitHub Repository: aos/grafana-agent
Path: blob/main/pkg/integrations/mysqld_exporter/mysqld-exporter.go
5441 views
1
// Package mysqld_exporter embeds https://github.com/prometheus/mysqld_exporter
2
package mysqld_exporter //nolint:golint
3
4
import (
5
"context"
6
"fmt"
7
"os"
8
9
config_util "github.com/prometheus/common/config"
10
11
"github.com/go-kit/log"
12
"github.com/go-kit/log/level"
13
"github.com/go-sql-driver/mysql"
14
"github.com/grafana/agent/pkg/integrations"
15
integrations_v2 "github.com/grafana/agent/pkg/integrations/v2"
16
"github.com/grafana/agent/pkg/integrations/v2/metricsutils"
17
"github.com/prometheus/mysqld_exporter/collector"
18
)
19
20
// DefaultConfig holds the default settings for the mysqld_exporter integration.
21
var DefaultConfig = Config{
22
LockWaitTimeout: 2,
23
24
InfoSchemaProcessListProcessesByUser: true,
25
InfoSchemaProcessListProcessesByHost: true,
26
InfoSchemaTablesDatabases: "*",
27
28
PerfSchemaEventsStatementsLimit: 250,
29
PerfSchemaEventsStatementsTimeLimit: 86400,
30
PerfSchemaEventsStatementsTextLimit: 120,
31
PerfSchemaFileInstancesFilter: ".*",
32
PerfSchemaFileInstancesRemovePrefix: "/var/lib/mysql",
33
34
HeartbeatDatabase: "heartbeat",
35
HeartbeatTable: "heartbeat",
36
}
37
38
// Config controls the mysqld_exporter integration.
39
type Config struct {
40
// DataSourceName to use to connect to MySQL.
41
DataSourceName config_util.Secret `yaml:"data_source_name,omitempty"`
42
43
// Collectors to mark as enabled in addition to the default.
44
EnableCollectors []string `yaml:"enable_collectors,omitempty"`
45
// Collectors to explicitly mark as disabled.
46
DisableCollectors []string `yaml:"disable_collectors,omitempty"`
47
48
// Overrides the default set of enabled collectors with the given list.
49
SetCollectors []string `yaml:"set_collectors,omitempty"`
50
51
// Collector-wide options
52
LockWaitTimeout int `yaml:"lock_wait_timeout,omitempty"`
53
LogSlowFilter bool `yaml:"log_slow_filter,omitempty"`
54
55
// Collector-specific config options
56
InfoSchemaProcessListMinTime int `yaml:"info_schema_processlist_min_time,omitempty"`
57
InfoSchemaProcessListProcessesByUser bool `yaml:"info_schema_processlist_processes_by_user,omitempty"`
58
InfoSchemaProcessListProcessesByHost bool `yaml:"info_schema_processlist_processes_by_host,omitempty"`
59
InfoSchemaTablesDatabases string `yaml:"info_schema_tables_databases,omitempty"`
60
PerfSchemaEventsStatementsLimit int `yaml:"perf_schema_eventsstatements_limit,omitempty"`
61
PerfSchemaEventsStatementsTimeLimit int `yaml:"perf_schema_eventsstatements_time_limit,omitempty"`
62
PerfSchemaEventsStatementsTextLimit int `yaml:"perf_schema_eventsstatements_digtext_text_limit,omitempty"`
63
PerfSchemaFileInstancesFilter string `yaml:"perf_schema_file_instances_filter,omitempty"`
64
PerfSchemaFileInstancesRemovePrefix string `yaml:"perf_schema_file_instances_remove_prefix,omitempty"`
65
HeartbeatDatabase string `yaml:"heartbeat_database,omitempty"`
66
HeartbeatTable string `yaml:"heartbeat_table,omitempty"`
67
HeartbeatUTC bool `yaml:"heartbeat_utc,omitempty"`
68
MySQLUserPrivileges bool `yaml:"mysql_user_privileges,omitempty"`
69
}
70
71
// UnmarshalYAML implements yaml.Unmarshaler for Config.
72
func (c *Config) UnmarshalYAML(unmarshal func(interface{}) error) error {
73
*c = DefaultConfig
74
75
type plain Config
76
return unmarshal((*plain)(c))
77
}
78
79
// Name returns the name of the integration that this config represents.
80
func (c *Config) Name() string {
81
return "mysqld_exporter"
82
}
83
84
// InstanceKey returns network(hostname:port)/dbname of the MySQL server.
85
func (c *Config) InstanceKey(_ string) (string, error) {
86
m, err := mysql.ParseDSN(string(c.DataSourceName))
87
if err != nil {
88
return "", fmt.Errorf("failed to parse DSN: %w", err)
89
}
90
91
if m.Addr == "" {
92
m.Addr = "localhost:3306"
93
}
94
if m.Net == "" {
95
m.Net = "tcp"
96
}
97
98
return fmt.Sprintf("%s(%s)/%s", m.Net, m.Addr, m.DBName), nil
99
}
100
101
// NewIntegration converts this config into an instance of an integration.
102
func (c *Config) NewIntegration(l log.Logger) (integrations.Integration, error) {
103
return New(l, c)
104
}
105
106
func init() {
107
integrations.RegisterIntegration(&Config{})
108
integrations_v2.RegisterLegacy(&Config{}, integrations_v2.TypeMultiplex, metricsutils.NewNamedShim("mysql"))
109
}
110
111
// New creates a new mysqld_exporter integration. The integration scrapes
112
// metrics from a mysqld process.
113
func New(log log.Logger, c *Config) (integrations.Integration, error) {
114
dsn := c.DataSourceName
115
if len(dsn) == 0 {
116
dsn = config_util.Secret(os.Getenv("MYSQLD_EXPORTER_DATA_SOURCE_NAME"))
117
}
118
if len(dsn) == 0 {
119
return nil, fmt.Errorf("cannot create mysqld_exporter; neither mysqld_exporter.data_source_name or $MYSQLD_EXPORTER_DATA_SOURCE_NAME is set")
120
}
121
122
scrapers := GetScrapers(c)
123
exporter := collector.New(context.Background(), string(dsn), collector.NewMetrics(), scrapers, log, collector.Config{
124
LockTimeout: c.LockWaitTimeout,
125
SlowLogFilter: c.LogSlowFilter,
126
})
127
128
level.Debug(log).Log("msg", "enabled mysqld_exporter scrapers")
129
for _, scraper := range scrapers {
130
level.Debug(log).Log("scraper", scraper.Name())
131
}
132
133
return integrations.NewCollectorIntegration(
134
c.Name(),
135
integrations.WithCollectors(exporter),
136
), nil
137
}
138
139
// GetScrapers returns the set of *enabled* scrapers from the config.
140
// Configurable scrapers will have their configuration filled out matching the
141
// Config's settings.
142
func GetScrapers(c *Config) []collector.Scraper {
143
scrapers := map[collector.Scraper]bool{
144
&collector.ScrapeAutoIncrementColumns{}: false,
145
&collector.ScrapeBinlogSize{}: false,
146
&collector.ScrapeClientStat{}: false,
147
&collector.ScrapeEngineInnodbStatus{}: false,
148
&collector.ScrapeEngineTokudbStatus{}: false,
149
&collector.ScrapeGlobalStatus{}: true,
150
&collector.ScrapeGlobalVariables{}: true,
151
&collector.ScrapeInfoSchemaInnodbTablespaces{}: false,
152
&collector.ScrapeInnodbCmpMem{}: true,
153
&collector.ScrapeInnodbCmp{}: true,
154
&collector.ScrapeInnodbMetrics{}: false,
155
&collector.ScrapePerfEventsStatementsSum{}: false,
156
&collector.ScrapePerfEventsWaits{}: false,
157
&collector.ScrapePerfFileEvents{}: false,
158
&collector.ScrapePerfIndexIOWaits{}: false,
159
&collector.ScrapePerfReplicationApplierStatsByWorker{}: false,
160
&collector.ScrapePerfReplicationGroupMemberStats{}: false,
161
&collector.ScrapePerfReplicationGroupMembers{}: false,
162
&collector.ScrapePerfTableIOWaits{}: false,
163
&collector.ScrapePerfTableLockWaits{}: false,
164
&collector.ScrapeQueryResponseTime{}: true,
165
&collector.ScrapeReplicaHost{}: false,
166
&collector.ScrapeSchemaStat{}: false,
167
&collector.ScrapeSlaveHosts{}: false,
168
&collector.ScrapeSlaveStatus{}: true,
169
&collector.ScrapeTableStat{}: false,
170
&collector.ScrapeUserStat{}: false,
171
172
// Collectors that have configuration
173
&collector.ScrapeHeartbeat{
174
Database: c.HeartbeatDatabase,
175
Table: c.HeartbeatTable,
176
UTC: c.HeartbeatUTC,
177
}: false,
178
179
&collector.ScrapePerfEventsStatements{
180
Limit: c.PerfSchemaEventsStatementsLimit,
181
TimeLimit: c.PerfSchemaEventsStatementsTimeLimit,
182
DigestTextLimit: c.PerfSchemaEventsStatementsTextLimit,
183
}: false,
184
185
&collector.ScrapePerfFileInstances{
186
Filter: c.PerfSchemaFileInstancesFilter,
187
RemovePrefix: c.PerfSchemaFileInstancesRemovePrefix,
188
}: false,
189
190
&collector.ScrapeProcesslist{
191
ProcessListMinTime: c.InfoSchemaProcessListMinTime,
192
ProcessesByHostFlag: c.InfoSchemaProcessListProcessesByHost,
193
ProcessesByUserFlag: c.InfoSchemaProcessListProcessesByUser,
194
}: false,
195
196
&collector.ScrapeTableSchema{
197
Databases: c.InfoSchemaTablesDatabases,
198
}: false,
199
200
&collector.ScrapeUser{
201
Privileges: c.MySQLUserPrivileges,
202
}: false,
203
}
204
205
// Override the defaults with the provided set of collectors if
206
// set_collectors has at least one element in it.
207
if len(c.SetCollectors) != 0 {
208
customDefaults := map[string]struct{}{}
209
for _, c := range c.SetCollectors {
210
customDefaults[c] = struct{}{}
211
}
212
for scraper := range scrapers {
213
_, enable := customDefaults[scraper.Name()]
214
scrapers[scraper] = enable
215
}
216
}
217
218
// Explicitly disable/enable specific collectors.
219
for _, c := range c.DisableCollectors {
220
for scraper := range scrapers {
221
if scraper.Name() == c {
222
scrapers[scraper] = false
223
break
224
}
225
}
226
}
227
for _, c := range c.EnableCollectors {
228
for scraper := range scrapers {
229
if scraper.Name() == c {
230
scrapers[scraper] = true
231
break
232
}
233
}
234
}
235
236
enabledScrapers := []collector.Scraper{}
237
for scraper, enabled := range scrapers {
238
if enabled {
239
enabledScrapers = append(enabledScrapers, scraper)
240
}
241
}
242
return enabledScrapers
243
}
244
245