diff --git a/CHANGELOG.md b/CHANGELOG.md index 37655985ae..0290dad339 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -34,6 +34,15 @@ Main (unreleased) - Logs from underlying clustering library `memberlist` are now surfaced with correct level (@thampiotr) +- Update mysqld_exporter from v0.15.0 to v0.16.0, most notable changes: (@cristiangreco) + - Support MySQL 8.4 replicas syntax + - Fetch lock time and cpu time from performance schema + - Fix fetching tmpTables vs tmpDiskTables from performance_schema + - Skip SPACE_TYPE column for MariaDB >=10.5 + - Fixed parsing of timestamps with non-zero padded days + - Fix auto_increment metric collection errors caused by using collation in INFORMATION_SCHEMA searches + - Change processlist query to support ONLY_FULL_GROUP_BY sql_mode + ### Bugfixes - Fixed an issue in the `prometheus.exporter.postgres` component that would leak goroutines when the target was not reachable (@dehaansa) diff --git a/go.mod b/go.mod index 1b8273d00a..5f7bc53c19 100644 --- a/go.mod +++ b/go.mod @@ -43,7 +43,7 @@ require ( github.com/go-kit/log v0.2.1 github.com/go-logfmt/logfmt v0.6.0 github.com/go-sourcemap/sourcemap v2.1.3+incompatible - github.com/go-sql-driver/mysql v1.7.1 + github.com/go-sql-driver/mysql v1.8.1 github.com/gogo/protobuf v1.3.2 github.com/golang/protobuf v1.5.4 github.com/golang/snappy v0.0.4 @@ -162,11 +162,11 @@ require ( github.com/prometheus/blackbox_exporter v0.24.1-0.20230623125439-bd22efa1c900 github.com/prometheus/client_golang v1.20.5 github.com/prometheus/client_model v0.6.1 - github.com/prometheus/common v0.60.0 + github.com/prometheus/common v0.60.1 github.com/prometheus/common/sigv4 v0.1.0 github.com/prometheus/consul_exporter v0.8.0 github.com/prometheus/memcached_exporter v0.13.0 - github.com/prometheus/mysqld_exporter v0.14.0 + github.com/prometheus/mysqld_exporter v0.16.0 github.com/prometheus/node_exporter v1.6.0 github.com/prometheus/procfs v0.15.1 github.com/prometheus/prometheus v0.55.1 // a.k.a. v2.51.2 @@ -710,7 +710,7 @@ require ( github.com/prometheus-community/go-runit v0.1.0 // indirect github.com/prometheus-community/prom-label-proxy v0.6.0 // indirect github.com/prometheus/alertmanager v0.27.0 // indirect - github.com/prometheus/exporter-toolkit v0.11.0 // indirect + github.com/prometheus/exporter-toolkit v0.13.1 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/relvacode/iso8601 v1.4.0 // indirect github.com/remeh/sizedwaitgroup v1.0.0 // indirect @@ -826,13 +826,16 @@ require ( ) require ( + filippo.io/edwards25519 v1.1.0 // indirect github.com/Azure/go-amqp v1.2.0 // indirect github.com/DataDog/datadog-agent/comp/core/log/def v0.57.1 // indirect github.com/antchfx/xmlquery v1.4.2 // indirect github.com/antchfx/xpath v1.3.2 // indirect github.com/ebitengine/purego v0.8.0 // indirect github.com/elastic/lunes v0.1.0 // indirect + github.com/mdlayher/vsock v1.2.1 // indirect github.com/moby/sys/userns v0.1.0 // indirect + github.com/open-telemetry/opentelemetry-collector-contrib/exporter/syslogexporter v0.112.0 // indirect github.com/open-telemetry/opentelemetry-collector-contrib/pkg/kafka/topic v0.112.0 // indirect github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect go.opentelemetry.io/collector/connector/connectorprofiles v0.112.0 // indirect @@ -909,8 +912,11 @@ replace ( // grafana fork of the exporter, or completely into upstream github.com/prometheus-community/postgres_exporter => github.com/grafana/postgres_exporter v0.15.1-0.20241105053755-e0a51174f168 +// Needed until a bunch of exporters are updated, because 0.13.0 breaks compatibility in web.ListenAndServe + github.com/prometheus/exporter-toolkit => github.com/prometheus/exporter-toolkit v0.11.0 + // TODO(marctc): remove once this PR is merged upstream: https://github.com/prometheus/mysqld_exporter/pull/774 - github.com/prometheus/mysqld_exporter => github.com/grafana/mysqld_exporter v0.12.2-0.20231005125903-364b9c41e595 + github.com/prometheus/mysqld_exporter => github.com/grafana/mysqld_exporter v0.16.1-0.20241111085008-47b8ea9fab19 // TODO(marctc, mattdurham): Replace node_export with custom fork for multi usage. https://github.com/prometheus/node_exporter/pull/2812 github.com/prometheus/node_exporter => github.com/grafana/node_exporter v0.18.1-grafana-r01.0.20231004161416-702318429731 diff --git a/go.sum b/go.sum index 0f39957612..2f92e83471 100644 --- a/go.sum +++ b/go.sum @@ -66,6 +66,8 @@ connectrpc.com/connect v1.16.2/go.mod h1:n2kgwskMHXC+lVqb18wngEpF95ldBHXjZYJussz dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= +filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 h1:/vQbFIOMbk2FiG/kXiLl8BRyzTWDw7gX/Hz7Dd5eDMs= github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4/go.mod h1:hN7oaIRCjzsZ2dE+yG5k+rsdt3qcwykqK6HVGcKwsw4= github.com/99designs/keyring v1.2.2 h1:pZd3neh/EmUzWONb35LxQfvuY7kiSXAq3HQd97+XBn0= @@ -1000,8 +1002,8 @@ github.com/go-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5Nq github.com/go-sql-driver/mysql v0.0.0-20180618115901-749ddf1598b4/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= -github.com/go-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrtU8EI= -github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= +github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y= +github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= @@ -1243,8 +1245,8 @@ github.com/grafana/loki/pkg/push v0.0.0-20240617182007-6c33561108ad h1:4XAhmVmKb github.com/grafana/loki/pkg/push v0.0.0-20240617182007-6c33561108ad/go.mod h1:lJEF/Wh5MYlmBem6tOYAFObkLsuikfrEf8Iy9AdMPiQ= github.com/grafana/loki/v3 v3.0.0-20240617182007-6c33561108ad h1:eaHz6gH7OM3LWGp1h2QZ+/wkeyjNspk3QwjD4YUWR5g= github.com/grafana/loki/v3 v3.0.0-20240617182007-6c33561108ad/go.mod h1:fKBY3k60xjlGcIdbOaJiy3aWopF65FpQvQWczCp2SZ0= -github.com/grafana/mysqld_exporter v0.12.2-0.20231005125903-364b9c41e595 h1:I9sRknI5ajd8whPOX0nBDXy5B6xUfhItClMy+6R4oqE= -github.com/grafana/mysqld_exporter v0.12.2-0.20231005125903-364b9c41e595/go.mod h1:U8ifHC5pT2WuVTO7ki4KZmWLjfEKfktQiU3bh0J8scw= +github.com/grafana/mysqld_exporter v0.16.1-0.20241111085008-47b8ea9fab19 h1:JKMpcPPmhU198g3skPdSf2YvcgUKZ6bf3X1uTXnCZXU= +github.com/grafana/mysqld_exporter v0.16.1-0.20241111085008-47b8ea9fab19/go.mod h1:ctzLZ0vK3ow5JZmBfbS261ufC/4vtfuwFileKJea3kg= github.com/grafana/node_exporter v0.18.1-grafana-r01.0.20231004161416-702318429731 h1:vyyIYY2sLpmgFIckJ1vSO/oYkvB0thDF6UiFYp5PThM= github.com/grafana/node_exporter v0.18.1-grafana-r01.0.20231004161416-702318429731/go.mod h1:vOZxEzxm0nZmuNqjtIfvtmvdRtJik9POmcN5mQVLf5E= github.com/grafana/opentelemetry-collector-contrib/receiver/prometheusreceiver v0.0.0-20240326165551-1ae1b9218b1b h1:o7tJxI3dVrIwZwNd7feiMNjYRnbMvyGCQtxJGgfORQQ= @@ -1770,6 +1772,8 @@ github.com/mdlayher/netlink v1.7.2 h1:/UtM3ofJap7Vl4QWCPDGXY8d3GIY2UGSDbK+QWmY8/ github.com/mdlayher/netlink v1.7.2/go.mod h1:xraEF7uJbxLhc5fpHL4cPe221LI2bdttWlU+ZGLfQSw= github.com/mdlayher/socket v0.4.1 h1:eM9y2/jlbs1M615oshPQOHZzj6R6wMT7bX5NPiQvn2U= github.com/mdlayher/socket v0.4.1/go.mod h1:cAqeGjoufqdxWkD7DkpyS+wcefOtmu5OQ8KuoJGIReA= +github.com/mdlayher/vsock v1.2.1 h1:pC1mTJTvjo1r9n9fbm7S1j04rCgCzhCOS5DY0zqHlnQ= +github.com/mdlayher/vsock v1.2.1/go.mod h1:NRfCibel++DgeMD8z/hP+PPTjlNJsdPOmxcnENvE+SE= github.com/mdlayher/wifi v0.1.0 h1:y8wYRUXwok5CtUZOXT3egghYesX0O79E3ALl+SIDm9Q= github.com/mdlayher/wifi v0.1.0/go.mod h1:+gBYnZAMcUKHSFzMJXwlz7tLsEHgwDJ9DJCefhJM+gI= github.com/metalmatze/signal v0.0.0-20210307161603-1c9aa721a97a h1:0usWxe5SGXKQovz3p+BiQ81Jy845xSMu2CWKuXsXuUM= @@ -2232,6 +2236,8 @@ github.com/prometheus/common v0.31.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+ github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= github.com/prometheus/common v0.60.0 h1:+V9PAREWNvJMAuJ1x1BaWl9dewMW4YrHZQbx0sJNllA= github.com/prometheus/common v0.60.0/go.mod h1:h0LYf1R1deLSKtD4Vdg8gy4RuOvENW2J/h19V5NADQw= +github.com/prometheus/common v0.60.1 h1:FUas6GcOw66yB/73KC+BOZoFJmbo/1pojoILArPAaSc= +github.com/prometheus/common v0.60.1/go.mod h1:h0LYf1R1deLSKtD4Vdg8gy4RuOvENW2J/h19V5NADQw= github.com/prometheus/common/sigv4 v0.1.0 h1:qoVebwtwwEhS85Czm2dSROY5fTo2PAPEVdDeppTwGX4= github.com/prometheus/common/sigv4 v0.1.0/go.mod h1:2Jkxxk9yYvCkE5G1sQT7GuEXm57JrvHu9k5YwTjsNtI= github.com/prometheus/consul_exporter v0.8.0 h1:2z3drFic65WFoHaJRKkmnJRRlBLmmxVqT8L9LO2yxAo= @@ -2240,6 +2246,8 @@ github.com/prometheus/exporter-toolkit v0.7.0/go.mod h1:ZUBIj498ePooX9t/2xtDjeQY github.com/prometheus/exporter-toolkit v0.7.1/go.mod h1:ZUBIj498ePooX9t/2xtDjeQYwvRpiPP2lh5u4iblj2g= github.com/prometheus/exporter-toolkit v0.11.0 h1:yNTsuZ0aNCNFQ3aFTD2uhPOvr4iD7fdBvKPAEGkNf+g= github.com/prometheus/exporter-toolkit v0.11.0/go.mod h1:BVnENhnNecpwoTLiABx7mrPB/OLRIgN74qlQbV+FK1Q= +github.com/prometheus/exporter-toolkit v0.13.1 h1:Evsh0gWQo2bdOHlnz9+0Nm7/OFfIwhE2Ws4A2jIlR04= +github.com/prometheus/exporter-toolkit v0.13.1/go.mod h1:ujdv2YIOxtdFxxqtloLpbqmxd5J0Le6IITUvIRSWjj0= github.com/prometheus/memcached_exporter v0.13.0 h1:d246RYODFCXy39XA8S2PBrqp5jLCSvl9b4KsYspDCHk= github.com/prometheus/memcached_exporter v0.13.0/go.mod h1:fp7Wk6v0RFijeP3Syvd1TShBSJoCG5iFfvPdi5dCMEU= github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= diff --git a/internal/runtime/logging/slgk_handler.go b/internal/runtime/logging/slgk_handler.go new file mode 100644 index 0000000000..d936ca5f65 --- /dev/null +++ b/internal/runtime/logging/slgk_handler.go @@ -0,0 +1,115 @@ +package logging + +import ( + "context" + "log/slog" + + "github.com/go-kit/log" + "github.com/go-kit/log/level" +) + +var _ slog.Handler = (*SlogGoKitHandler)(nil) + +// SlogGoKitHandler is an slog.Handler that wraps a go-kit logger. +// This is specific to Alloy's logging system, as we expect the go-kit +// logger to be configured with the correct level. +type SlogGoKitHandler struct { + logger log.Logger + group string + preformatted []any +} + +func NewSlogGoKitHandler(logger log.Logger) *SlogGoKitHandler { + return &SlogGoKitHandler{ + logger: logger, + } +} + +func (h SlogGoKitHandler) Enabled(ctx context.Context, level slog.Level) bool { + // return always true, we expect the underlying logger to handle the level + return true +} + +func (h SlogGoKitHandler) Handle(ctx context.Context, record slog.Record) error { + var logger log.Logger + switch record.Level { + case slog.LevelInfo: + logger = level.Info(h.logger) + case slog.LevelWarn: + logger = level.Warn(h.logger) + case slog.LevelError: + logger = level.Error(h.logger) + default: + logger = level.Debug(h.logger) + } + + pairs := make([]any, 0, 2*record.NumAttrs()) + pairs = append(pairs, "msg", record.Message) + pairs = append(pairs, h.preformatted...) + + record.Attrs(func(attr slog.Attr) bool { + pairs = appendPair(pairs, h.group, attr) + return true + }) + + return logger.Log(pairs...) +} + +func (h SlogGoKitHandler) WithAttrs(attrs []slog.Attr) slog.Handler { + pairs := make([]any, 0, 2*len(attrs)) + for _, attr := range attrs { + pairs = appendPair(pairs, h.group, attr) + } + + if h.preformatted != nil { + pairs = append(h.preformatted, pairs...) + } + + return &SlogGoKitHandler{ + logger: h.logger, + preformatted: pairs, + group: h.group, + } +} + +func (h SlogGoKitHandler) WithGroup(name string) slog.Handler { + if name == "" { + return h + } + + group := name + if h.group != "" { + group = h.group + "." + group + } + + return &SlogGoKitHandler{ + logger: h.logger, + preformatted: h.preformatted, + group: group, + } +} + +func appendPair(pairs []any, groupPrefix string, attr slog.Attr) []any { + if attr.Equal(slog.Attr{}) { + return pairs + } + + switch attr.Value.Kind() { + case slog.KindGroup: + if attr.Key != "" { + groupPrefix = groupPrefix + "." + attr.Key + } + for _, at := range attr.Value.Group() { + pairs = appendPair(pairs, groupPrefix, at) + } + default: + key := attr.Key + if groupPrefix != "" { + key = groupPrefix + "." + key + } + + pairs = append(pairs, key, attr.Value) + } + + return pairs +} diff --git a/internal/runtime/logging/slgk_handler_test.go b/internal/runtime/logging/slgk_handler_test.go new file mode 100644 index 0000000000..1ea375c7d4 --- /dev/null +++ b/internal/runtime/logging/slgk_handler_test.go @@ -0,0 +1,75 @@ +package logging_test + +import ( + "bytes" + "log/slog" + "strings" + "testing" + "testing/slogtest" + + "github.com/go-kit/log" + "github.com/go-logfmt/logfmt" + "github.com/stretchr/testify/require" + + "github.com/grafana/alloy/internal/runtime/logging" +) + +func TestWithSlogTester(t *testing.T) { + buffer := bytes.NewBuffer(nil) + handler := logging.NewSlogGoKitHandler(log.NewLogfmtLogger(buffer)) + + err := slogtest.TestHandler(handler, func() []map[string]any { + results := []map[string]any{} + + dec := logfmt.NewDecoder(buffer) + for dec.ScanRecord() { + res := map[string]any{} + for dec.ScanKeyval() { + res[string(dec.Key())] = dec.Value() + } + results = append(results, res) + } + + require.NoError(t, dec.Err()) + return results + }) + require.NoError(t, err) +} + +func TestUpdateLevel(t *testing.T) { + buffer := bytes.NewBuffer(nil) + baseLogger, err := logging.New(buffer, logging.Options{Level: logging.LevelInfo, Format: logging.FormatLogfmt}) + require.NoError(t, err) + + gkLogger := log.With(baseLogger, "test", "test") + gkLogger.Log("msg", "hello") + require.Contains(t, buffer.String(), "ts=") + noTimestamp := strings.Join(strings.Split(buffer.String(), " ")[1:], " ") + require.Equal(t, "level=info msg=hello test=test\n", noTimestamp) + + sLogger := slog.New(logging.NewSlogGoKitHandler(gkLogger)) + buffer.Reset() + sLogger.Info("hello") + require.Contains(t, buffer.String(), "ts=") + noTimestamp = strings.Join(strings.Split(buffer.String(), " ")[1:], " ") + require.Equal(t, "level=info msg=hello test=test\n", noTimestamp) + + buffer.Reset() + sLogger.Debug("hello") + require.Equal(t, "", buffer.String()) + + err = baseLogger.Update(logging.Options{Level: logging.LevelDebug, Format: logging.FormatLogfmt}) + require.NoError(t, err) + + buffer.Reset() + sLogger.Info("hello") + require.Contains(t, buffer.String(), "ts=") + noTimestamp = strings.Join(strings.Split(buffer.String(), " ")[1:], " ") + require.Equal(t, "level=info msg=hello test=test\n", noTimestamp) + + buffer.Reset() + sLogger.Debug("hello") + require.Contains(t, buffer.String(), "ts=") + noTimestamp = strings.Join(strings.Split(buffer.String(), " ")[1:], " ") + require.Equal(t, "level=debug msg=hello test=test\n", noTimestamp) +} diff --git a/internal/static/integrations/mysqld_exporter/mysqld-exporter.go b/internal/static/integrations/mysqld_exporter/mysqld-exporter.go index eb01ab285c..475f28a72c 100644 --- a/internal/static/integrations/mysqld_exporter/mysqld-exporter.go +++ b/internal/static/integrations/mysqld_exporter/mysqld-exporter.go @@ -4,6 +4,7 @@ package mysqld_exporter //nolint:golint import ( "context" "fmt" + "log/slog" "os" config_util "github.com/prometheus/common/config" @@ -11,6 +12,8 @@ import ( "github.com/go-kit/log" "github.com/go-kit/log/level" "github.com/go-sql-driver/mysql" + + "github.com/grafana/alloy/internal/runtime/logging" "github.com/grafana/alloy/internal/static/integrations" integrations_v2 "github.com/grafana/alloy/internal/static/integrations/v2" "github.com/grafana/alloy/internal/static/integrations/v2/metricsutils" @@ -122,7 +125,8 @@ func New(log log.Logger, c *Config) (integrations.Integration, error) { } scrapers := GetScrapers(c) - exporter := collector.New(context.Background(), string(dsn), scrapers, log, collector.Config{ + logger := slog.New(logging.NewSlogGoKitHandler(log)) + exporter := collector.New(context.Background(), string(dsn), scrapers, logger, collector.Config{ LockTimeout: c.LockWaitTimeout, SlowLogFilter: c.LogSlowFilter, })