feat: add logging

This commit is contained in:
lab
2021-12-28 00:49:57 +08:00
parent 632a2d42c2
commit a1f8fad872
5 changed files with 403 additions and 0 deletions

View File

@@ -0,0 +1,71 @@
package gormlogrus
import (
"context"
"errors"
"fmt"
"time"
"github.com/sirupsen/logrus"
"gorm.io/gorm"
gormlogger "gorm.io/gorm/logger"
"gorm.io/gorm/utils"
)
type GormLogrusAdapter struct {
SlowThreshold time.Duration
SourceField string
SkipErrRecordNotFound bool
Logger logrus.FieldLogger
}
func New(logger logrus.FieldLogger) *GormLogrusAdapter {
return &GormLogrusAdapter{
Logger: logger,
SkipErrRecordNotFound: false,
SourceField: "gorm",
SlowThreshold: 1 * time.Second,
}
}
func (l *GormLogrusAdapter) LogMode(gormlogger.LogLevel) gormlogger.Interface {
return l
}
func (l *GormLogrusAdapter) Info(ctx context.Context, s string, args ...interface{}) {
l.Logger.Infof(s, args)
}
func (l *GormLogrusAdapter) Warn(ctx context.Context, s string, args ...interface{}) {
logrus.Warnf(s, args)
}
func (l *GormLogrusAdapter) Error(ctx context.Context, s string, args ...interface{}) {
logrus.Errorf(s, args)
}
func (l *GormLogrusAdapter) Trace(ctx context.Context, begin time.Time, fc func() (string, int64), err error) {
elapsed := time.Since(begin)
sql, rowsAffectedNum := fc()
fields := logrus.Fields{}
if l.SourceField != "" {
fields[l.SourceField] = utils.FileWithLineNum()
}
// format := "%s [cost: %s] [rows: %d]"
// args := []interface{}{sql, elapsed, rowsAffectedNum}
msg := fmt.Sprintf("%s [cost: %s] [rows: %d]", sql, elapsed, rowsAffectedNum)
if err != nil && !(errors.Is(err, gorm.ErrRecordNotFound) && l.SkipErrRecordNotFound) {
fields[logrus.ErrorKey] = err
l.Logger.WithFields(fields).Error(msg)
return
}
if l.SlowThreshold != 0 && elapsed > l.SlowThreshold {
l.Logger.WithFields(fields).Warn(msg)
return
}
l.Logger.WithFields(fields).Debug(msg)
}

View File

@@ -0,0 +1,75 @@
package logging
import (
"github.com/sirupsen/logrus"
)
const (
defaultTimestampFormat = "2006-01-02 15:04:05.000000"
defaultLoggerLevel = logrus.DebugLevel
)
var DefaultConfig = defaultConfig()
func defaultConfig() *Config {
return &Config{
Level: defaultLoggerLevel.String(),
TimestampFormat: defaultTimestampFormat,
ReportCaller: true,
}
}
type Config struct {
Level string
TimestampFormat string `mapstructure:"timestamp_format"`
ReportCaller bool `mapstructure:"report_caller"`
}
func (cfg Config) GetLevel() logrus.Level {
l, err := logrus.ParseLevel(cfg.Level)
if err != nil {
logrus.
WithError(err).
Errorf("parse logger level failed with: %s", cfg.Level)
return defaultLoggerLevel
}
return l
}
func (cfg Config) GetTimestampFormat() string {
if cfg.TimestampFormat != "" {
return cfg.TimestampFormat
}
return defaultTimestampFormat
}
func Init() {
InitLogger(DefaultConfig)
}
func InitLogger(cfg *Config, hooks ...logrus.Hook) {
logrus.SetLevel(cfg.GetLevel())
logrus.SetReportCaller(cfg.ReportCaller)
formatter := logrus.JSONFormatter{
PrettyPrint: true,
TimestampFormat: cfg.GetTimestampFormat(),
}
logrus.SetFormatter(&formatter)
for _, hook := range hooks {
logrus.AddHook(hook)
}
}
func New() logrus.FieldLogger {
return logrus.StandardLogger()
}
func WithScope(scope string) logrus.FieldLogger {
return logrus.WithField("scope", scope)
}
func AddHook(hook logrus.Hook) {
logrus.AddHook(hook)
}

View File

@@ -0,0 +1,50 @@
package pgxlogrus
import (
"context"
"fmt"
"time"
"github.com/jackc/pgx/v4"
"github.com/sirupsen/logrus"
)
type pgxLogger struct {
logger logrus.FieldLogger
}
func New(logger logrus.FieldLogger) *pgxLogger {
return &pgxLogger{
logger: logger,
}
}
func (lg pgxLogger) Log(ctx context.Context, level pgx.LogLevel, msg string, data map[string]interface{}) {
lg.logger.WithFields(lg.fieldsData(data)).Info(msg)
}
func (lg pgxLogger) fieldsData(data map[string]interface{}) logrus.Fields {
fields := make(logrus.Fields)
if v, ok := data["time"]; ok && v != nil {
fields["cost"] = v
fields["costString"] = fmt.Sprintf("%v", time.Duration(v.(time.Duration)))
}
if v, ok := data["sql"]; ok {
fields["SQL"] = v
}
if v, ok := data["pid"]; ok {
fields["PID"] = v
}
if v, ok := data["args"]; ok {
fields["args"] = v
}
if v, ok := data["rowCount"]; ok {
fields["rowCount"] = v
}
return fields
}