Skip to content

Commit

Permalink
fix(log): improve the log system and solve memory leaks
Browse files Browse the repository at this point in the history
  • Loading branch information
qwqcode committed Apr 18, 2024
1 parent 3098a75 commit ee8c522
Show file tree
Hide file tree
Showing 12 changed files with 325 additions and 396 deletions.
4 changes: 2 additions & 2 deletions cmd/upgrade.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ func NewUpgradeCommand() *cobra.Command {
if !ignoreVersionCheck {
v := semver.MustParse(strings.TrimPrefix(config.Version, "v"))
if !found || latest.Version.LTE(v) {
log.Println(i18n.T("Current version is the latest") + " (v" + v.String() + ")")
log.Info(i18n.T("Current version is the latest") + " (v" + v.String() + ")")
return
}
}
Expand All @@ -49,7 +49,7 @@ func NewUpgradeCommand() *cobra.Command {
log.Fatal(i18n.T("Update failed")+" ", err)
}

log.Println(i18n.T("Update complete"))
log.Info(i18n.T("Update complete"))
fmt.Printf("\n"+
"-------------------------------\n"+
" v%s Release Note\n"+
Expand Down
17 changes: 7 additions & 10 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ require (
github.com/blang/semver v3.5.1+incompatible
github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874
github.com/cheggaaa/pb/v3 v3.1.5
github.com/eko/gocache/lib/v4 v4.1.5
github.com/eko/gocache/lib/v4 v4.1.6
github.com/eko/gocache/store/bigcache/v4 v4.2.1
github.com/eko/gocache/store/memcache/v4 v4.2.1
github.com/eko/gocache/store/redis/v4 v4.2.1
Expand All @@ -22,27 +22,27 @@ require (
github.com/jeremywohl/flatten v1.0.1
github.com/knadh/koanf v1.5.0
github.com/lionsoul2014/ip2region/binding/golang v0.0.0-20240322081424-40c7f53fc97c
github.com/mattn/go-colorable v0.1.13
github.com/microcosm-cc/bluemonday v1.0.26
github.com/nikoksr/notify v0.41.0
github.com/qwqcode/go-aliyun-email v0.0.0-20180120030821-cb6e7b1382bf
github.com/redis/go-redis/v9 v9.5.1
github.com/rhysd/go-github-selfupdate v1.2.3
github.com/rifflock/lfshook v0.0.0-20180920164130-b9218ef580f5
github.com/samber/lo v1.39.0
github.com/sirupsen/logrus v1.9.3
github.com/spf13/cobra v1.8.0
github.com/steambap/captcha v1.4.1
github.com/stretchr/testify v1.9.0
github.com/swaggo/swag v1.16.3
github.com/tidwall/gjson v1.17.1
github.com/vmihailenco/msgpack v4.0.4+incompatible
github.com/x-cray/logrus-prefixed-formatter v0.5.2
github.com/yuin/goldmark v1.7.1
go.uber.org/zap v1.27.0
golang.org/x/crypto v0.22.0
golang.org/x/exp v0.0.0-20240409090435-93d18d7e34b8
golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f
golang.org/x/sync v0.7.0
golang.org/x/term v0.19.0
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df
gopkg.in/natefinch/lumberjack.v2 v2.2.1
gopkg.in/yaml.v3 v3.0.1
gorm.io/driver/mysql v1.5.6
gorm.io/driver/postgres v1.5.7
Expand All @@ -54,7 +54,7 @@ require (
require (
filippo.io/edwards25519 v1.1.0 // indirect
github.com/ClickHouse/ch-go v0.61.5 // indirect
github.com/ClickHouse/clickhouse-go/v2 v2.23.0 // indirect
github.com/ClickHouse/clickhouse-go/v2 v2.23.1 // indirect
github.com/KyleBanks/depth v1.2.1 // indirect
github.com/VividCortex/ewma v1.2.0 // indirect
github.com/andybalholm/brotli v1.1.0 // indirect
Expand Down Expand Up @@ -95,17 +95,13 @@ require (
github.com/klauspost/compress v1.17.8 // indirect
github.com/line/line-bot-sdk-go v7.8.0+incompatible // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mattn/go-runewidth v0.0.15 // indirect
github.com/mattn/go-sqlite3 v1.14.22 // indirect
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect
github.com/microsoft/go-mssqldb v1.7.0 // indirect
github.com/mitchellh/copystructure v1.2.0 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/mitchellh/reflectwalk v1.0.2 // indirect
github.com/nxadm/tail v1.4.11 // indirect
github.com/onsi/ginkgo v1.16.5 // indirect
github.com/onsi/gomega v1.32.0 // indirect
github.com/paulmach/orb v0.11.1 // indirect
github.com/pierrec/lz4/v4 v4.1.21 // indirect
Expand Down Expand Up @@ -135,6 +131,7 @@ require (
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
go.opentelemetry.io/otel v1.25.0 // indirect
go.opentelemetry.io/otel/trace v1.25.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
golang.org/x/image v0.15.0 // indirect
golang.org/x/net v0.24.0 // indirect
golang.org/x/oauth2 v0.19.0 // indirect
Expand Down
47 changes: 14 additions & 33 deletions go.sum

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion internal/cache/base.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ package cache

import (
"context"
"log"
"strings"
"time"

"github.com/ArtalkJS/Artalk/internal/config"
"github.com/ArtalkJS/Artalk/internal/log"
"github.com/allegro/bigcache/v3"
"github.com/bradfitz/gomemcache/memcache"
lib_cache "github.com/eko/gocache/lib/v4/cache"
Expand Down
7 changes: 6 additions & 1 deletion internal/core/base.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ func (app *App) Bootstrap() error {
app.initI18n()

// log
log.LoadGlobal(log.Options{
log.Init(log.Options{
IsDiscard: !app.Conf().Log.Enabled,
IsDebug: app.Conf().Debug,
LogFile: app.Conf().Log.Filename,
Expand Down Expand Up @@ -149,6 +149,11 @@ func (app *App) ResetBootstrapState() error {
}
}

// sync log
if err := log.Sync(); err != nil {
return fmt.Errorf("log sync error: %w", err)
}

return nil
}

Expand Down
2 changes: 1 addition & 1 deletion internal/db/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (

func NewDB(conf config.DBConf) (*gorm.DB, error) {
gormConfig := &gorm.Config{
Logger: logger.NewGormLogger(),
Logger: logger.New(),
NamingStrategy: schema.NamingStrategy{
TablePrefix: conf.TablePrefix,
},
Expand Down
124 changes: 94 additions & 30 deletions internal/db/logger/logger.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,59 +3,123 @@ package logger
import (
"context"
"errors"
"path/filepath"
"runtime"
"strings"
"time"

"github.com/ArtalkJS/Artalk/internal/log"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
"gorm.io/gorm"
gormlogger "gorm.io/gorm/logger"
"gorm.io/gorm/utils"
gorm_logger "gorm.io/gorm/logger"
)

type gLogger struct {
SlowThreshold time.Duration
SourceField string
SkipErrRecordNotFound bool
var (
Info = gorm_logger.Info
Warn = gorm_logger.Warn
Error = gorm_logger.Error
Silent = gorm_logger.Silent
)

type ContextInfoGetterFn func(ctx context.Context) []zapcore.Field

type Logger struct {
LogLevel gorm_logger.LogLevel
SlowThreshold time.Duration
SkipCallerLookup bool
IgnoreRecordNotFoundError bool
ContextInfoGetter ContextInfoGetterFn
}

func NewGormLogger() *gLogger {
return &gLogger{
SkipErrRecordNotFound: true,
func New() Logger {
level := gorm_logger.Warn
if zap.L().Core().Enabled(zapcore.DebugLevel) {
level = gorm_logger.Info
}

return Logger{
LogLevel: level,
SlowThreshold: 100 * time.Millisecond,
SkipCallerLookup: false,
IgnoreRecordNotFoundError: true,
ContextInfoGetter: nil,
}
}

func (l *gLogger) LogMode(gormlogger.LogLevel) gormlogger.Interface {
return l
func (l Logger) SetAsDefault() {
gorm_logger.Default = l
}

func (l *gLogger) Info(ctx context.Context, s string, args ...interface{}) {
log.WithContext(ctx).Infof(s, args...)
func (l Logger) LogMode(level gorm_logger.LogLevel) gorm_logger.Interface {
l.LogLevel = level
return l
}

func (l *gLogger) Warn(ctx context.Context, s string, args ...interface{}) {
log.WithContext(ctx).Warnf(s, args...)
func (l Logger) Info(ctx context.Context, str string, args ...interface{}) {
if l.LogLevel < gorm_logger.Info {
return
}
l.logger(ctx).Sugar().Debugf(str, args...)
}

func (l *gLogger) Error(ctx context.Context, s string, args ...interface{}) {
log.WithContext(ctx).Errorf(s, args...)
func (l Logger) Warn(ctx context.Context, str string, args ...interface{}) {
if l.LogLevel < gorm_logger.Warn {
return
}
l.logger(ctx).Sugar().Warnf(str, args...)
}

func (l *gLogger) Trace(ctx context.Context, begin time.Time, fc func() (string, int64), err error) {
elapsed := time.Since(begin)
sql, _ := fc()
fields := log.Fields{}
if l.SourceField != "" {
fields[l.SourceField] = utils.FileWithLineNum()
}
if err != nil && !(errors.Is(err, gorm.ErrRecordNotFound) && l.SkipErrRecordNotFound) {
fields[log.ErrorKey] = err
log.WithContext(ctx).WithFields(fields).Errorf("%s [%s]", sql, elapsed)
func (l Logger) Error(ctx context.Context, str string, args ...interface{}) {
if l.LogLevel < gorm_logger.Error {
return
}
l.logger(ctx).Sugar().Errorf(str, args...)
}

if l.SlowThreshold != 0 && elapsed > l.SlowThreshold {
log.WithContext(ctx).WithFields(fields).Warnf("%s [%s]", sql, elapsed)
func (l Logger) Trace(ctx context.Context, begin time.Time, fc func() (string, int64), err error) {
if l.LogLevel <= 0 {
return
}
elapsed := time.Since(begin)
logger := l.logger(ctx)
switch {
case err != nil && l.LogLevel >= gorm_logger.Error && (!l.IgnoreRecordNotFoundError || !errors.Is(err, gorm.ErrRecordNotFound)):
sql, rows := fc()
logger.Error("[DB]", zap.Error(err), zap.Duration("elapsed", elapsed), zap.Int64("rows", rows), zap.String("sql", sql))
case l.SlowThreshold != 0 && elapsed > l.SlowThreshold && l.LogLevel >= gorm_logger.Warn:
sql, rows := fc()
logger.Warn("[DB]", zap.Duration("elapsed", elapsed), zap.Int64("rows", rows), zap.String("sql", sql))
case l.LogLevel >= gorm_logger.Info:
sql, rows := fc()
logger.Debug("[DB]", zap.Duration("elapsed", elapsed), zap.Int64("rows", rows), zap.String("sql", sql))
}
}

var (
gormPackage = filepath.Join("gorm.io", "gorm")
)

log.WithContext(ctx).WithFields(fields).Debugf("%s [%s]", sql, elapsed)
func (l Logger) logger(ctx context.Context) *zap.Logger {
logger := log.StandardLogger()
if l.ContextInfoGetter != nil {
fields := l.ContextInfoGetter(ctx)
logger = logger.With(fields...)
}

if l.SkipCallerLookup {
return logger
}

for i := 2; i < 15; i++ {
_, file, _, ok := runtime.Caller(i)
switch {
case !ok:
case strings.HasSuffix(file, "_test.go"): // skip test files
case strings.Contains(file, gormPackage): // skip gorm pkg
default:
return logger.WithOptions(zap.AddCallerSkip(i))
}
}
return logger
}
Loading

0 comments on commit ee8c522

Please sign in to comment.