Path: blob/main/pkg/integrations/mysqld_exporter/mysqld-exporter.go
5441 views
// Package mysqld_exporter embeds https://github.com/prometheus/mysqld_exporter1package mysqld_exporter //nolint:golint23import (4"context"5"fmt"6"os"78config_util "github.com/prometheus/common/config"910"github.com/go-kit/log"11"github.com/go-kit/log/level"12"github.com/go-sql-driver/mysql"13"github.com/grafana/agent/pkg/integrations"14integrations_v2 "github.com/grafana/agent/pkg/integrations/v2"15"github.com/grafana/agent/pkg/integrations/v2/metricsutils"16"github.com/prometheus/mysqld_exporter/collector"17)1819// DefaultConfig holds the default settings for the mysqld_exporter integration.20var DefaultConfig = Config{21LockWaitTimeout: 2,2223InfoSchemaProcessListProcessesByUser: true,24InfoSchemaProcessListProcessesByHost: true,25InfoSchemaTablesDatabases: "*",2627PerfSchemaEventsStatementsLimit: 250,28PerfSchemaEventsStatementsTimeLimit: 86400,29PerfSchemaEventsStatementsTextLimit: 120,30PerfSchemaFileInstancesFilter: ".*",31PerfSchemaFileInstancesRemovePrefix: "/var/lib/mysql",3233HeartbeatDatabase: "heartbeat",34HeartbeatTable: "heartbeat",35}3637// Config controls the mysqld_exporter integration.38type Config struct {39// DataSourceName to use to connect to MySQL.40DataSourceName config_util.Secret `yaml:"data_source_name,omitempty"`4142// Collectors to mark as enabled in addition to the default.43EnableCollectors []string `yaml:"enable_collectors,omitempty"`44// Collectors to explicitly mark as disabled.45DisableCollectors []string `yaml:"disable_collectors,omitempty"`4647// Overrides the default set of enabled collectors with the given list.48SetCollectors []string `yaml:"set_collectors,omitempty"`4950// Collector-wide options51LockWaitTimeout int `yaml:"lock_wait_timeout,omitempty"`52LogSlowFilter bool `yaml:"log_slow_filter,omitempty"`5354// Collector-specific config options55InfoSchemaProcessListMinTime int `yaml:"info_schema_processlist_min_time,omitempty"`56InfoSchemaProcessListProcessesByUser bool `yaml:"info_schema_processlist_processes_by_user,omitempty"`57InfoSchemaProcessListProcessesByHost bool `yaml:"info_schema_processlist_processes_by_host,omitempty"`58InfoSchemaTablesDatabases string `yaml:"info_schema_tables_databases,omitempty"`59PerfSchemaEventsStatementsLimit int `yaml:"perf_schema_eventsstatements_limit,omitempty"`60PerfSchemaEventsStatementsTimeLimit int `yaml:"perf_schema_eventsstatements_time_limit,omitempty"`61PerfSchemaEventsStatementsTextLimit int `yaml:"perf_schema_eventsstatements_digtext_text_limit,omitempty"`62PerfSchemaFileInstancesFilter string `yaml:"perf_schema_file_instances_filter,omitempty"`63PerfSchemaFileInstancesRemovePrefix string `yaml:"perf_schema_file_instances_remove_prefix,omitempty"`64HeartbeatDatabase string `yaml:"heartbeat_database,omitempty"`65HeartbeatTable string `yaml:"heartbeat_table,omitempty"`66HeartbeatUTC bool `yaml:"heartbeat_utc,omitempty"`67MySQLUserPrivileges bool `yaml:"mysql_user_privileges,omitempty"`68}6970// UnmarshalYAML implements yaml.Unmarshaler for Config.71func (c *Config) UnmarshalYAML(unmarshal func(interface{}) error) error {72*c = DefaultConfig7374type plain Config75return unmarshal((*plain)(c))76}7778// Name returns the name of the integration that this config represents.79func (c *Config) Name() string {80return "mysqld_exporter"81}8283// InstanceKey returns network(hostname:port)/dbname of the MySQL server.84func (c *Config) InstanceKey(_ string) (string, error) {85m, err := mysql.ParseDSN(string(c.DataSourceName))86if err != nil {87return "", fmt.Errorf("failed to parse DSN: %w", err)88}8990if m.Addr == "" {91m.Addr = "localhost:3306"92}93if m.Net == "" {94m.Net = "tcp"95}9697return fmt.Sprintf("%s(%s)/%s", m.Net, m.Addr, m.DBName), nil98}99100// NewIntegration converts this config into an instance of an integration.101func (c *Config) NewIntegration(l log.Logger) (integrations.Integration, error) {102return New(l, c)103}104105func init() {106integrations.RegisterIntegration(&Config{})107integrations_v2.RegisterLegacy(&Config{}, integrations_v2.TypeMultiplex, metricsutils.NewNamedShim("mysql"))108}109110// New creates a new mysqld_exporter integration. The integration scrapes111// metrics from a mysqld process.112func New(log log.Logger, c *Config) (integrations.Integration, error) {113dsn := c.DataSourceName114if len(dsn) == 0 {115dsn = config_util.Secret(os.Getenv("MYSQLD_EXPORTER_DATA_SOURCE_NAME"))116}117if len(dsn) == 0 {118return nil, fmt.Errorf("cannot create mysqld_exporter; neither mysqld_exporter.data_source_name or $MYSQLD_EXPORTER_DATA_SOURCE_NAME is set")119}120121scrapers := GetScrapers(c)122exporter := collector.New(context.Background(), string(dsn), collector.NewMetrics(), scrapers, log, collector.Config{123LockTimeout: c.LockWaitTimeout,124SlowLogFilter: c.LogSlowFilter,125})126127level.Debug(log).Log("msg", "enabled mysqld_exporter scrapers")128for _, scraper := range scrapers {129level.Debug(log).Log("scraper", scraper.Name())130}131132return integrations.NewCollectorIntegration(133c.Name(),134integrations.WithCollectors(exporter),135), nil136}137138// GetScrapers returns the set of *enabled* scrapers from the config.139// Configurable scrapers will have their configuration filled out matching the140// Config's settings.141func GetScrapers(c *Config) []collector.Scraper {142scrapers := map[collector.Scraper]bool{143&collector.ScrapeAutoIncrementColumns{}: false,144&collector.ScrapeBinlogSize{}: false,145&collector.ScrapeClientStat{}: false,146&collector.ScrapeEngineInnodbStatus{}: false,147&collector.ScrapeEngineTokudbStatus{}: false,148&collector.ScrapeGlobalStatus{}: true,149&collector.ScrapeGlobalVariables{}: true,150&collector.ScrapeInfoSchemaInnodbTablespaces{}: false,151&collector.ScrapeInnodbCmpMem{}: true,152&collector.ScrapeInnodbCmp{}: true,153&collector.ScrapeInnodbMetrics{}: false,154&collector.ScrapePerfEventsStatementsSum{}: false,155&collector.ScrapePerfEventsWaits{}: false,156&collector.ScrapePerfFileEvents{}: false,157&collector.ScrapePerfIndexIOWaits{}: false,158&collector.ScrapePerfReplicationApplierStatsByWorker{}: false,159&collector.ScrapePerfReplicationGroupMemberStats{}: false,160&collector.ScrapePerfReplicationGroupMembers{}: false,161&collector.ScrapePerfTableIOWaits{}: false,162&collector.ScrapePerfTableLockWaits{}: false,163&collector.ScrapeQueryResponseTime{}: true,164&collector.ScrapeReplicaHost{}: false,165&collector.ScrapeSchemaStat{}: false,166&collector.ScrapeSlaveHosts{}: false,167&collector.ScrapeSlaveStatus{}: true,168&collector.ScrapeTableStat{}: false,169&collector.ScrapeUserStat{}: false,170171// Collectors that have configuration172&collector.ScrapeHeartbeat{173Database: c.HeartbeatDatabase,174Table: c.HeartbeatTable,175UTC: c.HeartbeatUTC,176}: false,177178&collector.ScrapePerfEventsStatements{179Limit: c.PerfSchemaEventsStatementsLimit,180TimeLimit: c.PerfSchemaEventsStatementsTimeLimit,181DigestTextLimit: c.PerfSchemaEventsStatementsTextLimit,182}: false,183184&collector.ScrapePerfFileInstances{185Filter: c.PerfSchemaFileInstancesFilter,186RemovePrefix: c.PerfSchemaFileInstancesRemovePrefix,187}: false,188189&collector.ScrapeProcesslist{190ProcessListMinTime: c.InfoSchemaProcessListMinTime,191ProcessesByHostFlag: c.InfoSchemaProcessListProcessesByHost,192ProcessesByUserFlag: c.InfoSchemaProcessListProcessesByUser,193}: false,194195&collector.ScrapeTableSchema{196Databases: c.InfoSchemaTablesDatabases,197}: false,198199&collector.ScrapeUser{200Privileges: c.MySQLUserPrivileges,201}: false,202}203204// Override the defaults with the provided set of collectors if205// set_collectors has at least one element in it.206if len(c.SetCollectors) != 0 {207customDefaults := map[string]struct{}{}208for _, c := range c.SetCollectors {209customDefaults[c] = struct{}{}210}211for scraper := range scrapers {212_, enable := customDefaults[scraper.Name()]213scrapers[scraper] = enable214}215}216217// Explicitly disable/enable specific collectors.218for _, c := range c.DisableCollectors {219for scraper := range scrapers {220if scraper.Name() == c {221scrapers[scraper] = false222break223}224}225}226for _, c := range c.EnableCollectors {227for scraper := range scrapers {228if scraper.Name() == c {229scrapers[scraper] = true230break231}232}233}234235enabledScrapers := []collector.Scraper{}236for scraper, enabled := range scrapers {237if enabled {238enabledScrapers = append(enabledScrapers, scraper)239}240}241return enabledScrapers242}243244245