allow alternative logger implementations

This commit is contained in:
Pavel 2019-12-25 17:36:02 +03:00
parent a0d6a13e77
commit 9ad220967e
8 changed files with 176 additions and 16 deletions

View File

@ -19,7 +19,7 @@ type Engine struct {
Utils Utils
ginEngine *gin.Engine ginEngine *gin.Engine
httpClient *http.Client httpClient *http.Client
Logger *logging.Logger Logger LoggerInterface
csrf *CSRF csrf *CSRF
jobManager *JobManager jobManager *JobManager
Sessions sessions.Store Sessions sessions.Store

View File

@ -8,7 +8,6 @@ import (
"net/http" "net/http"
"time" "time"
"github.com/op/go-logging"
"github.com/pkg/errors" "github.com/pkg/errors"
) )
@ -46,7 +45,7 @@ type HTTPClientBuilder struct {
httpClient *http.Client httpClient *http.Client
httpTransport *http.Transport httpTransport *http.Transport
dialer *net.Dialer dialer *net.Dialer
logger *logging.Logger logger LoggerInterface
built bool built bool
logging bool logging bool
timeout time.Duration timeout time.Duration
@ -70,7 +69,7 @@ func NewHTTPClientBuilder() *HTTPClientBuilder {
} }
// WithLogger sets provided logger into HTTPClientBuilder // WithLogger sets provided logger into HTTPClientBuilder
func (b *HTTPClientBuilder) WithLogger(logger *logging.Logger) *HTTPClientBuilder { func (b *HTTPClientBuilder) WithLogger(logger LoggerInterface) *HTTPClientBuilder {
if logger != nil { if logger != nil {
b.logger = logger b.logger = logger
} }

View File

@ -52,7 +52,7 @@ type Job struct {
type JobManager struct { type JobManager struct {
jobs *sync.Map jobs *sync.Map
enableLogging bool enableLogging bool
logger *logging.Logger logger LoggerInterface
} }
// getWrappedFunc wraps job into function // getWrappedFunc wraps job into function
@ -143,7 +143,7 @@ func DefaultJobPanicHandler() JobPanicHandler {
} }
// SetLogger sets logger into JobManager // SetLogger sets logger into JobManager
func (j *JobManager) SetLogger(logger *logging.Logger) *JobManager { func (j *JobManager) SetLogger(logger LoggerInterface) *JobManager {
if logger != nil { if logger != nil {
j.logger = logger j.logger = logger
} }

View File

@ -324,10 +324,10 @@ func (t *JobManagerTest) ranFlag() bool {
func (t *JobManagerTest) Test_SetLogger() { func (t *JobManagerTest) Test_SetLogger() {
t.manager.logger = nil t.manager.logger = nil
t.manager.SetLogger(NewLogger("test", logging.ERROR, DefaultLogFormatter())) t.manager.SetLogger(NewLogger("test", logging.ERROR, DefaultLogFormatter()))
assert.IsType(t.T(), &logging.Logger{}, t.manager.logger) assert.IsType(t.T(), &Logger{}, t.manager.logger)
t.manager.SetLogger(nil) t.manager.SetLogger(nil)
assert.IsType(t.T(), &logging.Logger{}, t.manager.logger) assert.IsType(t.T(), &Logger{}, t.manager.logger)
} }
func (t *JobManagerTest) Test_SetLogging() { func (t *JobManagerTest) Test_SetLogging() {

View File

@ -39,6 +39,23 @@ func NewLocalizer(locale language.Tag, bundle *i18n.Bundle, matcher language.Mat
return localizer return localizer
} }
// NewLocalizerFS returns localizer instance with specified parameters. *packr.Box should be used instead of directory.
// Usage:
// NewLocalizerFS(language.English, DefaultLocalizerBundle(), DefaultLocalizerMatcher(), translationsBox)
// TODO This code should be covered with tests.
func NewLocalizerFS(locale language.Tag, bundle *i18n.Bundle, matcher language.Matcher, translationsBox *packr.Box) *Localizer {
localizer := &Localizer{
i18n: nil,
LocaleBundle: bundle,
LocaleMatcher: matcher,
TranslationsBox: translationsBox,
}
localizer.SetLanguage(locale)
localizer.LoadTranslations()
return localizer
}
// DefaultLocalizerBundle returns new localizer bundle with English as default language // DefaultLocalizerBundle returns new localizer bundle with English as default language
func DefaultLocalizerBundle() *i18n.Bundle { func DefaultLocalizerBundle() *i18n.Bundle {
return i18n.NewBundle(language.English) return i18n.NewBundle(language.English)

View File

@ -2,14 +2,49 @@ package core
import ( import (
"os" "os"
"sync"
"github.com/op/go-logging" "github.com/op/go-logging"
) )
// NewLogger will create new logger with specified formatter. // LoggerInterface contains methods which should be present in logger implementation
type LoggerInterface interface {
Fatal(args ...interface{})
Fatalf(format string, args ...interface{})
Panic(args ...interface{})
Panicf(format string, args ...interface{})
Critical(args ...interface{})
Criticalf(format string, args ...interface{})
Error(args ...interface{})
Errorf(format string, args ...interface{})
Warning(args ...interface{})
Warningf(format string, args ...interface{})
Notice(args ...interface{})
Noticef(format string, args ...interface{})
Info(args ...interface{})
Infof(format string, args ...interface{})
Debug(args ...interface{})
Debugf(format string, args ...interface{})
}
// Logger component. Uses github.com/op/go-logging under the hood.
type Logger struct {
logger *logging.Logger
mutex *sync.RWMutex
}
// NewLogger will create new goroutine-safe logger with specified formatter.
// Usage: // Usage:
// logger := NewLogger("telegram", logging.ERROR, DefaultLogFormatter()) // logger := NewLogger("telegram", logging.ERROR, DefaultLogFormatter())
func NewLogger(transportCode string, logLevel logging.Level, logFormat logging.Formatter) *logging.Logger { func NewLogger(transportCode string, logLevel logging.Level, logFormat logging.Formatter) *Logger {
return &Logger{
logger: newInheritedLogger(transportCode, logLevel, logFormat),
mutex: &sync.RWMutex{},
}
}
// newInheritedLogger is a constructor for underlying logger in Logger struct.
func newInheritedLogger(transportCode string, logLevel logging.Level, logFormat logging.Formatter) *logging.Logger {
logger := logging.MustGetLogger(transportCode) logger := logging.MustGetLogger(transportCode)
logBackend := logging.NewLogBackend(os.Stdout, "", 0) logBackend := logging.NewLogBackend(os.Stdout, "", 0)
formatBackend := logging.NewBackendFormatter(logBackend, logFormat) formatBackend := logging.NewBackendFormatter(logBackend, logFormat)
@ -26,3 +61,114 @@ func DefaultLogFormatter() logging.Formatter {
`%{time:2006-01-02 15:04:05.000} %{level:.4s} => %{message}`, `%{time:2006-01-02 15:04:05.000} %{level:.4s} => %{message}`,
) )
} }
// Fatal is equivalent to l.Critical(fmt.Sprint()) followed by a call to os.Exit(1).
func (l *Logger) Fatal(args ...interface{}) {
l.mutex.Lock()
defer l.mutex.Unlock()
l.logger.Fatal(args...)
}
// Fatalf is equivalent to l.Critical followed by a call to os.Exit(1).
func (l *Logger) Fatalf(format string, args ...interface{}) {
l.mutex.Lock()
defer l.mutex.Unlock()
l.logger.Fatalf(format, args...)
}
// Panic is equivalent to l.Critical(fmt.Sprint()) followed by a call to panic().
func (l *Logger) Panic(args ...interface{}) {
l.mutex.Lock()
defer l.mutex.Unlock()
l.logger.Panic(args...)
}
// Panicf is equivalent to l.Critical followed by a call to panic().
func (l *Logger) Panicf(format string, args ...interface{}) {
l.mutex.Lock()
defer l.mutex.Unlock()
l.logger.Panicf(format, args...)
}
// Critical logs a message using CRITICAL as log level.
func (l *Logger) Critical(args ...interface{}) {
l.mutex.Lock()
defer l.mutex.Unlock()
l.logger.Critical(args...)
}
// Criticalf logs a message using CRITICAL as log level.
func (l *Logger) Criticalf(format string, args ...interface{}) {
l.mutex.Lock()
defer l.mutex.Unlock()
l.logger.Criticalf(format, args...)
}
// Error logs a message using ERROR as log level.
func (l *Logger) Error(args ...interface{}) {
l.mutex.Lock()
defer l.mutex.Unlock()
l.logger.Error(args...)
}
// Errorf logs a message using ERROR as log level.
func (l *Logger) Errorf(format string, args ...interface{}) {
l.mutex.Lock()
defer l.mutex.Unlock()
l.logger.Errorf(format, args...)
}
// Warning logs a message using WARNING as log level.
func (l *Logger) Warning(args ...interface{}) {
l.mutex.Lock()
defer l.mutex.Unlock()
l.logger.Warning(args...)
}
func (l *Logger) Warningf(format string, args ...interface{}) {
l.mutex.Lock()
defer l.mutex.Unlock()
l.logger.Warningf(format, args...)
}
// Warningf logs a message using WARNING as log level.
func (l *Logger) Notice(args ...interface{}) {
l.mutex.Lock()
defer l.mutex.Unlock()
l.logger.Notice(args...)
}
// Noticef logs a message using NOTICE as log level.
func (l *Logger) Noticef(format string, args ...interface{}) {
l.mutex.Lock()
defer l.mutex.Unlock()
l.logger.Noticef(format, args...)
}
// Info logs a message using INFO as log level.
func (l *Logger) Info(args ...interface{}) {
l.mutex.Lock()
defer l.mutex.Unlock()
l.logger.Info(args...)
}
// Infof logs a message using INFO as log level.
func (l *Logger) Infof(format string, args ...interface{}) {
l.mutex.Lock()
defer l.mutex.Unlock()
l.logger.Infof(format, args...)
}
// Debug logs a message using DEBUG as log level.
func (l *Logger) Debug(args ...interface{}) {
l.mutex.Lock()
defer l.mutex.Unlock()
l.logger.Debug(args...)
}
// Debugf logs a message using DEBUG as log level.
func (l *Logger) Debugf(format string, args ...interface{}) {
l.mutex.Lock()
defer l.mutex.Unlock()
l.logger.Debugf(format, args...)
}

View File

@ -13,7 +13,6 @@ import (
"github.com/getsentry/raven-go" "github.com/getsentry/raven-go"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/op/go-logging"
) )
// ErrorHandlerFunc will handle errors // ErrorHandlerFunc will handle errors
@ -39,7 +38,7 @@ type Sentry struct {
Stacktrace bool Stacktrace bool
DefaultError string DefaultError string
Localizer *Localizer Localizer *Localizer
Logger *logging.Logger Logger LoggerInterface
Client *raven.Client Client *raven.Client
} }
@ -57,7 +56,7 @@ type SentryTaggedScalar struct {
} }
// NewSentry constructor // NewSentry constructor
func NewSentry(sentryDSN string, defaultError string, taggedTypes SentryTaggedTypes, logger *logging.Logger, localizer *Localizer) *Sentry { func NewSentry(sentryDSN string, defaultError string, taggedTypes SentryTaggedTypes, logger LoggerInterface, localizer *Localizer) *Sentry {
sentry := &Sentry{ sentry := &Sentry{
DefaultError: defaultError, DefaultError: defaultError,
TaggedTypes: taggedTypes, TaggedTypes: taggedTypes,

View File

@ -17,7 +17,6 @@ import (
"github.com/aws/aws-sdk-go/aws/credentials" "github.com/aws/aws-sdk-go/aws/credentials"
"github.com/aws/aws-sdk-go/aws/session" "github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/s3/s3manager" "github.com/aws/aws-sdk-go/service/s3/s3manager"
"github.com/op/go-logging"
v5 "github.com/retailcrm/api-client-go/v5" v5 "github.com/retailcrm/api-client-go/v5"
v1 "github.com/retailcrm/mg-transport-api-client-go/v1" v1 "github.com/retailcrm/mg-transport-api-client-go/v1"
) )
@ -27,12 +26,12 @@ type Utils struct {
IsDebug bool IsDebug bool
TokenCounter uint32 TokenCounter uint32
ConfigAWS ConfigAWS ConfigAWS ConfigAWS
Logger *logging.Logger Logger LoggerInterface
slashRegex *regexp.Regexp slashRegex *regexp.Regexp
} }
// NewUtils will create new Utils instance // NewUtils will create new Utils instance
func NewUtils(awsConfig ConfigAWS, logger *logging.Logger, debug bool) *Utils { func NewUtils(awsConfig ConfigAWS, logger LoggerInterface, debug bool) *Utils {
return &Utils{ return &Utils{
IsDebug: debug, IsDebug: debug,
ConfigAWS: awsConfig, ConfigAWS: awsConfig,