-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
Add Objects and ObjectValues field constructors #1071
Conversation
Add a new Zap field constructor that encodes an array of zero or more Zap-marshalable objects into a Zap array. Usage: // Given, // // func (*User) MarshalLogObject(zapcore.ObjectEncoder) error zap.Objects("foo", []*User{u1, u2, u3}) Before this, users would have to resort to constructing a `[]*User` wrapper, and use Zap's `Array` constructor: // Before: type users []*User func (uu users) MarshalLogArray(enc zapcore.ArrayEncoder) error a for _, u := range uu { if err := enc.AppendObject(u); err != nil { return err } } return nil } zap.Array("foo", users{u1, u2, u3}) Credit to ztstewart for the suggestion. Refs GO-618 Reviewed-At: D7294727 Reviewed-By: ztstewart
Codecov Report
@@ Coverage Diff @@
## master #1071 +/- ##
==========================================
+ Coverage 98.19% 98.30% +0.10%
==========================================
Files 48 49 +1
Lines 2111 2120 +9
==========================================
+ Hits 2073 2084 +11
+ Misses 29 28 -1
+ Partials 9 8 -1
Continue to review full report at Codecov.
|
In the previous change, we added a Objects field constructor to support logging arrays of any object supported by zap.Object. func (*User) MarshalLogObject(...) error { ... } var users []*User = ... zap.Object("users", users) That solution is incomplete because it does not cover the case when, instead of a `[]*User`, we have a `[]User` despite the method being on `*User`. This change adds a similar ObjectValues field constructor that handles the case where we have a `[]T` but the MarshalLogObject is on `*T`. This works by declaring a new type constraint objectMarshalerPtr. `objectMarshalerPtr[T]` is true for a type that is a pointer to `T`, and implements zapcore.ObjectMarshaler. Note that we still do not cover the case where the method is on the value receiver (`func (User) MarshalLogObject(..) error`) and we have a `[]*User`. We can add that when it becomes necessary. Reviewed-At: D7295739 Reviewed-By: ztstewart
bb9b132
to
a648660
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
neat :) left a minor nit on the comment but LGTM otherwise.
Minor optimization to avoid copying the struct to a variable. Refs GO-618 Reviewed-At: D7297933 Reviewed-By: abhinav
staticcheck is expected to have support for generics-based code in a few weeks. Disable it until then.
This pull request adds two new field constructors for slices, parameterized
over the types of the values in the slices:
This turns a slice of any Zap marshalable object into a Zap field.
This is a variant of Objects for the case where
*T
implementszapcore.ObjectMarshaler
but we have a[]T
.Together, these two field constructors obviate the need for writing
ArrayMarshaler
implementations for slices of objects:Backwards compatibility
Both new field constructors are hidden behind a build tag, but use of type
parameters requires us to bump the
go
directive in thego.mod
file to 1.18.Note that this does not break Zap on Go 1.17.
Per the documentation for the
go
directive,It only breaks our ability to run
go mod tidy
inside Zap from Go 1.17,which is okay because with the
go
directive, we're stating that we'redeveloping Zap while on Go 1.18.
Linting
staticcheck support for type parameters is expected in a few weeks.
Meanwhile, this disables staticcheck for the
make lint
target.(I considered switching linting to Go 1.17 until then, but that isn't
enough because the formatting linter expects valid Go code--which type
parameters aren't in 1.17.)