Skip to content
This repository was archived by the owner on Jan 21, 2025. It is now read-only.
This repository was archived by the owner on Jan 21, 2025. It is now read-only.

fieldLogger should implement LevelEnabler #84

@jackieli-tes

Description

@jackieli-tes

here is my use case: playground link

package main

import (
	"fmt"

	"logur.dev/logur"
	"play.ground/logging"
)

type ml struct {
	logging.Logger
}

// Printf is like fmt.Printf
func (l *ml) Printf(format string, v ...interface{}) {
	l.Logger.Info(fmt.Sprintf(format, v...))
}

// Verbose should return true when verbose logging output is wanted
func (l *ml) Verbose() bool {
	return l.Logger.LevelEnabled(logur.Debug)
}
func main() {
	log := logging.NewLogrusLogger()
	migrateLog := ml{log}
	if migrateLog.Verbose() {
		migrateLog.Printf("hello migrate log")
	}

	log = log.WithField("foo", "bar")
	migrateLog = ml{log}
	if migrateLog.Verbose() {
		migrateLog.Printf("hello migrate log again")
	}
}
-- go.mod --
module play.ground
-- migrate/log.go --
package migrate

// migrate logger is taken from:
// https://pkg.go.dev/github.com/golang-migrate/migrate/v4#Logger

// Logger is an interface so you can pass in your own
// logging implementation.
type Logger interface {
	// Printf is like fmt.Printf
	Printf(format string, v ...interface{})

	// Verbose should return true when verbose logging output is wanted
	Verbose() bool
}
-- logging/logger.go --
package logging

import (
	"fmt"

	"github.com/sirupsen/logrus"
	logrusadapter "logur.dev/adapter/logrus"
	"logur.dev/logur"
)

// Logger is the fundamental interface for all log operations.
type Logger interface {
	Trace(msg string, fields ...map[string]interface{})
	Debug(msg string, fields ...map[string]interface{})
	Info(msg string, fields ...map[string]interface{})
	Warn(msg string, fields ...map[string]interface{})
	Error(msg string, fields ...map[string]interface{})

	// WithFields annotates a logger with some context and it as a new instance.
	WithFields(fields map[string]interface{}) Logger
	WithField(key string, value interface{}) Logger

	logur.LevelEnabler
}

type logger struct {
	logur.Logger
}

func (l *logger) WithFields(fields map[string]interface{}) Logger {
	return &logger{logur.WithFields(l, fields)}
}

func (l *logger) WithField(key string, value interface{}) Logger {
	return &logger{logur.WithField(l, key, value)}
}

func (l *logger) LevelEnabled(lvl logur.Level) bool {
	if ll, ok := l.Logger.(logur.LevelEnabler); ok {
		return ll.LevelEnabled(lvl)
	}
	fmt.Println("shouldn't reach here")
	return true
}

func NewLogrusLogger() Logger {
	rus := logrus.New()
	lvlstr := "debug" //os.Getenv("LOG_LEVEL")
	lvl, err := logrus.ParseLevel(lvlstr)
	if err != nil {
		rus.WithField("LOG_LEVEL", lvlstr).WithError(err).Warn("wrong level, using warn")
		lvl = logrus.WarnLevel
	}
	rus.SetLevel(lvl)

	l := logrusadapter.New(rus)
	return &logger{Logger: l}
}

When I use logur.WithField, it should really give me the LevelEnabler as well, otherwise there is no easy way for me to implement the LevelEnabled method

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions