Skip to content

Commit

Permalink
Enhance internal logging (#3900)
Browse files Browse the repository at this point in the history
* Introduce `Warn` function in global package

* Cover log levels with tests

---------

Co-authored-by: Robert Pająk <pellared@hotmail.com>
Co-authored-by: Aaron Clawson <3766680+MadVikingGod@users.noreply.github.com>
  • Loading branch information
3 people authored Mar 21, 2023
1 parent 3c75a44 commit 1eab60f
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 6 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
- The new `Exemplar` type is added to `go.opentelemetry.io/otel/sdk/metric/metricdata`.
Both the `DataPoint` and `HistogramDataPoint` types from that package have a new field of `Exemplars` containing the sampled exemplars for their timeseries. (#3849)
- Configuration for each metric instrument in `go.opentelemetry.io/otel/sdk/metric/instrument`. (#3895)
- The internal logging introduces a warning level verbosity equal to `V(1)`. (#3900)

### Changed

Expand All @@ -29,6 +30,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
- `NewNoopMeter` is replaced with `noop.NewMeterProvider().Meter("")`
- Rename `Int64ObserverOption` to `Int64ObservableOption` in `go.opentelemetry.io/otel/metric/instrument`. (#3895)
- Rename `Float64ObserverOption` to `Float64ObservableOption` in `go.opentelemetry.io/otel/metric/instrument`. (#3895)
- The internal logging changes the verbosity level of info to `V(4)`, the verbosity level of debug to `V(8)`. (#3900)

### Removed

Expand Down
19 changes: 13 additions & 6 deletions internal/global/internal_logging.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import (
"github.com/go-logr/stdr"
)

// globalLogger is the logging interface used within the otel api and sdk provide deatails of the internals.
// globalLogger is the logging interface used within the otel api and sdk provide details of the internals.
//
// The default logger uses stdr which is backed by the standard `log.Logger`
// interface. This logger will only show messages at the Error Level.
Expand All @@ -36,8 +36,9 @@ func init() {

// SetLogger overrides the globalLogger with l.
//
// To see Info messages use a logger with `l.V(1).Enabled() == true`
// To see Debug messages use a logger with `l.V(5).Enabled() == true`.
// To see Warn messages use a logger with `l.V(1).Enabled() == true`
// To see Info messages use a logger with `l.V(4).Enabled() == true`
// To see Debug messages use a logger with `l.V(8).Enabled() == true`.
func SetLogger(l logr.Logger) {
atomic.StorePointer(&globalLogger, unsafe.Pointer(&l))
}
Expand All @@ -47,9 +48,9 @@ func getLogger() logr.Logger {
}

// Info prints messages about the general state of the API or SDK.
// This should usually be less then 5 messages a minute.
// This should usually be less than 5 messages a minute.
func Info(msg string, keysAndValues ...interface{}) {
getLogger().V(1).Info(msg, keysAndValues...)
getLogger().V(4).Info(msg, keysAndValues...)
}

// Error prints messages about exceptional states of the API or SDK.
Expand All @@ -59,5 +60,11 @@ func Error(err error, msg string, keysAndValues ...interface{}) {

// Debug prints messages about all internal changes in the API or SDK.
func Debug(msg string, keysAndValues ...interface{}) {
getLogger().V(5).Info(msg, keysAndValues...)
getLogger().V(8).Info(msg, keysAndValues...)
}

// Warn prints messages about warnings in the API or SDK.
// Not an error but is likely more important than an informational event.
func Warn(msg string, keysAndValues ...interface{}) {
getLogger().V(1).Info(msg, keysAndValues...)
}
68 changes: 68 additions & 0 deletions internal/global/internal_logging_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,82 @@
package global

import (
"bytes"
"errors"
"log"
"os"
"testing"

"github.com/go-logr/logr"

"github.com/stretchr/testify/assert"

"github.com/go-logr/logr/funcr"
"github.com/go-logr/stdr"
)

func TestRace(t *testing.T) {
go SetLogger(stdr.New(log.New(os.Stderr, "", 0)))
go Info("")
}

func TestLogLevel(t *testing.T) {
tests := []struct {
name string
verbosity int
logF func()
want string
}{
{
name: "Verbosity 0 should log errors.",
verbosity: 0,
want: `"msg"="foobar" "error"="foobar"`,
logF: func() {
Error(errors.New("foobar"), "foobar")
},
},
{
name: "Verbosity 1 should log warnings",
verbosity: 1,
want: `"level"=1 "msg"="foo"`,
logF: func() {
Warn("foo")
},
},
{
name: "Verbosity 4 should log info",
verbosity: 4,
want: `"level"=4 "msg"="bar"`,
logF: func() {
Info("bar")
},
},
{
name: "Verbosity 8 should log debug",
verbosity: 8,
want: `"level"=8 "msg"="baz"`,
logF: func() {
Debug("baz")
},
},
}

for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
var buf bytes.Buffer
SetLogger(newBuffLogger(&buf, test.verbosity))

test.logF()

assert.Equal(t, test.want, buf.String())
})
}
}

func newBuffLogger(buf *bytes.Buffer, verbosity int) logr.Logger {
return funcr.New(func(prefix, args string) {
_, _ = buf.Write([]byte(args))
}, funcr.Options{
Verbosity: verbosity,
})
}

0 comments on commit 1eab60f

Please sign in to comment.