cmd/cli: adopt FilteredLevelWriter when doing internal logging

Without verbose log, we use internal log writer with log level set to
debug. However, this will affect other writers, like console log, since
they are default to notice level.

By adopting FilteredLevelWriter, we can make internal log writer run in
debug level, but all others will run in default level instead.
This commit is contained in:
Cuong Manh Le
2024-12-12 15:47:18 +07:00
committed by Cuong Manh Le
parent 02ee113b95
commit 8a96b8bec4
6 changed files with 35 additions and 24 deletions

View File

@@ -266,10 +266,10 @@ func run(appCallback *AppCallback, stopCh chan struct{}) {
// Log config do not have thing to validate, so it's safe to init log here,
// so it's able to log information in processCDFlags.
initLogging()
logWriters := initLogging()
// Initializing internal logging after global logging.
p.initInternalLogging()
p.initInternalLogging(logWriters)
mainLog.Load().Info().Msgf("starting ctrld %s", curVersion())
mainLog.Load().Info().Msgf("os: %s", osVersion())

View File

@@ -3,6 +3,7 @@ package cli
import (
"bytes"
"errors"
"io"
"os"
"sync"
"time"
@@ -59,7 +60,7 @@ func (lw *logWriter) Write(p []byte) (int, error) {
}
// initInternalLogging performs internal logging if there's no log enabled.
func (p *prog) initInternalLogging() {
func (p *prog) initInternalLogging(writers []io.Writer) {
if !p.needInternalLogging() {
return
}
@@ -72,13 +73,24 @@ func (p *prog) initInternalLogging() {
p.mu.Lock()
lw := p.internalLogWriter
p.mu.Unlock()
multi := zerolog.MultiLevelWriter(lw)
// If ctrld was run without explicit verbose level,
// run the internal logging at debug level, so we could
// have enough information for troubleshooting.
if verbose == 0 {
for i := range writers {
w := &zerolog.FilteredLevelWriter{
Writer: zerolog.LevelWriterAdapter{Writer: writers[i]},
Level: zerolog.NoticeLevel,
}
writers[i] = w
}
zerolog.SetGlobalLevel(zerolog.DebugLevel)
}
writers = append(writers, lw)
multi := zerolog.MultiLevelWriter(writers...)
l := mainLog.Load().Output(multi).With().Logger()
mainLog.Store(&l)
ctrld.ProxyLogger.Store(&l)
if verbose == 0 {
zerolog.SetGlobalLevel(zerolog.DebugLevel)
}
}
// needInternalLogging reports whether prog needs to run internal logging.

View File

@@ -101,9 +101,9 @@ func initConsoleLogging() {
}
// initLogging initializes global logging setup.
func initLogging() {
func initLogging() []io.Writer {
zerolog.TimeFieldFormat = time.RFC3339 + ".000"
initLoggingWithBackup(true)
return initLoggingWithBackup(true)
}
// initLoggingWithBackup initializes log setup base on current config.
@@ -112,8 +112,8 @@ func initLogging() {
// This is only used in runCmd for special handling in case of logging config
// change in cd mode. Without special reason, the caller should use initLogging
// wrapper instead of calling this function directly.
func initLoggingWithBackup(doBackup bool) {
writers := []io.Writer{io.Discard}
func initLoggingWithBackup(doBackup bool) []io.Writer {
var writers []io.Writer
if logFilePath := normalizeLogFilePath(cfg.Service.LogPath); logFilePath != "" {
// Create parent directory if necessary.
if err := os.MkdirAll(filepath.Dir(logFilePath), 0750); err != nil {
@@ -151,21 +151,22 @@ func initLoggingWithBackup(doBackup bool) {
switch {
case silent:
zerolog.SetGlobalLevel(zerolog.NoLevel)
return
return writers
case verbose == 1:
logLevel = "info"
case verbose > 1:
logLevel = "debug"
}
if logLevel == "" {
return
return writers
}
level, err := zerolog.ParseLevel(logLevel)
if err != nil {
mainLog.Load().Warn().Err(err).Msg("could not set log level")
return
return writers
}
zerolog.SetGlobalLevel(level)
return writers
}
func initCache() {

View File

@@ -514,13 +514,13 @@ func (p *prog) run(reload bool, reloadCh chan struct{}) {
if !reload {
// Stop writing log to unix socket.
consoleWriter.Out = os.Stdout
initLoggingWithBackup(false)
logWriters := initLoggingWithBackup(false)
if p.logConn != nil {
_ = p.logConn.Close()
}
go p.apiConfigReload()
p.postRun()
p.initInternalLogging()
p.initInternalLogging(logWriters)
}
wg.Wait()
}