Skip to content

PMM-7 logrus to slog #1062

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 17 commits into from
Apr 24, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
6 changes: 3 additions & 3 deletions exporter/base_collector.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,23 +17,23 @@ package exporter

import (
"context"
"log/slog"
"sync"

"github.com/prometheus/client_golang/prometheus"
"github.com/sirupsen/logrus"
"go.mongodb.org/mongo-driver/mongo"
)

type baseCollector struct {
client *mongo.Client
logger *logrus.Entry
logger *slog.Logger

lock sync.Mutex
metricsCache []prometheus.Metric
}

// newBaseCollector creates a skeletal collector, which is used to create other collectors.
func newBaseCollector(client *mongo.Client, logger *logrus.Entry) *baseCollector {
func newBaseCollector(client *mongo.Client, logger *slog.Logger) *baseCollector {
return &baseCollector{
client: client,
logger: logger,
Expand Down
16 changes: 8 additions & 8 deletions exporter/collstats_collector.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ package exporter

import (
"context"
"log/slog"
"strings"

"github.com/prometheus/client_golang/prometheus"
"github.com/sirupsen/logrus"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo"
)
Expand All @@ -38,10 +38,10 @@ type collstatsCollector struct {
}

// newCollectionStatsCollector creates a collector for statistics about collections.
func newCollectionStatsCollector(ctx context.Context, client *mongo.Client, logger *logrus.Logger, discovery bool, topology labelsGetter, collections []string, enableDetails bool) *collstatsCollector {
func newCollectionStatsCollector(ctx context.Context, client *mongo.Client, logger *slog.Logger, discovery bool, topology labelsGetter, collections []string, enableDetails bool) *collstatsCollector {
return &collstatsCollector{
ctx: ctx,
base: newBaseCollector(client, logger.WithFields(logrus.Fields{"collector": "collstats"})),
base: newBaseCollector(client, logger.With("collector", "collstats")),

compatibleMode: false, // there are no compatible metrics for this collector.
discoveringMode: discovery,
Expand Down Expand Up @@ -70,7 +70,7 @@ func (d *collstatsCollector) collect(ch chan<- prometheus.Metric) {
if d.discoveringMode {
onlyCollectionsNamespaces, err := listAllCollections(d.ctx, client, d.collections, systemDBs, true)
if err != nil {
logger.Errorf("cannot auto discover databases and collections: %s", err.Error())
logger.Error("cannot auto discover databases and collections", "error", err.Error())

return
}
Expand All @@ -80,7 +80,7 @@ func (d *collstatsCollector) collect(ch chan<- prometheus.Metric) {
var err error
collections, err = checkNamespacesForViews(d.ctx, client, d.collections)
if err != nil {
logger.Errorf("cannot list collections: %s", err.Error())
logger.Error("cannot list collections", "error", err.Error())
return
}
}
Expand Down Expand Up @@ -126,19 +126,19 @@ func (d *collstatsCollector) collect(ch chan<- prometheus.Metric) {

cursor, err := client.Database(database).Collection(collection).Aggregate(d.ctx, pipeline)
if err != nil {
logger.Errorf("cannot get $collstats cursor for collection %s.%s: %s", database, collection, err)
logger.Error("cannot get $collstats cursor for collection", "database", database, "collection", collection, "error", err)

continue
}

var stats []bson.M
if err = cursor.All(d.ctx, &stats); err != nil {
logger.Errorf("cannot get $collstats for collection %s.%s: %s", database, collection, err)
logger.Error("cannot get $collstats for collection", "database", database, "collection", collection, "error", err)

continue
}

logger.Debugf("$collStats metrics for %s.%s", database, collection)
logger.Debug("$collStats metrics", "database", database, "collection", collection)
debugResult(logger, stats)

prefix := "collstats"
Expand Down
4 changes: 2 additions & 2 deletions exporter/collstats_collector_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import (
"time"

"github.com/prometheus/client_golang/prometheus/testutil"
"github.com/sirupsen/logrus"
"github.com/prometheus/common/promslog"
"github.com/stretchr/testify/assert"
"go.mongodb.org/mongo-driver/bson"

Expand Down Expand Up @@ -53,7 +53,7 @@ func TestCollStatsCollector(t *testing.T) {
ti := labelsGetterMock{}

collection := []string{"testdb.testcol_00", "testdb.testcol_01", "testdb.testcol_02"}
logger := logrus.New()
logger := promslog.New(&promslog.Config{})
c := newCollectionStatsCollector(ctx, client, logger, false, ti, collection, false)

// The last \n at the end of this string is important
Expand Down
25 changes: 13 additions & 12 deletions exporter/currentop_collector.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,13 @@ package exporter

import (
"context"
"fmt"
"log/slog"
"strconv"
"time"

"github.com/pkg/errors"
"github.com/prometheus/client_golang/prometheus"
"github.com/sirupsen/logrus"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo"
Expand All @@ -39,12 +40,12 @@ type currentopCollector struct {
var ErrInvalidOrMissingInprogEntry = errors.New("invalid or missing inprog entry in currentop results")

// newCurrentopCollector creates a collector for being processed queries.
func newCurrentopCollector(ctx context.Context, client *mongo.Client, logger *logrus.Logger,
func newCurrentopCollector(ctx context.Context, client *mongo.Client, logger *slog.Logger,
compatible bool, topology labelsGetter, currentOpSlowTime string,
) *currentopCollector {
return &currentopCollector{
ctx: ctx,
base: newBaseCollector(client, logger.WithFields(logrus.Fields{"collector": "currentop"})),
base: newBaseCollector(client, logger.With("collector", "currentop")),
compatibleMode: compatible,
topologyInfo: topology,
currentopslowtime: currentOpSlowTime,
Expand All @@ -66,7 +67,7 @@ func (d *currentopCollector) collect(ch chan<- prometheus.Metric) {
client := d.base.client
slowtime, err := time.ParseDuration(d.currentopslowtime)
if err != nil {
logger.Errorf("Failed to parse slowtime: %s", err)
logger.Error("Failed to parse slowtime", "error", err)
ch <- prometheus.NewInvalidMetric(prometheus.NewInvalidDesc(err), err)
return
}
Expand All @@ -90,7 +91,7 @@ func (d *currentopCollector) collect(ch chan<- prometheus.Metric) {

var r primitive.M
if err := res.Decode(&r); err != nil {
logger.Errorf("Failed to decode currentOp response: %s", err)
logger.Error("Failed to decode currentOp response", "error", err)
ch <- prometheus.NewInvalidMetric(prometheus.NewInvalidDesc(err), err)
return
}
Expand All @@ -101,7 +102,7 @@ func (d *currentopCollector) collect(ch chan<- prometheus.Metric) {
inprog, ok := r["inprog"].(primitive.A)

if !ok {
logger.Errorf("Invalid type primitive.A assertion for 'inprog': %T", r["inprog"])
logger.Error(fmt.Sprintf("Invalid type primitive.A assertion for 'inprog': %T", r["inprog"]))
ch <- prometheus.NewInvalidMetric(prometheus.NewInvalidDesc(ErrInvalidOrMissingInprogEntry),
ErrInvalidOrMissingInprogEntry)
}
Expand All @@ -115,33 +116,33 @@ func (d *currentopCollector) collect(ch chan<- prometheus.Metric) {

bsonMapElement, ok := bsonMap.(primitive.M)
if !ok {
logger.Errorf("Invalid type primitive.M assertion for bsonMap: %T", bsonMapElement)
logger.Error(fmt.Sprintf("Invalid type primitive.M assertion for bsonMap: %T", bsonMapElement))
continue
}
opid, ok := bsonMapElement["opid"].(int32)
if !ok {
logger.Errorf("Invalid type int32 assertion for 'opid': %T", bsonMapElement)
logger.Error(fmt.Sprintf("Invalid type int32 assertion for 'opid': %T", bsonMapElement))
continue
}
namespace, ok := bsonMapElement["ns"].(string)
if !ok {
logger.Errorf("Invalid type string assertion for 'ns': %T", bsonMapElement)
logger.Error(fmt.Sprintf("Invalid type string assertion for 'ns': %T", bsonMapElement))
continue
}
db, collection := splitNamespace(namespace)
op, ok := bsonMapElement["op"].(string)
if !ok {
logger.Errorf("Invalid type string assertion for 'op': %T", bsonMapElement)
logger.Error(fmt.Sprintf("Invalid type string assertion for 'op': %T", bsonMapElement))
continue
}
desc, ok := bsonMapElement["desc"].(string)
if !ok {
logger.Errorf("Invalid type string assertion for 'desc': %T", bsonMapElement)
logger.Error(fmt.Sprintf("Invalid type string assertion for 'desc': %T", bsonMapElement))
continue
}
microsecs_running, ok := bsonMapElement["microsecs_running"].(int64)
if !ok {
logger.Errorf("Invalid type int64 assertion for 'microsecs_running': %T", bsonMapElement)
logger.Error(fmt.Sprintf("Invalid type int64 assertion for 'microsecs_running': %T", bsonMapElement))
continue
}

Expand Down
4 changes: 2 additions & 2 deletions exporter/currentop_collector_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import (
"time"

"github.com/prometheus/client_golang/prometheus/testutil"
"github.com/sirupsen/logrus"
"github.com/prometheus/common/promslog"
"github.com/stretchr/testify/assert"
"go.mongodb.org/mongo-driver/bson"

Expand Down Expand Up @@ -60,7 +60,7 @@ func TestCurrentopCollector(t *testing.T) {
ti := labelsGetterMock{}
st := "0s"

c := newCurrentopCollector(ctx, client, logrus.New(), false, ti, st)
c := newCurrentopCollector(ctx, client, promslog.New(&promslog.Config{}), false, ti, st)

// Filter metrics by reason:
// 1. The result will be different on different hardware
Expand Down
14 changes: 7 additions & 7 deletions exporter/dbstats_collector.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ package exporter

import (
"context"
"log/slog"

"github.com/prometheus/client_golang/prometheus"
"github.com/sirupsen/logrus"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo"
)
Expand All @@ -37,10 +37,10 @@ type dbstatsCollector struct {
}

// newDBStatsCollector creates a collector for statistics on database storage.
func newDBStatsCollector(ctx context.Context, client *mongo.Client, logger *logrus.Logger, compatible bool, topology labelsGetter, databaseRegex []string, freeStorage bool) *dbstatsCollector {
func newDBStatsCollector(ctx context.Context, client *mongo.Client, logger *slog.Logger, compatible bool, topology labelsGetter, databaseRegex []string, freeStorage bool) *dbstatsCollector {
return &dbstatsCollector{
ctx: ctx,
base: newBaseCollector(client, logger.WithFields(logrus.Fields{"collector": "dbstats"})),
base: newBaseCollector(client, logger.With("collector", "dbstats")),

compatibleMode: compatible,
topologyInfo: topology,
Expand All @@ -67,12 +67,12 @@ func (d *dbstatsCollector) collect(ch chan<- prometheus.Metric) {

dbNames, err := databases(d.ctx, client, d.databaseFilter, nil)
if err != nil {
logger.Errorf("Failed to get database names: %s", err)
logger.Error("Failed to get database names", "error", err)

return
}

logger.Debugf("getting stats for databases: %v", dbNames)
logger.Debug("getting stats for databases", "databases", dbNames)
for _, db := range dbNames {
var dbStats bson.M
var cmd bson.D
Expand All @@ -84,12 +84,12 @@ func (d *dbstatsCollector) collect(ch chan<- prometheus.Metric) {
r := client.Database(db).RunCommand(d.ctx, cmd)
err := r.Decode(&dbStats)
if err != nil {
logger.Errorf("Failed to get $dbstats for database %s: %s", db, err)
logger.Error("Failed to get $dbstats for database", "database", db, "error", err)

continue
}

logger.Debugf("$dbStats metrics for %s", db)
logger.Debug("$dbStats metrics for", "database", db)
debugResult(logger, dbStats)

prefix := "dbstats"
Expand Down
4 changes: 2 additions & 2 deletions exporter/dbstats_collector_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import (
"time"

"github.com/prometheus/client_golang/prometheus/testutil"
"github.com/sirupsen/logrus"
"github.com/prometheus/common/promslog"
"github.com/stretchr/testify/assert"
"go.mongodb.org/mongo-driver/bson"

Expand Down Expand Up @@ -58,7 +58,7 @@ func TestDBStatsCollector(t *testing.T) {

ti := labelsGetterMock{}

logger := logrus.New()
logger := promslog.New(&promslog.Config{})
c := newDBStatsCollector(ctx, client, logger, false, ti, []string{dbName}, false)
expected := strings.NewReader(`
# HELP mongodb_dbstats_collections dbstats.collections
Expand Down
12 changes: 6 additions & 6 deletions exporter/debug.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,25 +16,25 @@
package exporter

import (
"context"
"encoding/json"
"fmt"
"log/slog"
"os"

"github.com/sirupsen/logrus"
)

func debugResult(log *logrus.Entry, m interface{}) {
if !log.Logger.IsLevelEnabled(logrus.DebugLevel) {
func debugResult(log *slog.Logger, m interface{}) {
if !log.Enabled(context.TODO(), slog.LevelDebug) {
return
}

debugStr, err := json.MarshalIndent(m, "", " ")
if err != nil {
log.Errorf("cannot marshal struct for debug: %s", err)
log.Error("cannot marshal struct for debug", "error", err)
return
}

// don't use logrus because:
// don't use the passed-in logger because:
// 1. It will escape new lines and " making it harder to read and to use
// 2. It will add timestamp
// 3. This way is easier to copy/paste to put the info in a ticket
Expand Down
17 changes: 11 additions & 6 deletions exporter/debug_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,25 +20,30 @@ import (
"os"
"testing"

"github.com/sirupsen/logrus"
"github.com/prometheus/common/promslog"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"go.mongodb.org/mongo-driver/bson"
)

func TestDebug(t *testing.T) {
log := logrus.New()
log.SetLevel(logrus.DebugLevel)
logLevel := promslog.NewLevel()
err := logLevel.Set("debug")
require.NoError(t, err)

olderr := os.Stderr
r, w, _ := os.Pipe()

os.Stderr = w
defer func() {
os.Stderr = olderr
logrus.SetLevel(logrus.ErrorLevel)
_ = logLevel.Set("error")
}()

log.Out = w
log := promslog.New(&promslog.Config{
Level: logLevel,
Writer: w,
})

m := bson.M{
"f1": 1,
Expand All @@ -55,7 +60,7 @@ func TestDebug(t *testing.T) {
}
}` + "\n"

debugResult(log.WithField("component", "test"), m)
debugResult(log.With("component", "test"), m)
assert.NoError(t, w.Close())
out, _ := io.ReadAll(r)

Expand Down
Loading
Loading