Skip to content

Commit

Permalink
add: 重构log
Browse files Browse the repository at this point in the history
  • Loading branch information
moocss committed Nov 22, 2024
1 parent 95724e3 commit f3a8c1c
Show file tree
Hide file tree
Showing 28 changed files with 1,284 additions and 276 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module github.com/apus-run/van

go 1.22
go 1.23

replace github.com/ugorji/go => github.com/ugorji/go v1.2.12

Expand Down
13 changes: 0 additions & 13 deletions log/slog/attr.go

This file was deleted.

68 changes: 68 additions & 0 deletions log/slog/attrs.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package slog

import (
"log/slog"
"time"
)

var ErrorKey = "error"

func ErrorString(err error) Attr {
return slog.String(ErrorKey, err.Error())
}

func ErrorValue(err error) slog.Value {
return slog.StringValue(err.Error())
}

// TimeValue returns a Value for a time.Time.
// It discards the monotonic portion.
func TimeValue(v time.Time) any {
return uint64(v.UnixNano())
}

// DurationValue returns a Value for a time.Duration.
func DurationValue(v time.Duration) uint64 {
return uint64(v.Nanoseconds())
}

func String(key, v string) Attr {
return slog.String(key, v)
}

func Int64(key string, v int64) Attr {
return slog.Int64(key, v)
}

func Int(key string, v int) Attr {
return slog.Int(key, v)
}

// Uint64 returns an Attr for a uint64.
func Uint64(key string, v uint64) Attr {
return slog.Uint64(key, v)
}

func Float64(key string, v float64) Attr {
return slog.Float64(key, v)
}

func Bool(key string, v bool) Attr {
return slog.Bool(key, v)
}

func Time(key string, v time.Time) Attr {
return slog.Time(key, v)
}

func Duration(key string, v time.Duration) Attr {
return slog.Duration(key, v)
}

func Group(key string, args ...any) Attr {
return slog.Group(key, args...)
}

func Any(key string, v any) Attr {
return slog.Any(key, v)
}
21 changes: 11 additions & 10 deletions log/slog/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,30 @@ package slog

import (
"context"
"log/slog"
)

type ContextLogKey struct{}

func NewContext(ctx context.Context, l *slog.Logger) context.Context {
func NewContext(ctx context.Context, l *SlogLogger) context.Context {
return context.WithValue(ctx, ContextLogKey{}, l)
}

func WithContext(ctx context.Context, l *slog.Logger) context.Context {
if _, ok := ctx.Value(ContextLogKey{}).(*slog.Logger); ok {
func WithContext(ctx context.Context, l *SlogLogger) context.Context {
if _, ok := ctx.Value(ContextLogKey{}).(*SlogLogger); ok {
return ctx
}
return context.WithValue(ctx, ContextLogKey{}, l)
}

func FromContext(ctx context.Context) *slog.Logger {
if l, ok := ctx.Value(ContextLogKey{}).(*slog.Logger); ok {
func FromContext(ctx context.Context) *SlogLogger {
if l, ok := ctx.Value(ContextLogKey{}).(*SlogLogger); ok {
return l
}
return slog.Default()
return nil
}

//func log(ctx context.Context, level slog.Level, msg string, args ...any) {
// FromContext(ctx).Log(ctx, level, msg, args...)
//}
// C represents for `FromContext` with empty keyvals.
// slog.C(ctx).Info("Set function called")
func C(ctx context.Context) *SlogLogger {
return FromContext(ctx)
}
53 changes: 53 additions & 0 deletions log/slog/format.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package slog

import (
"fmt"
)

// sprint is a function that takes a variadic parameter of type interface{} and returns a string.
// The function works as follows:
// - If no arguments are provided, it returns an empty string.
// - If a single argument is provided:
// - If the argument is of type string, it returns the string as is.
// - If the argument is not of type string but implements the fmt.Stringer interface, it returns the string representation of the argument.
// - If the argument is not of type string and does not implement the fmt.Stringer interface, it converts the argument to a string using fmt.Sprint and returns the result.
//
// - If more than one argument is provided, it converts all arguments to a string using fmt.Sprint and returns the result.
func sprint(a ...any) string {
if len(a) == 0 {
return ""
} else if len(a) == 1 {
if s, ok := a[0].(string); ok {
return s
} else if v, ok := a[0].(fmt.Stringer); ok {
return v.String()
} else {
return fmt.Sprint(a...)
}
} else {
return fmt.Sprint(a...)
}
}

// sprintf is a function that takes a string template and a variadic parameter of type interface{} and returns a string.
// The function works as follows:
// - If no arguments are provided, it returns the template string as is.
// - If the template string is not empty, it formats the string using fmt.Sprintf with the provided arguments and returns the result.
// - If only one argument is provided and it is of type string, it returns the string as is.
// - Otherwise, it converts the arguments to a string using the sprint function and returns the result.
func sprintf(template string, args ...any) string {
if len(args) == 0 {
return template
}

if template != "" {
return fmt.Sprintf(template, args...)
}

if len(args) == 1 {
if str, ok := args[0].(string); ok {
return str
}
}
return sprint(args...)
}
120 changes: 120 additions & 0 deletions log/slog/format_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
package slog

import (
"fmt"
"testing"
)

func Test_sprint(t *testing.T) {
tests := []struct {
name string
args []interface{}
want string
}{
{
name: "NoArgs",
args: []interface{}{},
want: "",
},
{
name: "WithOneArgString",
args: []interface{}{"arg1"},
want: "arg1",
},
{
name: "WithOneArgNotString",
args: []interface{}{123},
want: "123",
},
{
name: "WithMultipleArgsString",
args: []interface{}{"arg1", "arg2"},
want: "arg1arg2",
},
{
name: "WithMultipleArgsNotString",
args: []interface{}{123, 456},
want: "123 456",
},
{
name: "WithErrorArgs",
args: []interface{}{fmt.Errorf("error message")},
want: "error message",
},
{
name: "WithStringerArgs",
args: []interface{}{stringer{str: "stringer"}},
want: "stringer",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := sprint(tt.args...); got != tt.want {
t.Errorf("sprint() = %v, want %v", got, tt.want)
}
})
}
}

func Test_sprintf(t *testing.T) {
type args struct {
template string
args []interface{}
}
tests := []struct {
name string
args args
want string
}{
{
name: "NoArgs",
args: args{template: "template", args: []interface{}{}},
want: "template",
},
{
name: "WithTemplateAndOneArg",
args: args{template: "template %s", args: []interface{}{"arg1"}},
want: "template arg1",
},
{
name: "WithTemplateAndMultipleArgs",
args: args{template: "template %s %s", args: []interface{}{"arg1", "arg2"}},
want: "template arg1 arg2",
},
{
name: "WithOneArgNotString",
args: args{template: "", args: []interface{}{123}},
want: "123",
},
{
name: "WithMultipleArgsNotString",
args: args{template: "", args: []interface{}{123, 456}},
want: "123 456",
},
{
name: "WithErrorArgs",
args: args{template: "", args: []interface{}{fmt.Errorf("error message")}},
want: "error message",
},
{
name: "WithStringerArgs",
args: args{template: "", args: []interface{}{stringer{str: "stringer"}}},
want: "stringer",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := sprintf(tt.args.template, tt.args.args...); got != tt.want {
t.Errorf("sprintf() = %v, want %v", got, tt.want)
}
})
}
}

type stringer struct {
str string
}

func (s stringer) String() string {
return s.str
}
Loading

0 comments on commit f3a8c1c

Please sign in to comment.