mirror of
https://github.com/retailcrm/mg-transport-core.git
synced 2024-11-21 20:56:04 +03:00
integrate zap logger
This commit is contained in:
parent
2455c11704
commit
96ac6a6940
@ -5,7 +5,6 @@ import (
|
||||
"fmt"
|
||||
"html/template"
|
||||
"io/fs"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
"sync"
|
||||
|
||||
@ -15,6 +14,7 @@ import (
|
||||
"github.com/gorilla/securecookie"
|
||||
"github.com/gorilla/sessions"
|
||||
"github.com/retailcrm/zabbix-metrics-collector"
|
||||
"go.uber.org/zap"
|
||||
"golang.org/x/text/language"
|
||||
|
||||
"github.com/retailcrm/mg-transport-core/v2/core/config"
|
||||
@ -141,13 +141,9 @@ func (e *Engine) Prepare() *Engine {
|
||||
e.Localizer.Preload(e.PreloadLanguages)
|
||||
}
|
||||
|
||||
if !e.Config.IsDebug() {
|
||||
logger.DefaultOpts.Level = slog.LevelInfo
|
||||
}
|
||||
|
||||
e.CreateDB(e.Config.GetDBConfig())
|
||||
e.ResetUtils(e.Config.GetAWSConfig(), e.Config.IsDebug(), 0)
|
||||
e.SetLogger(logger.NewDefaultText())
|
||||
e.SetLogger(logger.NewDefault(e.Config.IsDebug()))
|
||||
e.Sentry.Localizer = &e.Localizer
|
||||
e.Utils.Logger = e.Logger()
|
||||
e.Sentry.Logger = e.Logger()
|
||||
@ -180,14 +176,14 @@ func (e *Engine) HijackGinLogs() *Engine {
|
||||
if e.Logger() == nil {
|
||||
return e
|
||||
}
|
||||
gin.DefaultWriter = logger.WriterAdapter(e.Logger(), slog.LevelDebug)
|
||||
gin.DefaultErrorWriter = logger.WriterAdapter(e.Logger(), slog.LevelError)
|
||||
gin.DefaultWriter = logger.WriterAdapter(e.Logger(), zap.DebugLevel)
|
||||
gin.DefaultErrorWriter = logger.WriterAdapter(e.Logger(), zap.ErrorLevel)
|
||||
gin.DebugPrintRouteFunc = func(httpMethod, absolutePath, handlerName string, nuHandlers int) {
|
||||
e.Logger().Debug("route",
|
||||
slog.String(logger.HTTPMethodAttr, httpMethod),
|
||||
slog.String("path", absolutePath),
|
||||
slog.String(logger.HandlerAttr, handlerName),
|
||||
slog.Int("handlerCount", nuHandlers))
|
||||
zap.String(logger.HTTPMethodAttr, httpMethod),
|
||||
zap.String("path", absolutePath),
|
||||
zap.String(logger.HandlerAttr, handlerName),
|
||||
zap.Int("handlerCount", nuHandlers))
|
||||
}
|
||||
return e
|
||||
}
|
||||
|
@ -252,7 +252,7 @@ func (e *EngineTest) Test_SetLogger() {
|
||||
defer func() {
|
||||
e.engine.logger = origLogger
|
||||
}()
|
||||
e.engine.logger = logger.NewDefaultNil()
|
||||
e.engine.logger = logger.NewNil()
|
||||
e.engine.SetLogger(nil)
|
||||
assert.NotNil(e.T(), e.engine.logger)
|
||||
}
|
||||
|
@ -1,9 +1,8 @@
|
||||
package healthcheck
|
||||
|
||||
import (
|
||||
"log/slog"
|
||||
|
||||
"github.com/retailcrm/mg-transport-core/v2/core/logger"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -31,19 +30,19 @@ type CounterProcessor struct {
|
||||
func (c CounterProcessor) Process(id int, counter Counter) bool { // nolint:varnamelen
|
||||
if counter.IsFailed() {
|
||||
if counter.IsFailureProcessed() {
|
||||
c.debugLog("skipping counter because its failure is already processed", slog.Int(logger.CounterIDAttr, id))
|
||||
c.debugLog("skipping counter because its failure is already processed", zap.Int(logger.CounterIDAttr, id))
|
||||
return true
|
||||
}
|
||||
|
||||
apiURL, apiKey, _, exists := c.ConnectionDataProvider(id)
|
||||
if !exists {
|
||||
c.debugLog("cannot find connection data for counter", slog.Int(logger.CounterIDAttr, id))
|
||||
c.debugLog("cannot find connection data for counter", zap.Int(logger.CounterIDAttr, id))
|
||||
return true
|
||||
}
|
||||
err := c.Notifier(apiURL, apiKey, counter.Message())
|
||||
if err != nil {
|
||||
c.debugLog("cannot send notification for counter",
|
||||
slog.Int(logger.CounterIDAttr, id), logger.Err(err), slog.String(logger.FailureMessageAttr, counter.Message()))
|
||||
zap.Int(logger.CounterIDAttr, id), logger.Err(err), zap.String(logger.FailureMessageAttr, counter.Message()))
|
||||
}
|
||||
counter.FailureProcessed()
|
||||
return true
|
||||
@ -56,7 +55,7 @@ func (c CounterProcessor) Process(id int, counter Counter) bool { // nolint:varn
|
||||
// The results may not be representative.
|
||||
if (succeeded + failed) < c.MinRequests {
|
||||
c.debugLog("skipping counter because it has too few requests",
|
||||
slog.Int(logger.CounterIDAttr, id), slog.Any("minRequests", c.MinRequests))
|
||||
zap.Int(logger.CounterIDAttr, id), zap.Any("minRequests", c.MinRequests))
|
||||
return true
|
||||
}
|
||||
|
||||
@ -75,13 +74,13 @@ func (c CounterProcessor) Process(id int, counter Counter) bool { // nolint:varn
|
||||
|
||||
apiURL, apiKey, lang, exists := c.ConnectionDataProvider(id)
|
||||
if !exists {
|
||||
c.debugLog("cannot find connection data for counter", slog.Int(logger.CounterIDAttr, id))
|
||||
c.debugLog("cannot find connection data for counter", zap.Int(logger.CounterIDAttr, id))
|
||||
return true
|
||||
}
|
||||
err := c.Notifier(apiURL, apiKey, c.getErrorText(counter.Name(), c.Error, lang))
|
||||
if err != nil {
|
||||
c.debugLog("cannot send notification for counter",
|
||||
slog.Int(logger.CounterIDAttr, id), logger.Err(err), slog.String(logger.FailureMessageAttr, counter.Message()))
|
||||
zap.Int(logger.CounterIDAttr, id), logger.Err(err), zap.String(logger.FailureMessageAttr, counter.Message()))
|
||||
}
|
||||
counter.CountersProcessed()
|
||||
return true
|
||||
@ -99,6 +98,6 @@ func (c CounterProcessor) getErrorText(name, msg, lang string) string {
|
||||
|
||||
func (c CounterProcessor) debugLog(msg string, args ...interface{}) {
|
||||
if c.Debug {
|
||||
c.Logger.Debug(msg, args...)
|
||||
c.Logger.Debug(msg, logger.AnyZapFields(args)...)
|
||||
}
|
||||
}
|
||||
|
@ -96,7 +96,7 @@ func (t *CounterProcessorTest) Test_FailureProcessed() {
|
||||
p.Process(1, c)
|
||||
c.AssertExpectations(t.T())
|
||||
t.Assert().Contains(log.String(), "skipping counter because its failure is already processed")
|
||||
t.Assert().Contains(log.String(), "counterId=1")
|
||||
t.Assert().Contains(log.String(), `"counterId": 1`)
|
||||
}
|
||||
|
||||
func (t *CounterProcessorTest) Test_CounterFailed_CannotFindConnection() {
|
||||
@ -109,7 +109,7 @@ func (t *CounterProcessorTest) Test_CounterFailed_CannotFindConnection() {
|
||||
p.Process(1, c)
|
||||
c.AssertExpectations(t.T())
|
||||
t.Assert().Contains(log.String(), "cannot find connection data for counter")
|
||||
t.Assert().Contains(log.String(), "counterId=1")
|
||||
t.Assert().Contains(log.String(), `"counterId": 1`)
|
||||
}
|
||||
|
||||
func (t *CounterProcessorTest) Test_CounterFailed_ErrWhileNotifying() {
|
||||
@ -124,9 +124,9 @@ func (t *CounterProcessorTest) Test_CounterFailed_ErrWhileNotifying() {
|
||||
p.Process(1, c)
|
||||
c.AssertExpectations(t.T())
|
||||
t.Assert().Contains(log.String(), "cannot send notification for counter")
|
||||
t.Assert().Contains(log.String(), "counterId=1")
|
||||
t.Assert().Contains(log.String(), `error="http status code: 500"`)
|
||||
t.Assert().Contains(log.String(), `failureMessage="error message"`)
|
||||
t.Assert().Contains(log.String(), `"counterId": 1`)
|
||||
t.Assert().Contains(log.String(), `"error": "http status code: 500"`)
|
||||
t.Assert().Contains(log.String(), `"failureMessage": "error message"`)
|
||||
t.Assert().Equal(t.apiURL, n.apiURL)
|
||||
t.Assert().Equal(t.apiKey, n.apiKey)
|
||||
t.Assert().Equal("error message", n.message)
|
||||
@ -160,7 +160,7 @@ func (t *CounterProcessorTest) Test_TooFewRequests() {
|
||||
p.Process(1, c)
|
||||
c.AssertExpectations(t.T())
|
||||
t.Assert().Contains(log.String(),
|
||||
fmt.Sprintf(`msg="skipping counter because it has too few requests" counterId=%d minRequests=%d`, 1, DefaultMinRequests))
|
||||
fmt.Sprintf(`skipping counter because it has too few requests {"counterId": %d, "minRequests": %d}`, 1, DefaultMinRequests))
|
||||
}
|
||||
|
||||
func (t *CounterProcessorTest) Test_ThresholdNotPassed() {
|
||||
@ -206,7 +206,7 @@ func (t *CounterProcessorTest) Test_ThresholdPassed_NoConnectionFound() {
|
||||
p.Process(1, c)
|
||||
c.AssertExpectations(t.T())
|
||||
t.Assert().Contains(log.String(), "cannot find connection data for counter")
|
||||
t.Assert().Contains(log.String(), "counterId=1")
|
||||
t.Assert().Contains(log.String(), `"counterId": 1`)
|
||||
t.Assert().Empty(n.message)
|
||||
}
|
||||
|
||||
@ -224,7 +224,7 @@ func (t *CounterProcessorTest) Test_ThresholdPassed_NotifyingError() {
|
||||
|
||||
p.Process(1, c)
|
||||
c.AssertExpectations(t.T())
|
||||
t.Assert().Contains(log.String(), `msg="cannot send notification for counter" counterId=1 error="unknown error" failureMessage=""`)
|
||||
t.Assert().Contains(log.String(), `cannot send notification for counter {"counterId": 1, "error": "unknown error", "failureMessage": ""}`)
|
||||
t.Assert().Equal(`default error [{"Name":"MockedCounter"}]`, n.message)
|
||||
}
|
||||
|
||||
|
@ -3,11 +3,11 @@ package core
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/retailcrm/mg-transport-core/v2/core/logger"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
// JobFunc is empty func which should be executed in a parallel goroutine.
|
||||
@ -74,7 +74,7 @@ func (j *Job) getWrappedFunc(name string, log logger.Logger) func(callback JobAf
|
||||
}
|
||||
}()
|
||||
|
||||
log = log.With(logger.HandlerAttr, name)
|
||||
log = log.With(logger.Handler(name))
|
||||
err := j.Command(log)
|
||||
if err != nil && j.ErrorHandler != nil {
|
||||
j.ErrorHandler(name, err, log)
|
||||
@ -148,14 +148,14 @@ func (j *Job) runOnceSync(name string, log logger.Logger) {
|
||||
|
||||
// NewJobManager is a JobManager constructor.
|
||||
func NewJobManager() *JobManager {
|
||||
return &JobManager{jobs: &sync.Map{}, nilLogger: logger.NewDefaultNil()}
|
||||
return &JobManager{jobs: &sync.Map{}, nilLogger: logger.NewNil()}
|
||||
}
|
||||
|
||||
// DefaultJobErrorHandler returns default error handler for a job.
|
||||
func DefaultJobErrorHandler() JobErrorHandler {
|
||||
return func(name string, err error, log logger.Logger) {
|
||||
if err != nil && name != "" {
|
||||
log.Error("job failed with an error", slog.String("job", name), logger.Err(err))
|
||||
log.Error("job failed with an error", zap.String("job", name), logger.Err(err))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -164,7 +164,7 @@ func DefaultJobErrorHandler() JobErrorHandler {
|
||||
func DefaultJobPanicHandler() JobPanicHandler {
|
||||
return func(name string, recoverValue interface{}, log logger.Logger) {
|
||||
if recoverValue != nil && name != "" {
|
||||
log.Error("job panicked with the value", slog.String("job", name), slog.Any("value", recoverValue))
|
||||
log.Error("job panicked with the value", zap.String("job", name), zap.Any("value", recoverValue))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,8 @@
|
||||
package core
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"math/rand"
|
||||
"strings"
|
||||
"sync"
|
||||
@ -14,6 +12,8 @@ import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/stretchr/testify/suite"
|
||||
"go.uber.org/zap"
|
||||
"go.uber.org/zap/zapcore"
|
||||
|
||||
"github.com/retailcrm/mg-transport-core/v2/core/logger"
|
||||
)
|
||||
@ -26,7 +26,7 @@ type JobTest struct {
|
||||
executeErr chan error
|
||||
panicValue chan interface{}
|
||||
lastLog string
|
||||
lastMsgLevel slog.Level
|
||||
lastMsgLevel zapcore.Level
|
||||
syncBool bool
|
||||
}
|
||||
|
||||
@ -37,18 +37,58 @@ type JobManagerTest struct {
|
||||
syncRunnerFlag bool
|
||||
}
|
||||
|
||||
type callbackLoggerFunc func(ctx context.Context, level slog.Level, msg string, args ...any)
|
||||
type callbackLoggerFunc func(level zapcore.Level, msg string, args ...zap.Field)
|
||||
|
||||
type callbackLogger struct {
|
||||
fn callbackLoggerFunc
|
||||
fields []zap.Field
|
||||
fn callbackLoggerFunc
|
||||
}
|
||||
|
||||
func (n *callbackLogger) Handler() slog.Handler {
|
||||
return logger.NilHandler
|
||||
func (n *callbackLogger) Check(lvl zapcore.Level, msg string) *zapcore.CheckedEntry {
|
||||
return &zapcore.CheckedEntry{}
|
||||
}
|
||||
|
||||
func (n *callbackLogger) With(args ...any) logger.Logger {
|
||||
return n
|
||||
func (n *callbackLogger) DPanic(msg string, fields ...zap.Field) {
|
||||
n.fn(zap.PanicLevel, msg, fields...)
|
||||
}
|
||||
|
||||
func (n *callbackLogger) Panic(msg string, fields ...zap.Field) {
|
||||
n.fn(zap.PanicLevel, msg, fields...)
|
||||
}
|
||||
|
||||
func (n *callbackLogger) Fatal(msg string, fields ...zap.Field) {
|
||||
n.fn(zap.FatalLevel, msg, fields...)
|
||||
}
|
||||
|
||||
func (n *callbackLogger) Sync() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (n *callbackLogger) clone() *callbackLogger {
|
||||
return &callbackLogger{fn: n.fn, fields: n.fields}
|
||||
}
|
||||
|
||||
func (n *callbackLogger) cloneWithFields(fields []zap.Field) *callbackLogger {
|
||||
cl := &callbackLogger{fn: n.fn, fields: n.fields}
|
||||
existing := cl.fields
|
||||
if len(existing) == 0 {
|
||||
cl.fields = fields
|
||||
return cl
|
||||
}
|
||||
cl.fields = append(existing, fields...)
|
||||
return cl
|
||||
}
|
||||
|
||||
func (n *callbackLogger) Level() zapcore.Level {
|
||||
return zapcore.DebugLevel
|
||||
}
|
||||
|
||||
func (n *callbackLogger) With(args ...zap.Field) logger.Logger {
|
||||
return n.cloneWithFields(args)
|
||||
}
|
||||
|
||||
func (n *callbackLogger) WithLazy(args ...zap.Field) logger.Logger {
|
||||
return n.cloneWithFields(args)
|
||||
}
|
||||
|
||||
func (n *callbackLogger) WithGroup(name string) logger.Logger {
|
||||
@ -59,47 +99,24 @@ func (n *callbackLogger) ForAccount(handler, conn, acc any) logger.Logger {
|
||||
return n
|
||||
}
|
||||
|
||||
func (n *callbackLogger) Enabled(ctx context.Context, level slog.Level) bool {
|
||||
return true
|
||||
func (n *callbackLogger) Log(level zapcore.Level, msg string, args ...zap.Field) {
|
||||
n.fn(level, msg, args...)
|
||||
}
|
||||
|
||||
func (n *callbackLogger) Log(ctx context.Context, level slog.Level, msg string, args ...any) {
|
||||
n.fn(ctx, level, msg, args...)
|
||||
func (n *callbackLogger) Debug(msg string, args ...zap.Field) {
|
||||
n.Log(zap.DebugLevel, msg, args...)
|
||||
}
|
||||
|
||||
func (n *callbackLogger) LogAttrs(ctx context.Context, level slog.Level, msg string, attrs ...slog.Attr) {
|
||||
func (n *callbackLogger) Info(msg string, args ...zap.Field) {
|
||||
n.Log(zap.InfoLevel, msg, args...)
|
||||
}
|
||||
|
||||
func (n *callbackLogger) Debug(msg string, args ...any) {
|
||||
n.Log(nil, slog.LevelDebug, msg, args...)
|
||||
func (n *callbackLogger) Warn(msg string, args ...zap.Field) {
|
||||
n.Log(zap.WarnLevel, msg, args...)
|
||||
}
|
||||
|
||||
func (n *callbackLogger) DebugContext(ctx context.Context, msg string, args ...any) {
|
||||
n.Log(ctx, slog.LevelDebug, msg, args...)
|
||||
}
|
||||
|
||||
func (n *callbackLogger) Info(msg string, args ...any) {
|
||||
n.Log(nil, slog.LevelInfo, msg, args...)
|
||||
}
|
||||
|
||||
func (n *callbackLogger) InfoContext(ctx context.Context, msg string, args ...any) {
|
||||
n.Log(ctx, slog.LevelInfo, msg, args...)
|
||||
}
|
||||
|
||||
func (n *callbackLogger) Warn(msg string, args ...any) {
|
||||
n.Log(nil, slog.LevelWarn, msg, args...)
|
||||
}
|
||||
|
||||
func (n *callbackLogger) WarnContext(ctx context.Context, msg string, args ...any) {
|
||||
n.Log(ctx, slog.LevelWarn, msg, args...)
|
||||
}
|
||||
|
||||
func (n *callbackLogger) Error(msg string, args ...any) {
|
||||
n.Log(nil, slog.LevelError, msg, args...)
|
||||
}
|
||||
|
||||
func (n *callbackLogger) ErrorContext(ctx context.Context, msg string, args ...any) {
|
||||
n.Log(ctx, slog.LevelError, msg, args...)
|
||||
func (n *callbackLogger) Error(msg string, args ...zap.Field) {
|
||||
n.Log(zap.ErrorLevel, msg, args...)
|
||||
}
|
||||
|
||||
func TestJob(t *testing.T) {
|
||||
@ -117,9 +134,9 @@ func TestDefaultJobErrorHandler(t *testing.T) {
|
||||
|
||||
fn := DefaultJobErrorHandler()
|
||||
require.NotNil(t, fn)
|
||||
fn("job", errors.New("test"), &callbackLogger{fn: func(_ context.Context, level slog.Level, s string, i ...interface{}) {
|
||||
fn("job", errors.New("test"), &callbackLogger{fn: func(level zapcore.Level, s string, i ...zap.Field) {
|
||||
require.Len(t, i, 2)
|
||||
assert.Equal(t, "error=test", fmt.Sprintf("%s", i[1]))
|
||||
assert.Equal(t, "error=test", fmt.Sprintf("%s=%v", i[1].Key, i[1].Interface))
|
||||
}})
|
||||
}
|
||||
|
||||
@ -130,9 +147,9 @@ func TestDefaultJobPanicHandler(t *testing.T) {
|
||||
|
||||
fn := DefaultJobPanicHandler()
|
||||
require.NotNil(t, fn)
|
||||
fn("job", errors.New("test"), &callbackLogger{fn: func(_ context.Context, level slog.Level, s string, i ...interface{}) {
|
||||
fn("job", errors.New("test"), &callbackLogger{fn: func(level zapcore.Level, s string, i ...zap.Field) {
|
||||
require.Len(t, i, 2)
|
||||
assert.Equal(t, "value=test", fmt.Sprintf("%s", i[1]))
|
||||
assert.Equal(t, "value=test", fmt.Sprintf("%s=%s", i[1].Key, i[1].Interface))
|
||||
}})
|
||||
}
|
||||
|
||||
@ -149,7 +166,7 @@ func (t *JobTest) testPanicHandler() JobPanicHandler {
|
||||
}
|
||||
|
||||
func (t *JobTest) testLogger() logger.Logger {
|
||||
return &callbackLogger{fn: func(_ context.Context, level slog.Level, format string, args ...interface{}) {
|
||||
return &callbackLogger{fn: func(level zapcore.Level, format string, args ...zap.Field) {
|
||||
if format == "" {
|
||||
var sb strings.Builder
|
||||
sb.Grow(3 * len(args)) // nolint:gomnd
|
||||
@ -161,7 +178,12 @@ func (t *JobTest) testLogger() logger.Logger {
|
||||
format = strings.TrimRight(sb.String(), " ")
|
||||
}
|
||||
|
||||
t.lastLog = fmt.Sprintf(format, args...)
|
||||
anyFields := []any{}
|
||||
for _, item := range args {
|
||||
anyFields = append(anyFields, item.Key+"="+fmt.Sprint(item.Interface))
|
||||
}
|
||||
|
||||
t.lastLog = fmt.Sprintf(format, anyFields...)
|
||||
t.lastMsgLevel = level
|
||||
}}
|
||||
}
|
||||
@ -406,7 +428,7 @@ func (t *JobManagerTest) WaitForJob() bool {
|
||||
|
||||
func (t *JobManagerTest) Test_SetLogger() {
|
||||
t.manager.logger = nil
|
||||
t.manager.SetLogger(logger.NewDefaultText())
|
||||
t.manager.SetLogger(logger.NewDefault(true))
|
||||
assert.IsType(t.T(), &logger.Default{}, t.manager.logger)
|
||||
|
||||
t.manager.SetLogger(nil)
|
||||
|
@ -2,8 +2,9 @@ package logger
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -19,28 +20,32 @@ const (
|
||||
HTTPStatusNameAttr = "statusName"
|
||||
)
|
||||
|
||||
func Err(err any) slog.Attr {
|
||||
func Err(err any) zap.Field {
|
||||
if err == nil {
|
||||
return slog.String(ErrorAttr, "<nil>")
|
||||
return zap.String(ErrorAttr, "<nil>")
|
||||
}
|
||||
return slog.Any(ErrorAttr, err)
|
||||
return zap.Any(ErrorAttr, err)
|
||||
}
|
||||
|
||||
func HTTPStatusCode(code int) slog.Attr {
|
||||
return slog.Int(HTTPStatusAttr, code)
|
||||
func Handler(name string) zap.Field {
|
||||
return zap.String(HandlerAttr, name)
|
||||
}
|
||||
|
||||
func HTTPStatusName(code int) slog.Attr {
|
||||
return slog.String(HTTPStatusNameAttr, http.StatusText(code))
|
||||
func HTTPStatusCode(code int) zap.Field {
|
||||
return zap.Int(HTTPStatusAttr, code)
|
||||
}
|
||||
|
||||
func Body(val any) slog.Attr {
|
||||
func HTTPStatusName(code int) zap.Field {
|
||||
return zap.String(HTTPStatusNameAttr, http.StatusText(code))
|
||||
}
|
||||
|
||||
func Body(val any) zap.Field {
|
||||
switch item := val.(type) {
|
||||
case string:
|
||||
return slog.String(BodyAttr, item)
|
||||
return zap.String(BodyAttr, item)
|
||||
case []byte:
|
||||
return slog.String(BodyAttr, string(item))
|
||||
return zap.String(BodyAttr, string(item))
|
||||
default:
|
||||
return slog.String(BodyAttr, fmt.Sprintf("%#v", val))
|
||||
return zap.String(BodyAttr, fmt.Sprintf("%#v", val))
|
||||
}
|
||||
}
|
||||
|
@ -1,87 +1,59 @@
|
||||
package logger
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log/slog"
|
||||
"os"
|
||||
"strconv"
|
||||
|
||||
"go.uber.org/zap"
|
||||
"go.uber.org/zap/zapcore"
|
||||
)
|
||||
|
||||
type Logger interface {
|
||||
With(fields ...zap.Field) Logger
|
||||
WithLazy(fields ...zap.Field) Logger
|
||||
Level() zapcore.Level
|
||||
Check(lvl zapcore.Level, msg string) *zapcore.CheckedEntry
|
||||
Log(lvl zapcore.Level, msg string, fields ...zap.Field)
|
||||
Debug(msg string, fields ...zap.Field)
|
||||
Info(msg string, fields ...zap.Field)
|
||||
Warn(msg string, fields ...zap.Field)
|
||||
Error(msg string, fields ...zap.Field)
|
||||
DPanic(msg string, fields ...zap.Field)
|
||||
Panic(msg string, fields ...zap.Field)
|
||||
Fatal(msg string, fields ...zap.Field)
|
||||
ForAccount(handler, conn, acc any) Logger
|
||||
Sync() error
|
||||
}
|
||||
|
||||
type Default struct {
|
||||
Logger *slog.Logger
|
||||
*zap.Logger
|
||||
}
|
||||
|
||||
func NewDefault(log *slog.Logger) Logger {
|
||||
return &Default{Logger: log}
|
||||
func NewDefault(debug bool) Logger {
|
||||
return &Default{
|
||||
Logger: NewZap(debug),
|
||||
}
|
||||
}
|
||||
|
||||
func NewDefaultText() Logger {
|
||||
return NewDefault(slog.New(slog.NewTextHandler(os.Stdout, DefaultOpts)))
|
||||
func (l *Default) With(fields ...zap.Field) Logger {
|
||||
return l.With(fields...).(Logger)
|
||||
}
|
||||
|
||||
func NewDefaultJSON() Logger {
|
||||
return NewDefault(slog.New(slog.NewJSONHandler(os.Stdout, DefaultOpts)))
|
||||
func (l *Default) WithLazy(fields ...zap.Field) Logger {
|
||||
return l.WithLazy(fields...).(Logger)
|
||||
}
|
||||
|
||||
func NewDefaultNil() Logger {
|
||||
return NewDefault(slog.New(NilHandler))
|
||||
func (l *Default) ForAccount(handler, conn, acc any) Logger {
|
||||
return l.WithLazy(zap.Any(HandlerAttr, handler), zap.Any(ConnectionAttr, conn), zap.Any(AccountAttr, acc))
|
||||
}
|
||||
|
||||
func (d *Default) Handler() slog.Handler {
|
||||
return d.Logger.Handler()
|
||||
}
|
||||
|
||||
func (d *Default) ForAccount(handler, conn, acc any) Logger {
|
||||
return d.With(slog.Any(HandlerAttr, handler), slog.Any(ConnectionAttr, conn), slog.Any(AccountAttr, acc))
|
||||
}
|
||||
|
||||
func (d *Default) With(args ...any) Logger {
|
||||
return &Default{Logger: d.Logger.With(args...)}
|
||||
}
|
||||
|
||||
func (d *Default) WithGroup(name string) Logger {
|
||||
return &Default{Logger: d.Logger.WithGroup(name)}
|
||||
}
|
||||
|
||||
func (d *Default) Enabled(ctx context.Context, level slog.Level) bool {
|
||||
return d.Logger.Enabled(ctx, level)
|
||||
}
|
||||
|
||||
func (d *Default) Log(ctx context.Context, level slog.Level, msg string, args ...any) {
|
||||
d.Logger.Log(ctx, level, msg, args...)
|
||||
}
|
||||
|
||||
func (d *Default) LogAttrs(ctx context.Context, level slog.Level, msg string, attrs ...slog.Attr) {
|
||||
d.Logger.LogAttrs(ctx, level, msg, attrs...)
|
||||
}
|
||||
|
||||
func (d *Default) Debug(msg string, args ...any) {
|
||||
d.Logger.Debug(msg, args...)
|
||||
}
|
||||
|
||||
func (d *Default) DebugContext(ctx context.Context, msg string, args ...any) {
|
||||
d.Logger.DebugContext(ctx, msg, args...)
|
||||
}
|
||||
|
||||
func (d *Default) Info(msg string, args ...any) {
|
||||
d.Logger.Info(msg, args...)
|
||||
}
|
||||
|
||||
func (d *Default) InfoContext(ctx context.Context, msg string, args ...any) {
|
||||
d.Logger.InfoContext(ctx, msg, args...)
|
||||
}
|
||||
|
||||
func (d *Default) Warn(msg string, args ...any) {
|
||||
d.Logger.Warn(msg, args...)
|
||||
}
|
||||
|
||||
func (d *Default) WarnContext(ctx context.Context, msg string, args ...any) {
|
||||
d.Logger.WarnContext(ctx, msg, args...)
|
||||
}
|
||||
|
||||
func (d *Default) Error(msg string, args ...any) {
|
||||
d.Logger.Error(msg, args...)
|
||||
}
|
||||
|
||||
func (d *Default) ErrorContext(ctx context.Context, msg string, args ...any) {
|
||||
d.Logger.ErrorContext(ctx, msg, args...)
|
||||
func AnyZapFields(args []interface{}) []zap.Field {
|
||||
fields := make([]zap.Field, len(args))
|
||||
for i := 0; i < len(fields); i++ {
|
||||
if val, ok := args[i].(zap.Field); ok {
|
||||
fields[i] = val
|
||||
continue
|
||||
}
|
||||
fields[i] = zap.Any("arg"+strconv.Itoa(i), args[i])
|
||||
}
|
||||
return fields
|
||||
}
|
||||
|
@ -1,9 +1,10 @@
|
||||
package logger
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
"log/slog"
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
// GinMiddleware will construct Gin middleware which will log requests.
|
||||
@ -23,14 +24,14 @@ func GinMiddleware(log Logger) gin.HandlerFunc {
|
||||
}
|
||||
|
||||
log.Info("request",
|
||||
slog.String(HandlerAttr, "GIN"),
|
||||
slog.String("startTime", start.Format(time.RFC3339)),
|
||||
slog.String("endTime", end.Format(time.RFC3339)),
|
||||
slog.Any("latency", end.Sub(start)/time.Millisecond),
|
||||
slog.String("remoteAddress", c.ClientIP()),
|
||||
slog.String(HTTPMethodAttr, c.Request.Method),
|
||||
slog.String("path", path),
|
||||
slog.Int("bodySize", c.Writer.Size()),
|
||||
zap.String(HandlerAttr, "GIN"),
|
||||
zap.String("startTime", start.Format(time.RFC3339)),
|
||||
zap.String("endTime", end.Format(time.RFC3339)),
|
||||
zap.Any("latency", end.Sub(start)/time.Millisecond),
|
||||
zap.String("remoteAddress", c.ClientIP()),
|
||||
zap.String(HTTPMethodAttr, c.Request.Method),
|
||||
zap.String("path", path),
|
||||
zap.Int("bodySize", c.Writer.Size()),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +0,0 @@
|
||||
package logger
|
||||
|
||||
import "log/slog"
|
||||
|
||||
var DefaultOpts = &slog.HandlerOptions{
|
||||
AddSource: false,
|
||||
Level: slog.LevelDebug,
|
||||
}
|
@ -1,44 +0,0 @@
|
||||
package logger
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log/slog"
|
||||
)
|
||||
|
||||
// LoggerOld contains methods which should be present in logger implementation.
|
||||
type LoggerOld interface {
|
||||
Fatal(args ...any)
|
||||
Fatalf(format string, args ...any)
|
||||
Panic(args ...any)
|
||||
Panicf(format string, args ...any)
|
||||
Critical(args ...any)
|
||||
Criticalf(format string, args ...any)
|
||||
Error(args ...any)
|
||||
Errorf(format string, args ...any)
|
||||
Warning(args ...any)
|
||||
Warningf(format string, args ...any)
|
||||
Notice(args ...any)
|
||||
Noticef(format string, args ...any)
|
||||
Info(args ...any)
|
||||
Infof(format string, args ...any)
|
||||
Debug(args ...any)
|
||||
Debugf(format string, args ...any)
|
||||
}
|
||||
|
||||
type Logger interface {
|
||||
Handler() slog.Handler
|
||||
With(args ...any) Logger
|
||||
WithGroup(name string) Logger
|
||||
ForAccount(handler, conn, acc any) Logger
|
||||
Enabled(ctx context.Context, level slog.Level) bool
|
||||
Log(ctx context.Context, level slog.Level, msg string, args ...any)
|
||||
LogAttrs(ctx context.Context, level slog.Level, msg string, attrs ...slog.Attr)
|
||||
Debug(msg string, args ...any)
|
||||
DebugContext(ctx context.Context, msg string, args ...any)
|
||||
Info(msg string, args ...any)
|
||||
InfoContext(ctx context.Context, msg string, args ...any)
|
||||
Warn(msg string, args ...any)
|
||||
WarnContext(ctx context.Context, msg string, args ...any)
|
||||
Error(msg string, args ...any)
|
||||
ErrorContext(ctx context.Context, msg string, args ...any)
|
||||
}
|
@ -2,6 +2,7 @@ package logger
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
v1 "github.com/retailcrm/mg-transport-api-client-go/v1"
|
||||
)
|
||||
|
||||
|
52
core/logger/nil.go
Normal file
52
core/logger/nil.go
Normal file
@ -0,0 +1,52 @@
|
||||
package logger
|
||||
|
||||
import (
|
||||
"go.uber.org/zap"
|
||||
"go.uber.org/zap/zapcore"
|
||||
)
|
||||
|
||||
type Nil struct{}
|
||||
|
||||
func NewNil() Logger {
|
||||
return &Nil{}
|
||||
}
|
||||
|
||||
func (l *Nil) With(fields ...zap.Field) Logger {
|
||||
return l
|
||||
}
|
||||
|
||||
func (l *Nil) WithLazy(fields ...zap.Field) Logger {
|
||||
return l
|
||||
}
|
||||
|
||||
func (l *Nil) Level() zapcore.Level {
|
||||
return zapcore.DebugLevel
|
||||
}
|
||||
|
||||
func (l *Nil) Check(lvl zapcore.Level, msg string) *zapcore.CheckedEntry {
|
||||
return &zapcore.CheckedEntry{}
|
||||
}
|
||||
|
||||
func (l *Nil) Log(lvl zapcore.Level, msg string, fields ...zap.Field) {}
|
||||
|
||||
func (l *Nil) Debug(msg string, fields ...zap.Field) {}
|
||||
|
||||
func (l *Nil) Info(msg string, fields ...zap.Field) {}
|
||||
|
||||
func (l *Nil) Warn(msg string, fields ...zap.Field) {}
|
||||
|
||||
func (l *Nil) Error(msg string, fields ...zap.Field) {}
|
||||
|
||||
func (l *Nil) DPanic(msg string, fields ...zap.Field) {}
|
||||
|
||||
func (l *Nil) Panic(msg string, fields ...zap.Field) {}
|
||||
|
||||
func (l *Nil) Fatal(msg string, fields ...zap.Field) {}
|
||||
|
||||
func (l *Nil) ForAccount(handler, conn, acc any) Logger {
|
||||
return l
|
||||
}
|
||||
|
||||
func (l *Nil) Sync() error {
|
||||
return nil
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
package logger
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log/slog"
|
||||
)
|
||||
|
||||
var NilHandler slog.Handler = &nilHandler{}
|
||||
|
||||
type nilHandler struct{}
|
||||
|
||||
func (n *nilHandler) Enabled(ctx context.Context, level slog.Level) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (n *nilHandler) Handle(ctx context.Context, record slog.Record) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (n *nilHandler) WithAttrs(attrs []slog.Attr) slog.Handler {
|
||||
return n
|
||||
}
|
||||
|
||||
func (n *nilHandler) WithGroup(name string) slog.Handler {
|
||||
return n
|
||||
}
|
@ -1,21 +1,21 @@
|
||||
package logger
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"log/slog"
|
||||
|
||||
"go.uber.org/zap/zapcore"
|
||||
)
|
||||
|
||||
type writerAdapter struct {
|
||||
log Logger
|
||||
level slog.Level
|
||||
level zapcore.Level
|
||||
}
|
||||
|
||||
func WriterAdapter(log Logger, level slog.Level) io.Writer {
|
||||
func WriterAdapter(log Logger, level zapcore.Level) io.Writer {
|
||||
return &writerAdapter{log: log, level: level}
|
||||
}
|
||||
|
||||
func (w *writerAdapter) Write(p []byte) (n int, err error) {
|
||||
w.log.Log(context.Background(), w.level, string(p))
|
||||
w.log.Log(w.level, string(p))
|
||||
return len(p), nil
|
||||
}
|
||||
|
52
core/logger/zap.go
Normal file
52
core/logger/zap.go
Normal file
@ -0,0 +1,52 @@
|
||||
package logger
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"go.uber.org/zap"
|
||||
"go.uber.org/zap/zapcore"
|
||||
)
|
||||
|
||||
func NewZap(debug bool) *zap.Logger {
|
||||
level := zapcore.InfoLevel
|
||||
if debug {
|
||||
level = zapcore.DebugLevel
|
||||
}
|
||||
log, err := zap.Config{
|
||||
Level: zap.NewAtomicLevelAt(level),
|
||||
Development: debug,
|
||||
Encoding: "console",
|
||||
EncoderConfig: EncoderConfig(),
|
||||
OutputPaths: []string{"stdout"},
|
||||
ErrorOutputPaths: []string{"stderr"},
|
||||
}.Build()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return log
|
||||
}
|
||||
|
||||
func EncoderConfig() zapcore.EncoderConfig {
|
||||
return zapcore.EncoderConfig{
|
||||
MessageKey: "message",
|
||||
LevelKey: "level",
|
||||
TimeKey: "timestamp",
|
||||
NameKey: "logger",
|
||||
CallerKey: "caller",
|
||||
FunctionKey: zapcore.OmitKey,
|
||||
StacktraceKey: "",
|
||||
LineEnding: "\n",
|
||||
EncodeLevel: func(level zapcore.Level, encoder zapcore.PrimitiveArrayEncoder) {
|
||||
encoder.AppendString("level=" + level.String())
|
||||
},
|
||||
EncodeTime: func(t time.Time, encoder zapcore.PrimitiveArrayEncoder) {
|
||||
encoder.AppendString("time=" + t.Format(time.RFC3339))
|
||||
},
|
||||
EncodeDuration: zapcore.StringDurationEncoder,
|
||||
EncodeCaller: func(caller zapcore.EntryCaller, encoder zapcore.PrimitiveArrayEncoder) {
|
||||
encoder.AppendString("caller=" + caller.TrimmedPath())
|
||||
},
|
||||
EncodeName: zapcore.FullNameEncoder,
|
||||
ConsoleSeparator: " ",
|
||||
}
|
||||
}
|
@ -5,7 +5,6 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"log/slog"
|
||||
"os"
|
||||
|
||||
"github.com/aws/aws-sdk-go-v2/aws"
|
||||
@ -13,6 +12,7 @@ import (
|
||||
"github.com/aws/aws-sdk-go-v2/feature/s3/manager"
|
||||
"github.com/aws/aws-sdk-go-v2/service/s3"
|
||||
"github.com/gomarkdown/markdown"
|
||||
"go.uber.org/zap"
|
||||
"golang.org/x/text/language"
|
||||
|
||||
"github.com/retailcrm/mg-transport-core/v2/core/config"
|
||||
@ -91,14 +91,14 @@ func (s *ModuleFeaturesUploader) Upload() {
|
||||
|
||||
content, err := os.ReadFile(s.featuresFilename)
|
||||
if err != nil {
|
||||
s.log.Error("cannot read markdown file %s %s", slog.String("fileName", s.featuresFilename), logger.Err(err))
|
||||
s.log.Error("cannot read markdown file %s %s", zap.String("fileName", s.featuresFilename), logger.Err(err))
|
||||
return
|
||||
}
|
||||
|
||||
for _, lang := range languages {
|
||||
translated, err := s.translate(content, lang)
|
||||
if err != nil {
|
||||
s.log.Error("cannot translate module features file", slog.String("lang", lang.String()), logger.Err(err))
|
||||
s.log.Error("cannot translate module features file", zap.String("lang", lang.String()), logger.Err(err))
|
||||
continue
|
||||
}
|
||||
|
||||
@ -106,7 +106,7 @@ func (s *ModuleFeaturesUploader) Upload() {
|
||||
resp, err := s.uploadFile(html, lang.String())
|
||||
|
||||
if err != nil {
|
||||
s.log.Error("cannot upload file", slog.String("lang", lang.String()), logger.Err(err))
|
||||
s.log.Error("cannot upload file", zap.String("lang", lang.String()), logger.Err(err))
|
||||
continue
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,6 @@ package core
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/http/httputil"
|
||||
@ -16,6 +15,7 @@ import (
|
||||
"github.com/getsentry/sentry-go"
|
||||
sentrygin "github.com/getsentry/sentry-go/gin"
|
||||
"github.com/pkg/errors"
|
||||
"go.uber.org/zap"
|
||||
|
||||
"github.com/retailcrm/mg-transport-core/v2/core/logger"
|
||||
"github.com/retailcrm/mg-transport-core/v2/core/stacktrace"
|
||||
@ -260,8 +260,8 @@ func (s *Sentry) recoveryMiddleware() gin.HandlerFunc { // nolint
|
||||
}
|
||||
headers[idx] = "header: " + headers[idx]
|
||||
}
|
||||
headersToStr := slog.String("headers", strings.Join(headers, "\r\n"))
|
||||
formattedStack := slog.String("stacktrace", string(stack))
|
||||
headersToStr := zap.String("headers", strings.Join(headers, "\r\n"))
|
||||
formattedStack := zap.String("stacktrace", string(stack))
|
||||
switch {
|
||||
case brokenPipe:
|
||||
l.Error("error", formattedErr, headersToStr)
|
||||
|
@ -12,9 +12,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/retailcrm/mg-transport-core/v2/core/config"
|
||||
|
||||
"github.com/retailcrm/mg-transport-core/v2/core/logger"
|
||||
)
|
||||
|
||||
@ -275,7 +273,7 @@ func (b *HTTPClientBuilder) buildMocks() error {
|
||||
func (b *HTTPClientBuilder) log(msg string, args ...interface{}) {
|
||||
if b.logging {
|
||||
if b.logger != nil {
|
||||
b.logger.Info(msg, args...)
|
||||
b.logger.Info(msg, logger.AnyZapFields(args)...)
|
||||
} else {
|
||||
fmt.Println(append([]any{msg}, args...))
|
||||
}
|
||||
|
@ -142,7 +142,7 @@ func (t *HTTPClientBuilderTest) Test_WithLogger() {
|
||||
builder.WithLogger(nil)
|
||||
assert.Nil(t.T(), builder.logger)
|
||||
|
||||
log := logger.NewDefaultText()
|
||||
log := logger.NewDefault(true)
|
||||
builder.WithLogger(log)
|
||||
assert.NotNil(t.T(), builder.logger)
|
||||
}
|
||||
|
@ -3,9 +3,11 @@ package testutil
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"log/slog"
|
||||
"os"
|
||||
|
||||
"github.com/retailcrm/mg-transport-core/v2/core/logger"
|
||||
"go.uber.org/zap"
|
||||
"go.uber.org/zap/zapcore"
|
||||
)
|
||||
|
||||
// ReadBuffer is implemented by the BufferLogger.
|
||||
@ -32,21 +34,32 @@ type BufferLogger struct {
|
||||
// NewBufferedLogger returns new BufferedLogger instance.
|
||||
func NewBufferedLogger() BufferedLogger {
|
||||
bl := &BufferLogger{}
|
||||
bl.Logger = slog.New(slog.NewTextHandler(&bl.buf, logger.DefaultOpts))
|
||||
bl.Logger = zap.New(
|
||||
zapcore.NewCore(
|
||||
zapcore.NewConsoleEncoder(
|
||||
logger.EncoderConfig()), zap.CombineWriteSyncers(os.Stdout, os.Stderr, &bl.buf), zapcore.DebugLevel))
|
||||
return bl
|
||||
}
|
||||
|
||||
// With doesn't do anything here and only added for backwards compatibility with the interface.
|
||||
func (l *BufferLogger) With(args ...any) logger.Logger {
|
||||
func (l *BufferLogger) With(fields ...zapcore.Field) logger.Logger {
|
||||
return &BufferLogger{
|
||||
Default: logger.Default{
|
||||
Logger: l.Logger.With(args...),
|
||||
Logger: l.Logger.With(fields...),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (l *BufferLogger) WithLazy(fields ...zapcore.Field) logger.Logger {
|
||||
return &BufferLogger{
|
||||
Default: logger.Default{
|
||||
Logger: l.Logger.WithLazy(fields...),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (l *BufferLogger) ForAccount(handler, conn, acc any) logger.Logger {
|
||||
return l.With(slog.Any(logger.HandlerAttr, handler), slog.Any(logger.ConnectionAttr, conn), slog.Any(logger.AccountAttr, acc))
|
||||
return l.WithLazy(
|
||||
zap.Any(logger.HandlerAttr, handler), zap.Any(logger.ConnectionAttr, conn), zap.Any(logger.AccountAttr, acc))
|
||||
}
|
||||
|
||||
// Read bytes from the logger buffer. io.Reader implementation.
|
||||
|
@ -29,17 +29,17 @@ func (t *BufferLoggerTest) Test_Read() {
|
||||
|
||||
data, err := io.ReadAll(t.logger)
|
||||
t.Require().NoError(err)
|
||||
t.Assert().Contains(string(data), "level=DEBUG msg=test")
|
||||
t.Assert().Contains(string(data), "level=debug test")
|
||||
}
|
||||
|
||||
func (t *BufferLoggerTest) Test_Bytes() {
|
||||
t.logger.Debug("test")
|
||||
t.Assert().Contains(string(t.logger.Bytes()), "level=DEBUG msg=test")
|
||||
t.Assert().Contains(string(t.logger.Bytes()), "level=debug test")
|
||||
}
|
||||
|
||||
func (t *BufferLoggerTest) Test_String() {
|
||||
t.logger.Debug("test")
|
||||
t.Assert().Contains(t.logger.String(), "level=DEBUG msg=test")
|
||||
t.Assert().Contains(t.logger.String(), "level=debug test")
|
||||
}
|
||||
|
||||
func (t *BufferLoggerTest) TestRace() {
|
||||
|
@ -148,3 +148,8 @@ func (b *LockableBuffer) ReadString(delim byte) (line string, err error) {
|
||||
b.rw.Lock()
|
||||
return b.buf.ReadString(delim)
|
||||
}
|
||||
|
||||
// Sync is a no-op.
|
||||
func (b *LockableBuffer) Sync() error {
|
||||
return nil
|
||||
}
|
||||
|
@ -21,7 +21,6 @@ import (
|
||||
"github.com/gin-gonic/gin"
|
||||
retailcrm "github.com/retailcrm/api-client-go/v2"
|
||||
v1 "github.com/retailcrm/mg-transport-api-client-go/v1"
|
||||
|
||||
"github.com/retailcrm/mg-transport-core/v2/core/config"
|
||||
|
||||
"github.com/retailcrm/mg-transport-core/v2/core/logger"
|
||||
@ -145,12 +144,12 @@ func (u *Utils) GetAPIClient(
|
||||
|
||||
if res := u.checkScopes(cr.Scopes, scopes); len(res) != 0 {
|
||||
if len(credentials) == 0 || len(cr.Scopes) > 0 {
|
||||
u.Logger.Error(url, status, res)
|
||||
u.Logger.Error(url, logger.HTTPStatusCode(status), logger.Body(res))
|
||||
return nil, http.StatusBadRequest, errorutil.NewInsufficientScopesErr(res)
|
||||
}
|
||||
|
||||
if res := u.checkScopes(cr.Credentials, credentials[0]); len(res) != 0 {
|
||||
u.Logger.Error(url, status, res)
|
||||
u.Logger.Error(url, logger.HTTPStatusCode(status), logger.Body(res))
|
||||
return nil, http.StatusBadRequest, errorutil.NewInsufficientScopesErr(res)
|
||||
}
|
||||
}
|
||||
|
@ -38,7 +38,7 @@ func mgClient() *v1.MgClient {
|
||||
}
|
||||
|
||||
func (u *UtilsTest) SetupSuite() {
|
||||
logger := logger.NewDefaultText()
|
||||
logger := logger.NewDefault(true)
|
||||
awsConfig := config.AWS{
|
||||
AccessKeyID: "access key id (will be removed)",
|
||||
SecretAccessKey: "secret access key",
|
||||
|
2
go.mod
2
go.mod
@ -28,6 +28,7 @@ require (
|
||||
github.com/retailcrm/zabbix-metrics-collector v1.0.0
|
||||
github.com/stretchr/testify v1.8.3
|
||||
go.uber.org/atomic v1.10.0
|
||||
go.uber.org/zap v1.26.0
|
||||
golang.org/x/text v0.14.0
|
||||
gopkg.in/gormigrate.v1 v1.6.0
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
@ -77,6 +78,7 @@ require (
|
||||
github.com/stretchr/objx v0.5.0 // indirect
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
||||
github.com/ugorji/go/codec v1.2.11 // indirect
|
||||
go.uber.org/multierr v1.10.0 // indirect
|
||||
golang.org/x/arch v0.3.0 // indirect
|
||||
golang.org/x/crypto v0.21.0 // indirect
|
||||
golang.org/x/net v0.23.0 // indirect
|
||||
|
11
go.sum
11
go.sum
@ -297,8 +297,9 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxv
|
||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/labstack/echo/v4 v4.5.0/go.mod h1:czIriw4a0C1dFun+ObrXp7ok03xON0N1awStJ6ArI7Y=
|
||||
github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k=
|
||||
github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q=
|
||||
@ -377,8 +378,6 @@ github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R
|
||||
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
|
||||
github.com/retailcrm/api-client-go/v2 v2.1.3 h1:AVcp9oeSOm6+3EWXCgdQs+XE3PTjzCKKB//MUAe0Zb0=
|
||||
github.com/retailcrm/api-client-go/v2 v2.1.3/go.mod h1:1yTZl9+gd3+/k0kAJe7sYvC+mL4fqMwIwtnSgSWZlkQ=
|
||||
github.com/retailcrm/mg-transport-api-client-go v1.1.32 h1:IBPltSoD5q2PPZJbNC/prK5F9rEVPXVx/ZzDpi7HKhs=
|
||||
github.com/retailcrm/mg-transport-api-client-go v1.1.32/go.mod h1:AWV6BueE28/6SCoyfKURTo4lF0oXYoOKmHTzehd5vAI=
|
||||
github.com/retailcrm/mg-transport-api-client-go v1.3.4 h1:HIn4eorABNfudn7hr5Rd6XYC/ieDTqCkaq6wv0AFTBE=
|
||||
github.com/retailcrm/mg-transport-api-client-go v1.3.4/go.mod h1:gDe/tj7t3Hr/uwIFSBVgGAmP85PoLajVl1A+skBo1Ro=
|
||||
github.com/retailcrm/zabbix-metrics-collector v1.0.0 h1:ju3rhpgVoiKII6oXEJEf2eoJy5bNcYAmOPRp1oPWDmA=
|
||||
@ -444,6 +443,12 @@ go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ=
|
||||
go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
|
||||
go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk=
|
||||
go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo=
|
||||
go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ=
|
||||
go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
||||
go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo=
|
||||
go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so=
|
||||
golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
|
||||
golang.org/x/arch v0.3.0 h1:02VY4/ZcO/gBOH6PUaoiptASxtXU10jazRCP865E97k=
|
||||
golang.org/x/arch v0.3.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
|
||||
|
Loading…
Reference in New Issue
Block a user