forked from TrueCloudLab/frostfs-s3-gw
[#369] Add fileLogger config reloading after SIGHUP
Declared fileLogger struct in log_http.go, turn existing funcs to methods. Add ReloadFileLogger method Signed-off-by: Nikita Zinkevich <n.zinkevich@yadro.com>
This commit is contained in:
parent
6f8971dd0e
commit
a48c19fcf3
3 changed files with 73 additions and 37 deletions
|
@ -11,43 +11,62 @@ import (
|
||||||
|
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/internal/logs"
|
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/internal/logs"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
"go.uber.org/zap/zapcore"
|
|
||||||
"gopkg.in/natefinch/lumberjack.v2"
|
"gopkg.in/natefinch/lumberjack.v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
type LogHTTPConfig struct {
|
type (
|
||||||
Enabled bool
|
LogHTTPConfig struct {
|
||||||
MaxBody int64
|
Enabled bool
|
||||||
MaxLogSize int
|
MaxBody int64
|
||||||
OutputPath string
|
MaxLogSize int
|
||||||
UseGzip bool
|
OutputPath string
|
||||||
}
|
UseGzip bool
|
||||||
|
|
||||||
// getFileLogger returns file logger for http requests or creates new if not exists.
|
|
||||||
func (h *LogHTTPConfig) getFileLogger() (*zap.Logger, error) {
|
|
||||||
c := newLoggerConfig()
|
|
||||||
c.OutputPaths = []string{h.OutputPath}
|
|
||||||
if h.OutputPath != StdoutPath && h.OutputPath != StderrPath && h.OutputPath != "" {
|
|
||||||
err := h.registerOutputSink()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
c.OutputPaths[0] = SinkName + ":" + h.OutputPath
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return c.Build()
|
fileLogger struct {
|
||||||
|
*zap.Logger
|
||||||
|
logRoller *lumberjack.Logger
|
||||||
|
}
|
||||||
|
|
||||||
|
// Implementation of zap.Sink for using lumberjack
|
||||||
|
lumberjackSink struct {
|
||||||
|
*lumberjack.Logger
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
var filelog = fileLogger{}
|
||||||
|
|
||||||
|
// newFileLogger returns registers zap sink and returns new fileLogger
|
||||||
|
func newFileLogger(conf *LogHTTPConfig) (fileLogger, error) {
|
||||||
|
var flog = fileLogger{}
|
||||||
|
c := flog.newLoggerConfig()
|
||||||
|
c.OutputPaths = []string{conf.OutputPath}
|
||||||
|
if conf.OutputPath != StdoutPath && conf.OutputPath != StderrPath && conf.OutputPath != "" {
|
||||||
|
err := flog.registerOutputSink(conf)
|
||||||
|
if err != nil {
|
||||||
|
return flog, err
|
||||||
|
}
|
||||||
|
c.OutputPaths[0] = SinkName + ":" + conf.OutputPath
|
||||||
|
}
|
||||||
|
log, err := c.Build()
|
||||||
|
if err != nil {
|
||||||
|
return flog, err
|
||||||
|
}
|
||||||
|
flog.Logger = log
|
||||||
|
|
||||||
|
return flog, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// registerOutputSink registers sink for logger file output.
|
// registerOutputSink creates and registers sink for logger file output.
|
||||||
func (h *LogHTTPConfig) registerOutputSink() error {
|
func (f *fileLogger) registerOutputSink(conf *LogHTTPConfig) error {
|
||||||
logRoller := &lumberjack.Logger{
|
f.logRoller = &lumberjack.Logger{
|
||||||
Filename: h.OutputPath,
|
Filename: conf.OutputPath,
|
||||||
MaxSize: h.MaxLogSize,
|
MaxSize: conf.MaxLogSize,
|
||||||
Compress: h.UseGzip,
|
Compress: conf.UseGzip,
|
||||||
}
|
}
|
||||||
err := zap.RegisterSink(SinkName, func(_ *url.URL) (zap.Sink, error) {
|
err := zap.RegisterSink(SinkName, func(_ *url.URL) (zap.Sink, error) {
|
||||||
return lumberjackSink{
|
return lumberjackSink{
|
||||||
Logger: logRoller,
|
Logger: f.logRoller,
|
||||||
}, nil
|
}, nil
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -57,18 +76,33 @@ func (h *LogHTTPConfig) registerOutputSink() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type lumberjackSink struct {
|
func (lumberjackSink) Sync() error {
|
||||||
*lumberjack.Logger
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (lumberjackSink) Sync() error {
|
func ReloadFileLogger(conf *LogHTTPConfig) error {
|
||||||
|
if filelog.logRoller == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
filelog.logRoller.MaxSize = conf.MaxLogSize
|
||||||
|
filelog.logRoller.Compress = conf.UseGzip
|
||||||
|
|
||||||
|
if filelog.logRoller.Filename != conf.OutputPath {
|
||||||
|
filelog.logRoller.Filename = conf.OutputPath
|
||||||
|
if err := filelog.logRoller.Rotate(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// LogHTTP logs http parameters from s3 request.
|
// LogHTTP logs http parameters from s3 request.
|
||||||
func LogHTTP(l *zap.Logger, config *LogHTTPConfig) Func {
|
func LogHTTP(l *zap.Logger, config *LogHTTPConfig) Func {
|
||||||
fileLogger, err := config.getFileLogger()
|
var err error
|
||||||
|
filelog, err = newFileLogger(config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
l.Warn(logs.FailedToInitializeHTTPLogger)
|
||||||
return func(h http.Handler) http.Handler {
|
return func(h http.Handler) http.Handler {
|
||||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
h.ServeHTTP(w, r)
|
h.ServeHTTP(w, r)
|
||||||
|
@ -81,7 +115,7 @@ func LogHTTP(l *zap.Logger, config *LogHTTPConfig) Func {
|
||||||
h.ServeHTTP(w, r)
|
h.ServeHTTP(w, r)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
var httplog = fileLogger.With(
|
var httplog = filelog.With(
|
||||||
zap.String("from", r.RemoteAddr),
|
zap.String("from", r.RemoteAddr),
|
||||||
zap.String("URI", r.RequestURI),
|
zap.String("URI", r.RequestURI),
|
||||||
zap.String("method", r.Method),
|
zap.String("method", r.Method),
|
||||||
|
@ -102,7 +136,7 @@ func LogHTTP(l *zap.Logger, config *LogHTTPConfig) Func {
|
||||||
}
|
}
|
||||||
|
|
||||||
// newLoggerConfig creates new zap.Config with disabled base fields.
|
// newLoggerConfig creates new zap.Config with disabled base fields.
|
||||||
func newLoggerConfig() zap.Config {
|
func (*fileLogger) newLoggerConfig() zap.Config {
|
||||||
c := zap.NewProductionConfig()
|
c := zap.NewProductionConfig()
|
||||||
c.DisableCaller = true
|
c.DisableCaller = true
|
||||||
c.DisableStacktrace = true
|
c.DisableStacktrace = true
|
||||||
|
|
|
@ -390,9 +390,9 @@ http_logging:
|
||||||
|----------------|--------|---------------|---------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
|----------------|--------|---------------|---------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||||
| `enabled` | bool | yes | false | Flag to enable the logger. |
|
| `enabled` | bool | yes | false | Flag to enable the logger. |
|
||||||
| `max_body` | int | yes | 1024 | Max body size for log output in bytes. |
|
| `max_body` | int | yes | 1024 | Max body size for log output in bytes. |
|
||||||
| `max_log_size` | int | no | 50 | Log file size threshold (in megabytes) to be moved in backup file. After reaching threshold, initial filename is appended with timestamp. And new empty file with initial name is created. |
|
| `max_log_size` | int | yes | 50 | Log file size threshold (in megabytes) to be moved in backup file. After reaching threshold, initial filename is appended with timestamp. And new empty file with initial name is created. |
|
||||||
| `gzip` | bool | no | false | Whether to enable Gzip compression for backup log files. |
|
| `gzip` | bool | yes | false | Whether to enable Gzip compression for backup log files. |
|
||||||
| `destination` | string | no | stdout | Specify path for log output. Accepts log file path, or "stdout" and "stderr" reserved words to print in output streams. |
|
| `destination` | string | yes | stdout | Specify path for log output. Accepts log file path, or "stdout" and "stderr" reserved words to print in output streams. |
|
||||||
|
|
||||||
|
|
||||||
### `cache` section
|
### `cache` section
|
||||||
|
|
|
@ -101,8 +101,10 @@ const (
|
||||||
FailedToResolveCID = "failed to resolve CID" // Debug in ../../api/middleware/metrics.go
|
FailedToResolveCID = "failed to resolve CID" // Debug in ../../api/middleware/metrics.go
|
||||||
RequestStart = "request start" // Info in ../../api/middleware/reqinfo.go
|
RequestStart = "request start" // Info in ../../api/middleware/reqinfo.go
|
||||||
RequestHTTP = "http request" // Info in ../../api/middleware/log_http.go
|
RequestHTTP = "http request" // Info in ../../api/middleware/log_http.go
|
||||||
|
FailedToInitializeHTTPLogger = "failed to initialize http logger" // Warn in ../../api/middleware/log_http.go
|
||||||
|
FailedToReloadHTTPFileLogger = "failed to reload http file logger" // Warn in ../../api/middleware/log_http.go
|
||||||
|
FailedToGetRequestBody = "failed to get request body" // Warn in ../../api/middleware/log_http.go
|
||||||
LogHTTPDisabledInThisBuild = "http logging disabled in this build" // Warn in ../../api/middleware/log_http_stub.go
|
LogHTTPDisabledInThisBuild = "http logging disabled in this build" // Warn in ../../api/middleware/log_http_stub.go
|
||||||
FailedToGetRequestBody = "failed to get request body" // Warn in ../../api/middleware/log_http_stub.go
|
|
||||||
FailedToUnescapeObjectName = "failed to unescape object name" // Warn in ../../api/middleware/reqinfo.go
|
FailedToUnescapeObjectName = "failed to unescape object name" // Warn in ../../api/middleware/reqinfo.go
|
||||||
InvalidDefaultMaxAge = "invalid defaultMaxAge" // Fatal in ../../cmd/s3-gw/app_settings.go
|
InvalidDefaultMaxAge = "invalid defaultMaxAge" // Fatal in ../../cmd/s3-gw/app_settings.go
|
||||||
CantShutDownService = "can't shut down service" // Panic in ../../cmd/s3-gw/service.go
|
CantShutDownService = "can't shut down service" // Panic in ../../cmd/s3-gw/service.go
|
||||||
|
|
Loading…
Reference in a new issue