Skip to content

Commit

Permalink
➕ add zap logger
Browse files Browse the repository at this point in the history
Signed-off-by: Rintaro Okamura <[email protected]>

:heavy_plus_sign: add zap logger

Signed-off-by: Rintaro Okamura <[email protected]>

:white_check_mark: add zap tests

Signed-off-by: Rintaro Okamura <[email protected]>

:white_check_mark: add zap tests

Signed-off-by: Rintaro Okamura <[email protected]>

:arrow_up: Upgrade zap and revise tests

Signed-off-by: Rintaro Okamura <[email protected]>
  • Loading branch information
rinx committed Jan 21, 2021
1 parent 347e7da commit 15c752e
Show file tree
Hide file tree
Showing 8 changed files with 2,187 additions and 0 deletions.
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ require (
go.opencensus.io v0.22.5
go.uber.org/automaxprocs v1.3.0
go.uber.org/goleak v1.1.10
go.uber.org/zap v1.16.0
golang.org/x/net v0.0.0-20210119194325-5f4716e94777
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -540,6 +540,8 @@ go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
go.uber.org/zap v1.14.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=
go.uber.org/zap v1.15.0 h1:ZZCA22JRF2gQE5FoNmhmrf7jeJJ2uhqDUNRYKm8dvmM=
go.uber.org/zap v1.15.0/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc=
go.uber.org/zap v1.16.0 h1:uFRZXykJGK9lLY4HtgSw44DnIcAM+kRBP7x5m+NpAOM=
go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ=
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad h1:DN0cp81fZ3njFcrLCytUHRSUkqBjfTo4Tx9RJTWs0EY=
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
Expand Down
12 changes: 12 additions & 0 deletions internal/log/log.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (

"github.com/vdaas/vald/internal/log/glg"
logger "github.com/vdaas/vald/internal/log/logger"
"github.com/vdaas/vald/internal/log/zap"
)

var (
Expand All @@ -40,6 +41,17 @@ func Init(opts ...Option) {

func getLogger(o *option) logger.Logger {
switch o.logType {
case logger.ZAP:
z, err := zap.New(
zap.WithLevel(o.level.String()),
zap.WithFormat(o.format.String()),
)
if err == nil {
return z
}

// fallback
fallthrough
case logger.GLG:
fallthrough
default:
Expand Down
18 changes: 18 additions & 0 deletions internal/log/log_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,24 @@ func Test_getLogger(t *testing.T) {
return nil
}
tests := []test{
func() test {
return test{
name: "returns zap object when *option.logType is ZAP",
args: args{
o: &option{
logType: logger.ZAP,
},
},
checkFunc: func(w want, got logger.Logger) error {
if got == nil {
return errors.New("got object is empty")
}

return nil
},
}
}(),

{
name: "returns glg object when *option.logType is GLG",
args: args{
Expand Down
56 changes: 56 additions & 0 deletions internal/log/zap/option.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
//
// Copyright (C) 2019-2020 Vdaas.org Vald team ( kpango, rinx, kmrmt )
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
package zap

import (
"github.com/vdaas/vald/internal/log/format"
"github.com/vdaas/vald/internal/log/level"
)

type Option func(l *logger)

var (
defaultOpts = []Option{
WithLevel(level.DEBUG.String()),
WithFormat(format.JSON.String()),
}
)

func WithLevel(lv string) Option {
return func(l *logger) {
if lv == "" {
return
}

l.level = level.Atol(lv)
}
}

func WithFormat(fmt string) Option {
return func(l *logger) {
if fmt == "" {
return
}

l.format = format.Atof(fmt)
}
}

func WithCaller(enable bool) Option {
return func(l *logger) {
l.enableCaller = enable
}
}
226 changes: 226 additions & 0 deletions internal/log/zap/option_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,226 @@
//
// Copyright (C) 2019-2020 Vdaas.org Vald team ( kpango, rinx, kmrmt )
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
package zap

import (
"reflect"
"testing"

"github.com/vdaas/vald/internal/errors"
"github.com/vdaas/vald/internal/log/format"
"github.com/vdaas/vald/internal/log/level"
"go.uber.org/goleak"
)

func TestWithLevel(t *testing.T) {
type T = logger
type args struct {
lv string
}
type want struct {
obj *T
}
type test struct {
name string
args args
want want
checkFunc func(want, *T) error
beforeFunc func(args)
afterFunc func(args)
}

defaultCheckFunc := func(w want, obj *T) error {
if !reflect.DeepEqual(obj, w.obj) {
return errors.Errorf("got: \"%#v\",\n\t\t\t\twant: \"%#v\"", obj, w.obj)
}
return nil
}

tests := []test{
{
name: "do nothing if lv is empty string",
args: args{
lv: "",
},
want: want{
obj: new(T),
},
},
{
name: "if lv is debug, DEBUG level will be set",
args: args{
lv: "debug",
},
want: want{
obj: &T{
level: level.DEBUG,
},
},
},
}

for _, test := range tests {
t.Run(test.name, func(tt *testing.T) {
defer goleak.VerifyNone(tt)
if test.beforeFunc != nil {
test.beforeFunc(test.args)
}
if test.afterFunc != nil {
defer test.afterFunc(test.args)
}

if test.checkFunc == nil {
test.checkFunc = defaultCheckFunc
}
got := WithLevel(test.args.lv)
obj := new(T)
got(obj)
if err := test.checkFunc(test.want, obj); err != nil {
tt.Errorf("error = %v", err)
}
})
}
}

func TestWithFormat(t *testing.T) {
type T = logger
type args struct {
fmt string
}
type want struct {
obj *T
}
type test struct {
name string
args args
want want
checkFunc func(want, *T) error
beforeFunc func(args)
afterFunc func(args)
}

defaultCheckFunc := func(w want, obj *T) error {
if !reflect.DeepEqual(obj, w.obj) {
return errors.Errorf("got: \"%#v\",\n\t\t\t\twant: \"%#v\"", obj, w.obj)
}
return nil
}

tests := []test{
{
name: "do nothing if fmt is empty string",
args: args{
fmt: "",
},
want: want{
obj: new(T),
},
},
{
name: "if fmt is json, JSON format will be set",
args: args{
fmt: "json",
},
want: want{
obj: &T{
format: format.JSON,
},
},
},
}

for _, test := range tests {
t.Run(test.name, func(tt *testing.T) {
defer goleak.VerifyNone(tt)
if test.beforeFunc != nil {
test.beforeFunc(test.args)
}
if test.afterFunc != nil {
defer test.afterFunc(test.args)
}
if test.checkFunc == nil {
test.checkFunc = defaultCheckFunc
}
got := WithFormat(test.args.fmt)
obj := new(T)
got(obj)
if err := test.checkFunc(test.want, obj); err != nil {
tt.Errorf("error = %v", err)
}
})
}
}

func TestWithCaller(t *testing.T) {
type T = logger
type args struct {
enable bool
}
type want struct {
obj *T
}
type test struct {
name string
args args
want want
checkFunc func(want, *T) error
beforeFunc func(args)
afterFunc func(args)
}

defaultCheckFunc := func(w want, obj *T) error {
if !reflect.DeepEqual(obj, w.obj) {
return errors.Errorf("got: \"%#v\",\n\t\t\t\twant: \"%#v\"", obj, w.obj)
}
return nil
}

tests := []test{
{
name: "given value will be set to enableCaller field",
args: args{
enable: true,
},
want: want{
obj: &T{
enableCaller: true,
},
},
},
}

for _, test := range tests {
t.Run(test.name, func(tt *testing.T) {
defer goleak.VerifyNone(tt)
if test.beforeFunc != nil {
test.beforeFunc(test.args)
}
if test.afterFunc != nil {
defer test.afterFunc(test.args)
}

if test.checkFunc == nil {
test.checkFunc = defaultCheckFunc
}
got := WithCaller(test.args.enable)
obj := new(T)
got(obj)
if err := test.checkFunc(test.want, obj); err != nil {
tt.Errorf("error = %v", err)
}
})
}
}
Loading

0 comments on commit 15c752e

Please sign in to comment.