Skip to content

Commit

Permalink
Merge pull request #66 from muir/fiftyfour
Browse files Browse the repository at this point in the history
replace AdjustedLevelLoger with ContextLevelAdjuster, added LevelAdju…
  • Loading branch information
muir authored Sep 22, 2022
2 parents a08082d + aa1647e commit 842cbe2
Show file tree
Hide file tree
Showing 2 changed files with 125 additions and 44 deletions.
13 changes: 8 additions & 5 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,23 @@ all: $(ZZZGENERATED)
go generate ./...
go build ./...

test: $(ZZZGENERATED)
test: $(ZZZGENERATED) testadjuster
go generate ./...
go test -v ./xopjson/... -run TestASingleLine
go test -v ./xopjson/... -tags xoptesting -run TestParameters -failfast $(TEST_ONLY)
go test -tags xoptesting ./... -failfast $(TEST_ONLY)
go test -tags xoptesting -race ./... -failfast $(TEST_ONLY)
XOPLEVEL_xoptestutil=warn go test -tags xoptesting ./xoptest/xoptestutil -run TestAdjustedLevelLogger -count 1
XOPLEVEL_xoptestutil=debug go test -tags xoptesting ./xoptest/xoptestutil -run TestAdjustedLevelLogger -count 1


testadjuster: $(ZZZGenerated)
XOPLEVEL_xoptestutil=warn XOPLEVEL_foo=debug go test -tags xoptesting ./xoptest/xoptestutil -run TestAdjuster -count 1
XOPLEVEL_xoptestutil=debug XOPLEVEL_foo=warn go test -tags xoptesting ./xoptest/xoptestutil -run TestAdjuster -count 1

citest:
go test ./... -failfast
go test -race ./... -failfast
XOPLEVEL_xoptestutil=warn go test ./xoptest/xoptestutil -run TestAdjustedLevelLogger -count 1
XOPLEVEL_xoptestutil=debug go test ./xoptest/xoptestutil -run TestAdjustedLevelLogger -count 1
XOPLEVEL_xoptestutil=warn XOPLEVEL_foo=debug go test -tags xoptesting ./xoptest/xoptestutil -run TestAdjuster -count 1
XOPLEVEL_xoptestutil=debug XOPLEVEL_foo=warn go test -tags xoptesting ./xoptest/xoptestutil -run TestAdjuster -count 1

${GOBIN}/gofumpt:;
go install mvdan.cc/gofumpt@latest
Expand Down
156 changes: 117 additions & 39 deletions context.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,33 @@ func CustomFromContext(getLogFromContext func(context.Context) *Log, adjustSetti
}
}

// AdjustedLevelLogger returns a function that gets a logger from
// LevelAdjuster returns a function that adjusts the level of
// a logger for local package-scoped defaults. It is a sibling
// to AdjustedLevelLogger.
//
// The default behavior is to determine the name of the local
// package and then using that look at the environment variable
// "XOPLEVEL_<package_name>" (where <package_name> is the name of
// the current package) and set the minimum log level according
// to the value of that environment variable.
//
// package foo
// var adjustLogger = xop.LevelAdjuster()
//
func LevelAdjuster(opts ...AdjusterOption) func(*Log) *Log {
level := adjustConfig(opts)
if level == 0 {
return func(log *Log) *Log { return log }
}
return func(log *Log) *Log {
return log.Sub().MinLevel(level).Log()
}
}

// ContextLevelAdjuster returns a function that gets a logger from
// context. The logger it returns will have a minimum logging level
// that is specific for the calling package.
// that is specific for the calling package. If starting from a log
// instead of a context, use LevelAdjuster
//
// The level used will be the level set in this order:
// (1) From the environment variable "XOPLEVEL_foo" (for package foo). The level
Expand All @@ -72,54 +96,108 @@ func CustomFromContext(getLogFromContext func(context.Context) *Log, adjustSetti
// (3) The level that the logger already has.
//
// package foo
// var getLogger = xop.AdjustedLevelLoger(xop.FromContextOrPanic, xopnum.Info)
// var getLogger = xop.AdjustedLevelLoger(xop.FromContextOrPanic)
//
// package foo
// var getLogger = xop.AdjustedLevelLoger(xop.FromContextOrDefault, 0)
//
// TODO: change API on this to take func args
func AdjustedLevelLoger(getLogFromContext func(context.Context) *Log, level xopnum.Level) func(context.Context) *Log {
func ContextLevelAdjuster(getLogFromContext func(context.Context) *Log, opts ...AdjusterOption) func(context.Context) *Log {
level := adjustConfig(opts)
if level == 0 {
return getLogFromContext
}
return CustomFromContext(getLogFromContext, func(sub *Sub) *Sub {
return sub.MinLevel(level)
})
}

// WithPackage overrides how the package name is found. The
// package name is combined with "XOPLEVEL_" to create the
// name of the environment variable to check for adjusting
// log levels with LevelAdjuster and ContextLevelAdjuster
func WithPackage(pkg string) AdjusterOption {
return func(o *adjustOptions) {
o.pkg = pkg
}
}

// WithEnvironment overrides the name of the environment variable
// used to override log levels in LevelAdjuster and ContextLevelAdjuster.
// WithEnvironment makes the package name irrelevant and thus should
// not bue used in combination with WithPackage.
func WithEnvironment(environmentVariableName string) AdjusterOption {
return func(o *adjustOptions) {
o.env = environmentVariableName
}
}

// WithDefault sets a default logger level for LevelAdjuster and
// ContextLevelAdjuster. If the environment variable is found then
// that will override this default. This default will override the
// existing minimum logging level.
func WithDefault(level xopnum.Level) AdjusterOption {
return func(o *adjustOptions) {
o.level = level
}
}

// WithSkippedFrames is needed only if LevelAdjuster or ContextLevelAdjuster
// are called from withing another function that should not be used to
// derrive the package name.
func WithSkippedFrames(additionalFramesToSkip int) AdjusterOption {
return func(o *adjustOptions) {
o.skip = additionalFramesToSkip
}
}

type AdjusterOption func(*adjustOptions)

type adjustOptions struct {
pkg string
env string
level xopnum.Level
skip int
}

func adjustConfig(opts []AdjusterOption) xopnum.Level {
var options adjustOptions
for _, f := range opts {
f(&options)
}

pc := make([]uintptr, 1)
if runtime.Callers(2, pc) > 0 {
if options.pkg == "" && options.env == "" && runtime.Callers(3+options.skip, pc) > 0 {
frames := runtime.CallersFrames(pc)
frame, _ := frames.Next()
var pkg string
if frame.Function != "" {
// Example: github.com/muir/xop-go/xoptest/xoptestutil.foo.Context
// Example: github.com/muir/xop-go/xoptest/xoptestutil.TestAdjusterContext
// Example: github.com/muir/xop-go/xoptest/xoptestutil.init
if strings.HasSuffix(frame.Function, ".init") {
if i := strings.LastIndexByte(frame.Function, '/'); i != -1 {
pkg = frame.Function[i+1 : len(frame.Function)-len(".init")]
} else {
pkg = strings.TrimSuffix(frame.Function, ".init")
}
} else {
p := strings.Split(frame.Function, ".")
if p[0] != "" {
pkg = p[0]
}
base := filepath.Base(frame.Function)
parts := strings.SplitN(base, ".", 2)
if len(parts) == 2 {
options.pkg = parts[0]
}
}
if pkg == "" {
pkg = filepath.Base(filepath.Dir(frame.File))
if pkg == "." || pkg == "/" {
pkg = ""
if options.pkg == "" {
options.pkg = filepath.Base(filepath.Dir(frame.File))
if options.pkg == "." || options.pkg == "/" {
options.pkg = ""
}
}
if pkg != "" {
if ls, ok := os.LookupEnv("XOPLEVEL_" + pkg); ok {
lvl, err := xopnum.LevelString(ls)
if err == nil {
level = lvl
} else if i, err := strconv.ParseInt(ls, 10, 64); err == nil {
level = xopnum.Level(i)
}
}

if options.env == "" && options.pkg != "" {
options.env = "XOPLEVEL_" + options.pkg
}

if options.env != "" {
if ls, ok := os.LookupEnv(options.env); ok {
lvl, err := xopnum.LevelString(ls)
if err == nil {
options.level = lvl
} else if i, err := strconv.ParseInt(ls, 10, 64); err == nil {
options.level = xopnum.Level(i)
}
}
}
if level == 0 {
return getLogFromContext
}
return CustomFromContext(getLogFromContext, func(sub *Sub) *Sub {
return sub.MinLevel(level)
})

return options.level
}

0 comments on commit 842cbe2

Please sign in to comment.