Skip to content

Commit

Permalink
backport of commit 3f9dbab (#16172)
Browse files Browse the repository at this point in the history
Co-authored-by: Chris Capurso <1036769+ccapurso@users.noreply.github.com>
  • Loading branch information
hc-github-team-secure-vault-core and ccapurso committed Jun 28, 2022
1 parent 624f8b4 commit 6ad55a8
Show file tree
Hide file tree
Showing 13 changed files with 587 additions and 17 deletions.
3 changes: 3 additions & 0 deletions changelog/16111.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:improvement
core: Add `sys/loggers` and `sys/loggers/:name` endpoints to provide ability to modify logging verbosity
```
18 changes: 11 additions & 7 deletions command/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -458,8 +458,9 @@ func (c *ServerCommand) runRecoveryMode() int {
}

c.logger = hclog.NewInterceptLogger(&hclog.LoggerOptions{
Output: c.gatedWriter,
Level: level,
Output: c.gatedWriter,
Level: level,
IndependentLevels: true,
// Note that if logFormat is either unspecified or standard, then
// the resulting logger's format will be standard.
JSONFormat: logFormat == logging.JSONFormat,
Expand Down Expand Up @@ -590,6 +591,7 @@ func (c *ServerCommand) runRecoveryMode() int {
Physical: backend,
StorageType: config.Storage.Type,
Seal: barrierSeal,
LogLevel: logLevelString,
Logger: c.logger,
DisableMlock: config.DisableMlock,
RecoveryMode: c.flagRecovery,
Expand Down Expand Up @@ -1114,14 +1116,16 @@ func (c *ServerCommand) Run(args []string) int {

if c.flagDevThreeNode || c.flagDevFourCluster {
c.logger = hclog.NewInterceptLogger(&hclog.LoggerOptions{
Mutex: &sync.Mutex{},
Output: c.gatedWriter,
Level: hclog.Trace,
Mutex: &sync.Mutex{},
Output: c.gatedWriter,
Level: hclog.Trace,
IndependentLevels: true,
})
} else {
c.logger = hclog.NewInterceptLogger(&hclog.LoggerOptions{
Output: c.gatedWriter,
Level: level,
Output: c.gatedWriter,
Level: level,
IndependentLevels: true,
// Note that if logFormat is either unspecified or standard, then
// the resulting logger's format will be standard.
JSONFormat: logFormat == logging.JSONFormat,
Expand Down
7 changes: 4 additions & 3 deletions sdk/helper/logging/logging.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,10 @@ func NewVaultLogger(level log.Level) log.Logger {
// writer and a Vault formatter
func NewVaultLoggerWithWriter(w io.Writer, level log.Level) log.Logger {
opts := &log.LoggerOptions{
Level: level,
Output: w,
JSONFormat: ParseEnvLogFormat() == JSONFormat,
Level: level,
IndependentLevels: true,
Output: w,
JSONFormat: ParseEnvLogFormat() == JSONFormat,
}
return log.New(opts)
}
Expand Down
9 changes: 7 additions & 2 deletions vault/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -318,14 +318,19 @@ func (c *Core) startClusterListener(ctx context.Context) error {
networkLayer := c.clusterNetworkLayer

if networkLayer == nil {
networkLayer = cluster.NewTCPLayer(c.clusterListenerAddrs, c.logger.Named("cluster-listener.tcp"))
tcpLogger := c.logger.Named("cluster-listener.tcp")
networkLayer = cluster.NewTCPLayer(c.clusterListenerAddrs, tcpLogger)
c.AddLogger(tcpLogger)
}

listenerLogger := c.logger.Named("cluster-listener")
c.clusterListener.Store(cluster.NewListener(networkLayer,
c.clusterCipherSuites,
c.logger.Named("cluster-listener"),
listenerLogger,
5*c.clusterHeartbeatInterval))

c.AddLogger(listenerLogger)

err := c.getClusterListener().Run(ctx)
if err != nil {
return err
Expand Down
23 changes: 23 additions & 0 deletions vault/core.go
Original file line number Diff line number Diff line change
Expand Up @@ -406,6 +406,9 @@ type Core struct {
baseLogger log.Logger
logger log.Logger

// log level provided by config, CLI flag, or env
logLevel string

// Disables the trace display for Sentinel checks
sentinelTraceDisabled bool

Expand Down Expand Up @@ -656,6 +659,8 @@ type CoreConfig struct {

SecureRandomReader io.Reader

LogLevel string

Logger log.Logger

// Disables the trace display for Sentinel checks
Expand Down Expand Up @@ -835,6 +840,7 @@ func CreateCore(conf *CoreConfig) (*Core, error) {
standbyStopCh: new(atomic.Value),
baseLogger: conf.Logger,
logger: conf.Logger.Named("core"),
logLevel: conf.LogLevel,

defaultLeaseTTL: conf.DefaultLeaseTTL,
maxLeaseTTL: conf.MaxLeaseTTL,
Expand Down Expand Up @@ -1013,6 +1019,10 @@ func NewCore(conf *CoreConfig) (*Core, error) {

c.loginMFABackend = NewLoginMFABackend(c, conf.Logger)

if c.loginMFABackend.mfaLogger != nil {
c.AddLogger(c.loginMFABackend.mfaLogger)
}

logicalBackends := make(map[string]logical.Factory)
for k, f := range conf.LogicalBackends {
logicalBackends[k] = f
Expand Down Expand Up @@ -2788,6 +2798,19 @@ func (c *Core) SetLogLevel(level log.Level) {
}
}

func (c *Core) SetLogLevelByName(name string, level log.Level) error {
c.allLoggersLock.RLock()
defer c.allLoggersLock.RUnlock()
for _, logger := range c.allLoggers {
if logger.Name() == name {
logger.SetLevel(level)
return nil
}
}

return fmt.Errorf("logger %q does not exist", name)
}

// SetConfig sets core's config object to the newly provided config.
func (c *Core) SetConfig(conf *server.Config) {
c.rawConfig.Store(conf)
Expand Down
8 changes: 6 additions & 2 deletions vault/expiration.go
Original file line number Diff line number Diff line change
Expand Up @@ -313,9 +313,12 @@ func getNumExpirationWorkers(c *Core, l log.Logger) int {
// NewExpirationManager creates a new ExpirationManager that is backed
// using a given view, and uses the provided router for revocation.
func NewExpirationManager(c *Core, view *BarrierView, e ExpireLeaseStrategy, logger log.Logger) *ExpirationManager {
jobManager := fairshare.NewJobManager("expire", getNumExpirationWorkers(c, logger), logger.Named("job-manager"), c.metricSink)
managerLogger := logger.Named("job-manager")
jobManager := fairshare.NewJobManager("expire", getNumExpirationWorkers(c, logger), managerLogger, c.metricSink)
jobManager.Start()

c.AddLogger(managerLogger)

exp := &ExpirationManager{
core: c,
router: c.router,
Expand Down Expand Up @@ -1264,7 +1267,8 @@ func (m *ExpirationManager) Renew(ctx context.Context, leaseID string, increment
// RenewToken is used to renew a token which does not need to
// invoke a logical backend.
func (m *ExpirationManager) RenewToken(ctx context.Context, req *logical.Request, te *logical.TokenEntry,
increment time.Duration) (*logical.Response, error) {
increment time.Duration,
) (*logical.Response, error) {
defer metrics.MeasureSince([]string{"expire", "renew-token"}, time.Now())

tokenNS, err := NamespaceByID(ctx, te.NamespaceID, m.core)
Expand Down
106 changes: 106 additions & 0 deletions vault/logical_system.go
Original file line number Diff line number Diff line change
Expand Up @@ -4424,6 +4424,112 @@ func (b *SystemBackend) handleVersionHistoryList(ctx context.Context, req *logic
return logical.ListResponseWithInfo(respKeys, respKeyInfo), nil
}

// getLogLevel returns the hclog.Level that corresponds with the provided level string.
// This differs hclog.LevelFromString in that it supports additional level strings so
// that in remains consistent with the handling found in the "vault server" command.
func getLogLevel(logLevel string) (log.Level, error) {
var level log.Level

switch logLevel {
case "trace":
level = log.Trace
case "debug":
level = log.Debug
case "notice", "info", "":
level = log.Info
case "warn", "warning":
level = log.Warn
case "err", "error":
level = log.Error
default:
return level, fmt.Errorf("unrecognized log level %q", logLevel)
}

return level, nil
}

func (b *SystemBackend) handleLoggersWrite(ctx context.Context, req *logical.Request, d *framework.FieldData) (*logical.Response, error) {
logLevelRaw, ok := d.GetOk("level")

if !ok {
return logical.ErrorResponse("level is required"), nil
}

logLevel := logLevelRaw.(string)
if logLevel == "" {
return logical.ErrorResponse("level is empty"), nil
}

level, err := getLogLevel(logLevel)
if err != nil {
return logical.ErrorResponse(fmt.Sprintf("invalid level provided: %s", err.Error())), nil
}

b.Core.SetLogLevel(level)

return nil, nil
}

func (b *SystemBackend) handleLoggersDelete(ctx context.Context, req *logical.Request, d *framework.FieldData) (*logical.Response, error) {
level, err := getLogLevel(b.Core.logLevel)
if err != nil {
return logical.ErrorResponse(fmt.Sprintf("log level from config is invalid: %s", err.Error())), nil
}

b.Core.SetLogLevel(level)

return nil, nil
}

func (b *SystemBackend) handleLoggersByNameWrite(ctx context.Context, req *logical.Request, d *framework.FieldData) (*logical.Response, error) {
nameRaw, nameOk := d.GetOk("name")
if !nameOk {
return logical.ErrorResponse("name is required"), nil
}

logLevelRaw, logLevelOk := d.GetOk("level")

if !logLevelOk {
return logical.ErrorResponse("level is required"), nil
}

logLevel := logLevelRaw.(string)
if logLevel == "" {
return logical.ErrorResponse("level is empty"), nil
}

level, err := getLogLevel(logLevel)
if err != nil {
return logical.ErrorResponse(fmt.Sprintf("invalid level provided: %s", err.Error())), nil
}

err = b.Core.SetLogLevelByName(nameRaw.(string), level)
if err != nil {
return logical.ErrorResponse(fmt.Sprintf("invalid params: %s", err.Error())), nil
}

return nil, nil
}

func (b *SystemBackend) handleLoggersByNameDelete(ctx context.Context, req *logical.Request, d *framework.FieldData) (*logical.Response, error) {
nameRaw, ok := d.GetOk("name")
if !ok {
return logical.ErrorResponse("name is required"), nil
}

level, err := getLogLevel(b.Core.logLevel)
if err != nil {
return logical.ErrorResponse(fmt.Sprintf("log level from config is invalid: %s", err.Error())), nil
}

err = b.Core.SetLogLevelByName(nameRaw.(string), level)
if err != nil {
return logical.ErrorResponse(fmt.Sprintf("invalid params: %s", err.Error())), nil
}

return nil, nil
}

func sanitizePath(path string) string {
if !strings.HasSuffix(path, "/") {
path += "/"
Expand Down
44 changes: 44 additions & 0 deletions vault/logical_system_paths.go
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,50 @@ func (b *SystemBackend) configPaths() []*framework.Path {
},
},
},
{
Pattern: "loggers$",
Fields: map[string]*framework.FieldSchema{
"level": {
Type: framework.TypeString,
Description: "Log verbosity level. Supported values (in order of detail) are " +
"\"trace\", \"debug\", \"info\", \"warn\", and \"error\".",
},
},
Operations: map[logical.Operation]framework.OperationHandler{
logical.UpdateOperation: &framework.PathOperation{
Callback: b.handleLoggersWrite,
Summary: "Modify the log level for all existing loggers.",
},
logical.DeleteOperation: &framework.PathOperation{
Callback: b.handleLoggersDelete,
Summary: "Revert the all loggers to use log level provided in config.",
},
},
},
{
Pattern: "loggers/" + framework.MatchAllRegex("name"),
Fields: map[string]*framework.FieldSchema{
"name": {
Type: framework.TypeString,
Description: "The name of the logger to be modified.",
},
"level": {
Type: framework.TypeString,
Description: "Log verbosity level. Supported values (in order of detail) are " +
"\"trace\", \"debug\", \"info\", \"warn\", and \"error\".",
},
},
Operations: map[logical.Operation]framework.OperationHandler{
logical.UpdateOperation: &framework.PathOperation{
Callback: b.handleLoggersByNameWrite,
Summary: "Modify the log level of a single logger.",
},
logical.DeleteOperation: &framework.PathOperation{
Callback: b.handleLoggersByNameDelete,
Summary: "Revert a single logger to use log level provided in config.",
},
},
},
}
}

Expand Down

0 comments on commit 6ad55a8

Please sign in to comment.