Skip to content

Commit

Permalink
Merge branch 'master' into feature/logx-support-rotation-by-size-limit
Browse files Browse the repository at this point in the history
  • Loading branch information
SgtDaJim committed Jul 18, 2022
2 parents 141861d + 8d567b5 commit 086777c
Show file tree
Hide file tree
Showing 75 changed files with 1,594 additions and 280 deletions.
11 changes: 11 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates

version: 2
updates:
- package-ecosystem: "gomod" # See documentation for possible values
directory: "/" # Location of package manifests
schedule:
interval: "daily"
2 changes: 2 additions & 0 deletions core/discov/internal/registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -191,9 +191,11 @@ func (c *cluster) handleWatchEvents(key string, events []*clientv3.Event) {
})
}
case clientv3.EventTypeDelete:
c.lock.Lock()
if vals, ok := c.values[key]; ok {
delete(vals, string(ev.Kv.Key))
}
c.lock.Unlock()
for _, l := range listeners {
l.OnDelete(KV{
Key: string(ev.Kv.Key),
Expand Down
21 changes: 21 additions & 0 deletions core/errorx/wrap.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package errorx

import "fmt"

// Wrap returns an error that wraps err with given message.
func Wrap(err error, message string) error {
if err == nil {
return nil
}

return fmt.Errorf("%s: %w", message, err)
}

// Wrapf returns an error that wraps err with given format and args.
func Wrapf(err error, format string, args ...interface{}) error {
if err == nil {
return nil
}

return fmt.Errorf("%s: %w", fmt.Sprintf(format, args...), err)
}
24 changes: 24 additions & 0 deletions core/errorx/wrap_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package errorx

import (
"errors"
"testing"

"github.com/stretchr/testify/assert"
)

func TestWrap(t *testing.T) {
assert.Nil(t, Wrap(nil, "test"))
assert.Equal(t, "foo: bar", Wrap(errors.New("bar"), "foo").Error())

err := errors.New("foo")
assert.True(t, errors.Is(Wrap(err, "bar"), err))
}

func TestWrapf(t *testing.T) {
assert.Nil(t, Wrapf(nil, "%s", "test"))
assert.Equal(t, "foo bar: quz", Wrapf(errors.New("quz"), "foo %s", "bar").Error())

err := errors.New("foo")
assert.True(t, errors.Is(Wrapf(err, "foo %s", "bar"), err))
}
10 changes: 10 additions & 0 deletions core/jsonx/json.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,16 @@ func Marshal(v interface{}) ([]byte, error) {
return json.Marshal(v)
}

// MarshalToString marshals v into a string.
func MarshalToString(v interface{}) (string, error) {
data, err := Marshal(v)
if err != nil {
return "", err
}

return string(data), nil
}

// Unmarshal unmarshals data bytes into v.
func Unmarshal(data []byte, v interface{}) error {
decoder := json.NewDecoder(bytes.NewReader(data))
Expand Down
16 changes: 16 additions & 0 deletions core/jsonx/json_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,22 @@ func TestMarshal(t *testing.T) {
assert.Equal(t, `{"name":"John","age":30}`, string(bs))
}

func TestMarshalToString(t *testing.T) {
var v = struct {
Name string `json:"name"`
Age int `json:"age"`
}{
Name: "John",
Age: 30,
}
toString, err := MarshalToString(v)
assert.Nil(t, err)
assert.Equal(t, `{"name":"John","age":30}`, toString)

_, err = MarshalToString(make(chan int))
assert.NotNil(t, err)
}

func TestUnmarshal(t *testing.T) {
const s = `{"name":"John","age":30}`
var v struct {
Expand Down
49 changes: 29 additions & 20 deletions core/logx/tracelogger.go → core/logx/contextlogger.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,65 +11,65 @@ import (

// WithContext sets ctx to log, for keeping tracing information.
func WithContext(ctx context.Context) Logger {
return &traceLogger{
return &contextLogger{
ctx: ctx,
}
}

type traceLogger struct {
type contextLogger struct {
logEntry
ctx context.Context
}

func (l *traceLogger) Error(v ...interface{}) {
func (l *contextLogger) Error(v ...interface{}) {
l.err(fmt.Sprint(v...))
}

func (l *traceLogger) Errorf(format string, v ...interface{}) {
func (l *contextLogger) Errorf(format string, v ...interface{}) {
l.err(fmt.Sprintf(format, v...))
}

func (l *traceLogger) Errorv(v interface{}) {
func (l *contextLogger) Errorv(v interface{}) {
l.err(fmt.Sprint(v))
}

func (l *traceLogger) Errorw(msg string, fields ...LogField) {
func (l *contextLogger) Errorw(msg string, fields ...LogField) {
l.err(msg, fields...)
}

func (l *traceLogger) Info(v ...interface{}) {
func (l *contextLogger) Info(v ...interface{}) {
l.info(fmt.Sprint(v...))
}

func (l *traceLogger) Infof(format string, v ...interface{}) {
func (l *contextLogger) Infof(format string, v ...interface{}) {
l.info(fmt.Sprintf(format, v...))
}

func (l *traceLogger) Infov(v interface{}) {
func (l *contextLogger) Infov(v interface{}) {
l.info(v)
}

func (l *traceLogger) Infow(msg string, fields ...LogField) {
func (l *contextLogger) Infow(msg string, fields ...LogField) {
l.info(msg, fields...)
}

func (l *traceLogger) Slow(v ...interface{}) {
func (l *contextLogger) Slow(v ...interface{}) {
l.slow(fmt.Sprint(v...))
}

func (l *traceLogger) Slowf(format string, v ...interface{}) {
func (l *contextLogger) Slowf(format string, v ...interface{}) {
l.slow(fmt.Sprintf(format, v...))
}

func (l *traceLogger) Slowv(v interface{}) {
func (l *contextLogger) Slowv(v interface{}) {
l.slow(v)
}

func (l *traceLogger) Sloww(msg string, fields ...LogField) {
func (l *contextLogger) Sloww(msg string, fields ...LogField) {
l.slow(msg, fields...)
}

func (l *traceLogger) WithContext(ctx context.Context) Logger {
func (l *contextLogger) WithContext(ctx context.Context) Logger {
if ctx == nil {
return l
}
Expand All @@ -78,40 +78,49 @@ func (l *traceLogger) WithContext(ctx context.Context) Logger {
return l
}

func (l *traceLogger) WithDuration(duration time.Duration) Logger {
func (l *contextLogger) WithDuration(duration time.Duration) Logger {
l.Duration = timex.ReprOfDuration(duration)
return l
}

func (l *traceLogger) buildFields(fields ...LogField) []LogField {
func (l *contextLogger) buildFields(fields ...LogField) []LogField {
if len(l.Duration) > 0 {
fields = append(fields, Field(durationKey, l.Duration))
}

traceID := traceIdFromContext(l.ctx)
if len(traceID) > 0 {
fields = append(fields, Field(traceKey, traceID))
}

spanID := spanIdFromContext(l.ctx)
if len(spanID) > 0 {
fields = append(fields, Field(spanKey, spanID))
}

val := l.ctx.Value(fieldsContextKey)
if val != nil {
if arr, ok := val.([]LogField); ok {
fields = append(fields, arr...)
}
}

return fields
}

func (l *traceLogger) err(v interface{}, fields ...LogField) {
func (l *contextLogger) err(v interface{}, fields ...LogField) {
if shallLog(ErrorLevel) {
getWriter().Error(v, l.buildFields(fields...)...)
}
}

func (l *traceLogger) info(v interface{}, fields ...LogField) {
func (l *contextLogger) info(v interface{}, fields ...LogField) {
if shallLog(InfoLevel) {
getWriter().Info(v, l.buildFields(fields...)...)
}
}

func (l *traceLogger) slow(v interface{}, fields ...LogField) {
func (l *contextLogger) slow(v interface{}, fields ...LogField) {
if shallLog(ErrorLevel) {
getWriter().Slow(v, l.buildFields(fields...)...)
}
Expand Down
20 changes: 20 additions & 0 deletions core/logx/tracelogger_test.go → core/logx/contextlogger_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,25 @@ func TestTraceWithoutContext(t *testing.T) {
validate(t, w.String(), false, false)
}

func TestLogWithFields(t *testing.T) {
w := new(mockWriter)
old := writer.Swap(w)
writer.lock.RLock()
defer func() {
writer.lock.RUnlock()
writer.Store(old)
}()

ctx := WithFields(context.Background(), Field("foo", "bar"))
l := WithContext(ctx)
SetLevel(InfoLevel)
l.Info(testlog)

var val mockValue
assert.Nil(t, json.Unmarshal([]byte(w.String()), &val))
assert.Equal(t, "bar", val.Foo)
}

func validate(t *testing.T, body string, expectedTrace, expectedSpan bool) {
var val mockValue
dec := json.NewDecoder(strings.NewReader(body))
Expand All @@ -217,4 +236,5 @@ func validate(t *testing.T, body string, expectedTrace, expectedSpan bool) {
type mockValue struct {
Trace string `json:"trace"`
Span string `json:"span"`
Foo string `json:"foo"`
}
2 changes: 1 addition & 1 deletion core/logx/durationlogger.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ func (l *durationLogger) Sloww(msg string, fields ...LogField) {
}

func (l *durationLogger) WithContext(ctx context.Context) Logger {
return &traceLogger{
return &contextLogger{
ctx: ctx,
logEntry: logEntry{
Duration: l.Duration,
Expand Down
18 changes: 18 additions & 0 deletions core/logx/fields.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package logx

import "context"

var fieldsContextKey contextKey

type contextKey struct{}

// WithFields returns a new context with the given fields.
func WithFields(ctx context.Context, fields ...LogField) context.Context {
if val := ctx.Value(fieldsContextKey); val != nil {
if arr, ok := val.([]LogField); ok {
return context.WithValue(ctx, fieldsContextKey, append(arr, fields...))
}
}

return context.WithValue(ctx, fieldsContextKey, fields)
}
35 changes: 35 additions & 0 deletions core/logx/fields_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package logx

import (
"context"
"testing"

"github.com/stretchr/testify/assert"
)

func TestWithFields(t *testing.T) {
ctx := WithFields(context.Background(), Field("a", 1), Field("b", 2))
vals := ctx.Value(fieldsContextKey)
assert.NotNil(t, vals)
fields, ok := vals.([]LogField)
assert.True(t, ok)
assert.EqualValues(t, []LogField{Field("a", 1), Field("b", 2)}, fields)
}

func TestWithFieldsAppend(t *testing.T) {
var dummyKey struct{}
ctx := context.WithValue(context.Background(), dummyKey, "dummy")
ctx = WithFields(ctx, Field("a", 1), Field("b", 2))
ctx = WithFields(ctx, Field("c", 3), Field("d", 4))
vals := ctx.Value(fieldsContextKey)
assert.NotNil(t, vals)
fields, ok := vals.([]LogField)
assert.True(t, ok)
assert.Equal(t, "dummy", ctx.Value(dummyKey))
assert.EqualValues(t, []LogField{
Field("a", 1),
Field("b", 2),
Field("c", 3),
Field("d", 4),
}, fields)
}
4 changes: 3 additions & 1 deletion core/mapping/unmarshaler.go
Original file line number Diff line number Diff line change
Expand Up @@ -534,8 +534,10 @@ func (u *Unmarshaler) fillSliceValue(slice reflect.Value, index int,
baseKind reflect.Kind, value interface{}) error {
ithVal := slice.Index(index)
switch v := value.(type) {
case json.Number:
case fmt.Stringer:
return setValue(baseKind, ithVal, v.String())
case string:
return setValue(baseKind, ithVal, v)
default:
// don't need to consider the difference between int, int8, int16, int32, int64,
// uint, uint8, uint16, uint32, uint64, because they're handled as json.Number.
Expand Down

0 comments on commit 086777c

Please sign in to comment.