Skip to content

Commit

Permalink
[nspcc-dev#1770] node: Support runtime re-configuration of the logger
Browse files Browse the repository at this point in the history
There is a need to re-configure storage node's logging on the
fly.

Provide `SubscribeConfigChanges` function to listen to changes of the
storage node config. Create dynamically configured `logger.Logger` in
`neofs-node` app and use it to log notifications about new Sidechain
blocks. Update `logger.Level` parameter on each `syscall.SIGHUP` signal.

Signed-off-by: Leonard Lyubich <ctulhurider@gmail.com>
  • Loading branch information
cthulhu-rider committed Oct 4, 2022
1 parent e926b6d commit 2ff2480
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 5 deletions.
4 changes: 3 additions & 1 deletion cmd/neofs-node/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,9 @@ type cfg struct {

internalErr chan error // channel for internal application errors at runtime

log *zap.Logger
log *logger.Logger

logN *logger.Logger

wg *sync.WaitGroup

Expand Down
30 changes: 29 additions & 1 deletion cmd/neofs-node/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@ package config

import (
"fmt"
"os"
"os/signal"
"strings"
"syscall"

"github.com/nspcc-dev/neofs-node/cmd/neofs-node/config/internal"
"github.com/spf13/viper"
Expand Down Expand Up @@ -52,7 +55,32 @@ func New(_ Prm, opts ...Option) *Config {
}
}

return &Config{
c := &Config{
v: v,
}

if len(o.reloadSubs) > 0 {
ch := make(chan os.Signal)
signal.Notify(ch, syscall.SIGHUP)

go func() {
for {
select {
case <-ch:
if o.path != "" {
err := v.ReadInConfig()
if err != nil {
panic(fmt.Errorf("failed to read config: %w", err))
}
}

for i := range o.reloadSubs {
o.reloadSubs[i](c)
}
}
}
}()
}

return c
}
10 changes: 10 additions & 0 deletions cmd/neofs-node/config/opts.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package config

type opts struct {
path string

reloadSubs []func(*Config)
}

func defaultOpts() *opts {
Expand All @@ -18,3 +20,11 @@ func WithConfigFile(path string) Option {
o.path = path
}
}

// SubscribeConfigChanges adds Config callback which will be invoked on each
// syscall.SIGHUP signal.
func SubscribeConfigChanges(f func(*Config)) Option {
return func(o *opts) {
o.reloadSubs = append(o.reloadSubs, f)
}
}
45 changes: 42 additions & 3 deletions cmd/neofs-node/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,12 @@ import (
"syscall"

"github.com/nspcc-dev/neofs-node/cmd/neofs-node/config"
loggerconfig "github.com/nspcc-dev/neofs-node/cmd/neofs-node/config/logger"
"github.com/nspcc-dev/neofs-node/misc"
"github.com/nspcc-dev/neofs-node/pkg/services/control"
"github.com/nspcc-dev/neofs-node/pkg/util/logger"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
)

const (
Expand Down Expand Up @@ -46,16 +49,52 @@ func main() {
os.Exit(SuccessReturnCode)
}

appCfg := config.New(config.Prm{}, config.WithConfigFile(*configFile))
var cfgLog logger.Config

err := validateConfig(appCfg)
logN, err := logger.NewConfigurable(&cfgLog)
fatalOnErr(err)

var appCfg *config.Config

appCfg = config.New(config.Prm{}, config.WithConfigFile(*configFile), config.SubscribeConfigChanges(func(c *config.Config) {
var lvl zapcore.Level

err = lvl.UnmarshalText([]byte(loggerconfig.Level(c)))
if err != nil {
logN.Write(logger.LevelError, "decode logging level",
logger.FieldError(err),
)
return
}

log.Println("decoded new level", lvl)

switch lvl {
default:
logN.Write(logger.LevelError, "unsupported logging level",
logger.FieldStringer("value", lvl),
)
return
case zapcore.DebugLevel:
cfgLog.SetLevel(logger.LevelDebug)
case zapcore.InfoLevel:
cfgLog.SetLevel(logger.LevelInfo)
case zapcore.WarnLevel:
cfgLog.SetLevel(logger.LevelWarn)
case zapcore.ErrorLevel:
cfgLog.SetLevel(logger.LevelError)
}
}))

err = validateConfig(appCfg)
fatalOnErr(err)

if *dryRunFlag {
return
}

c := initCfg(appCfg)
c.logN = logN

initApp(c)

Expand All @@ -79,7 +118,7 @@ func initAndLog(c *cfg, name string, initializer func(*cfg)) {
}

func initApp(c *cfg) {
c.ctx, c.ctxCancel = signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM, syscall.SIGHUP)
c.ctx, c.ctxCancel = signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)

initAndLog(c, "storage engine", func(c *cfg) {
fatalOnErr(c.cfgObject.cfgLocalStorage.localStorage.Open())
Expand Down

0 comments on commit 2ff2480

Please sign in to comment.