allow to customize the log level

The old log-verbose flag is not appropriate anymore.
You should now use the log-level flag to set your preferred log level.
The default level is "debug" as before, you can also set "info", "warn",
"error"

Signed-off-by: Nicola Murino <nicola.murino@gmail.com>
This commit is contained in:
Nicola Murino 2022-07-13 10:40:24 +02:00
parent 8fc4971df1
commit e0ce2e2e8a
No known key found for this signature in database
GPG key ID: 2F1FB59433D5A8CB
16 changed files with 95 additions and 57 deletions

View file

@ -30,7 +30,7 @@ Please take a look at the usage below to customize the startup options`,
LogMaxBackups: logMaxBackups,
LogMaxAge: logMaxAge,
LogCompress: logCompress,
LogVerbose: logVerbose,
LogLevel: logLevel,
LogUTCTime: logUTCTime,
Shutdown: make(chan bool),
}
@ -85,8 +85,9 @@ func getCustomServeFlags() []string {
result = append(result, "--"+logMaxAgeFlag)
result = append(result, strconv.Itoa(logMaxAge))
}
if logVerbose != defaultLogVerbose {
result = append(result, "--"+logVerboseFlag+"=false")
if logLevel != defaultLogLevel {
result = append(result, "--"+logLevelFlag)
result = append(result, logLevel)
}
if logUTCTime != defaultLogUTCTime {
result = append(result, "--"+logUTCTimeFlag+"=true")

View file

@ -31,7 +31,7 @@ var (
portablePassword string
portableStartDir string
portableLogFile string
portableLogVerbose bool
portableLogLevel string
portableLogUTCTime bool
portablePublicKeys []string
portablePermissions []string
@ -163,7 +163,7 @@ Please take a look at the usage below to customize the serving parameters`,
LogMaxBackups: defaultLogMaxBackup,
LogMaxAge: defaultLogMaxAge,
LogCompress: defaultLogCompress,
LogVerbose: portableLogVerbose,
LogLevel: portableLogLevel,
LogUTCTime: portableLogUTCTime,
Shutdown: make(chan bool),
PortableMode: 1,
@ -281,7 +281,11 @@ value`)
portableCmd.Flags().StringVarP(&portablePassword, "password", "p", "", `Leave empty to use an auto generated
value`)
portableCmd.Flags().StringVarP(&portableLogFile, logFilePathFlag, "l", "", "Leave empty to disable logging")
portableCmd.Flags().BoolVarP(&portableLogVerbose, logVerboseFlag, "v", false, "Enable verbose logs")
portableCmd.Flags().StringVar(&portableLogLevel, logLevelFlag, defaultLogLevel, `Set the log level.
Supported values:
debug, info, warn, error.
`)
portableCmd.Flags().BoolVar(&portableLogUTCTime, logUTCTimeFlag, false, "Use UTC time for logging")
portableCmd.Flags().StringSliceVarP(&portablePublicKeys, "public-key", "k", []string{}, "")
portableCmd.Flags().StringSliceVarP(&portablePermissions, "permissions", "g", []string{"list", "download"},

View file

@ -26,8 +26,8 @@ const (
logMaxAgeKey = "log_max_age"
logCompressFlag = "log-compress"
logCompressKey = "log_compress"
logVerboseFlag = "log-verbose"
logVerboseKey = "log_verbose"
logLevelFlag = "log-level"
logLevelKey = "log_level"
logUTCTimeFlag = "log-utc-time"
logUTCTimeKey = "log_utc_time"
loadDataFromFlag = "loaddata-from"
@ -45,7 +45,7 @@ const (
defaultLogMaxBackup = 5
defaultLogMaxAge = 28
defaultLogCompress = false
defaultLogVerbose = true
defaultLogLevel = "debug"
defaultLogUTCTime = false
defaultLoadDataFrom = ""
defaultLoadDataMode = 1
@ -61,7 +61,7 @@ var (
logMaxBackups int
logMaxAge int
logCompress bool
logVerbose bool
logLevel string
logUTCTime bool
loadDataFrom string
loadDataMode int
@ -215,13 +215,17 @@ It is unused if log-file-path is empty.
`)
viper.BindPFlag(logCompressKey, cmd.Flags().Lookup(logCompressFlag)) //nolint:errcheck
viper.SetDefault(logVerboseKey, defaultLogVerbose)
viper.BindEnv(logVerboseKey, "SFTPGO_LOG_VERBOSE") //nolint:errcheck
cmd.Flags().BoolVarP(&logVerbose, logVerboseFlag, "v", viper.GetBool(logVerboseKey),
`Enable verbose logs. This flag can be set
using SFTPGO_LOG_VERBOSE env var too.
viper.SetDefault(logLevelKey, defaultLogLevel)
viper.BindEnv(logLevelKey, "SFTPGO_LOG_LEVEL") //nolint:errcheck
cmd.Flags().StringVar(&logLevel, logLevelFlag, viper.GetString(logLevelKey),
`Set the log level. Supported values:
debug, info, warn, error.
This flag can be set
using SFTPGO_LOG_LEVEL env var too.
`)
viper.BindPFlag(logVerboseKey, cmd.Flags().Lookup(logVerboseFlag)) //nolint:errcheck
viper.BindPFlag(logLevelKey, cmd.Flags().Lookup(logLevelFlag)) //nolint:errcheck
viper.SetDefault(logUTCTimeKey, defaultLogUTCTime)
viper.BindEnv(logUTCTimeKey, "SFTPGO_LOG_UTC_TIME") //nolint:errcheck

View file

@ -28,7 +28,7 @@ Please take a look at the usage below to customize the startup options`,
LogMaxBackups: logMaxBackups,
LogMaxAge: logMaxAge,
LogCompress: logCompress,
LogVerbose: logVerbose,
LogLevel: logLevel,
LogUTCTime: logUTCTime,
LoadDataFrom: loadDataFrom,
LoadDataMode: loadDataMode,

View file

@ -28,7 +28,7 @@ var (
LogMaxBackups: logMaxBackups,
LogMaxAge: logMaxAge,
LogCompress: logCompress,
LogVerbose: logVerbose,
LogLevel: logLevel,
LogUTCTime: logUTCTime,
Shutdown: make(chan bool),
}

View file

@ -40,15 +40,22 @@ Command-line flags should be specified in the Subsystem declaration.
Run: func(cmd *cobra.Command, args []string) {
logSender := "startsubsys"
connectionID := xid.New().String()
logLevel := zerolog.DebugLevel
if !logVerbose {
logLevel = zerolog.InfoLevel
var zeroLogLevel zerolog.Level
switch logLevel {
case "info":
zeroLogLevel = zerolog.InfoLevel
case "warn":
zeroLogLevel = zerolog.WarnLevel
case "error":
zeroLogLevel = zerolog.ErrorLevel
default:
zeroLogLevel = zerolog.DebugLevel
}
logger.SetLogTime(logUTCTime)
if logJournalD {
logger.InitJournalDLogger(logLevel)
logger.InitJournalDLogger(zeroLogLevel)
} else {
logger.InitStdErrLogger(logLevel)
logger.InitStdErrLogger(zeroLogLevel)
}
osUser, err := user.Current()
if err != nil {
@ -84,7 +91,7 @@ Command-line flags should be specified in the Subsystem declaration.
logger.Error(logSender, "", "unable to initialize MFA: %v", err)
os.Exit(1)
}
if err := plugin.Initialize(config.GetPluginsConfig(), logVerbose); err != nil {
if err := plugin.Initialize(config.GetPluginsConfig(), logLevel); err != nil {
logger.Error(logSender, connectionID, "unable to initialize plugin system: %v", err)
os.Exit(1)
}
@ -182,13 +189,17 @@ error`)
addConfigFlags(subsystemCmd)
viper.SetDefault(logVerboseKey, defaultLogVerbose)
viper.BindEnv(logVerboseKey, "SFTPGO_LOG_VERBOSE") //nolint:errcheck
subsystemCmd.Flags().BoolVarP(&logVerbose, logVerboseFlag, "v", viper.GetBool(logVerboseKey),
`Enable verbose logs. This flag can be set
using SFTPGO_LOG_VERBOSE env var too.
viper.SetDefault(logLevelKey, defaultLogLevel)
viper.BindEnv(logLevelKey, "SFTPGO_LOG_LEVEL") //nolint:errcheck
subsystemCmd.Flags().StringVar(&logLevel, logLevelFlag, viper.GetString(logLevelKey),
`Set the log level. Supported values:
debug, info, warn, error.
This flag can be set
using SFTPGO_LOG_LEVEL env var too.
`)
viper.BindPFlag(logVerboseKey, subsystemCmd.Flags().Lookup(logVerboseFlag)) //nolint:errcheck
viper.BindPFlag(logLevelKey, subsystemCmd.Flags().Lookup(logLevelFlag)) //nolint:errcheck
viper.SetDefault(logUTCTimeKey, defaultLogUTCTime)
viper.BindEnv(logUTCTimeKey, "SFTPGO_LOG_UTC_TIME") //nolint:errcheck

View file

@ -264,7 +264,7 @@ func TestUnconfiguredHook(t *testing.T) {
Type: "notifier",
},
}
err := plugin.Initialize(pluginsConfig, true)
err := plugin.Initialize(pluginsConfig, "debug")
assert.Error(t, err)
assert.True(t, plugin.Handler.HasNotifiers())
@ -277,7 +277,7 @@ func TestUnconfiguredHook(t *testing.T) {
err = ExecuteActionNotification(c, operationDownload, "", "", "", "", "", 0, nil)
assert.NoError(t, err)
err = plugin.Initialize(nil, true)
err = plugin.Initialize(nil, "debug")
assert.NoError(t, err)
assert.False(t, plugin.Handler.HasNotifiers())

View file

@ -142,7 +142,7 @@ func TestDefenderIntegration(t *testing.T) {
if runtime.GOOS == osWindows {
pluginsConfig[0].Cmd += ".exe"
}
err = plugin.Initialize(pluginsConfig, true)
err = plugin.Initialize(pluginsConfig, "debug")
require.NoError(t, err)
ip := "127.1.1.1"

View file

@ -40,7 +40,7 @@ The `serve` command supports the following flags:
- `--log-max-age` int. Maximum number of days to retain old log files. Default 28 or the value of `SFTPGO_LOG_MAX_AGE` environment variable. It is unused if `log-file-path` is empty.
- `--log-max-backups` int. Maximum number of old log files to retain. Default 5 or the value of `SFTPGO_LOG_MAX_BACKUPS` environment variable. It is unused if `log-file-path` is empty.
- `--log-max-size` int. Maximum size in megabytes of the log file before it gets rotated. Default 10 or the value of `SFTPGO_LOG_MAX_SIZE` environment variable. It is unused if `log-file-path` is empty.
- `--log-verbose` boolean. Enable verbose logs. Default `true` or the value of `SFTPGO_LOG_VERBOSE` environment variable (1 or `true`, 0 or `false`).
- `--log-level` string. Set the log level. Supported values: `debug`, `info`, `warn`, `error`. Default `debug` or the value of `SFTPGO_LOG_LEVEL` environment variable.
- `--log-utc-time` boolean. Enable UTC time for logging. Default `false` or the value of `SFTPGO_LOG_UTC_TIME` environment variable (1 or `true`, 0 or `false`)
Log file can be rotated on demand sending a `SIGUSR1` signal on Unix based systems and using the command `sftpgo service rotatelogs` on Windows.

View file

@ -11,7 +11,7 @@ In this tutorial we explore the main features and concepts using the built-in we
- [Initial configuration](#Initial-configuration)
- [Creating users](#Creating-users)
- [Creating users with a Cloud Storage backend](#Creating-users-with-a-Cloud-Storage-backend)
- [Creating users with a local encrypted backend (Data At Rest Encryption)](#Creating-users-with-a-local-encrypted-backend-Data-At-Rest-Encryption))
- [Creating users with a local encrypted backend (Data At Rest Encryption)](#Creating-users-with-a-local-encrypted-backend-Data-At-Rest-Encryption)
- [Virtual permissions](#Virtual-permissions)
- [Virtual folders](#Virtual-folders)
- [Configuration parameters](#Configuration-parameters)
@ -60,7 +60,7 @@ Let's create our first local user:
![Add user](./img/add-user.png)
:warning: Please note that, on Linux, SFTPGo runs using a dedicated system user and group called `sftpgo`, for added security. If you want to be able to use diretories outside `/srv/sftpgo` you need to set the appropriate system level permissions. For example if you define `/home/username/test` as home dir you have to create this directory yourself with the proper permissions:
:warning: Please note that, on Linux, SFTPGo runs using a dedicated system user and group called `sftpgo`, for added security. If you want to be able to use directories outside `/srv/sftpgo` you need to set the appropriate system level permissions. For example if you define `/home/username/test` as home dir you have to create this directory yourself, if it doesn't exist, and set the appropriate system-level permissions:
```shell
sudo mkdir /home/username/test

View file

@ -76,8 +76,12 @@ Flags:
--gcs-storage-class string
-h, --help help for portable
-l, --log-file-path string Leave empty to disable logging
--log-level string Set the log level.
Supported values:
debug, info, warn, error.
(default "debug")
--log-utc-time Use UTC time for logging
-v, --log-verbose Enable verbose logs
-p, --password string Leave empty to use an auto generated
value
-g, --permissions strings User's permissions. "*" means any

6
go.mod
View file

@ -70,7 +70,7 @@ require (
golang.org/x/oauth2 v0.0.0-20220630143837-2104d58473e0
golang.org/x/sys v0.0.0-20220712014510-0a85c31ab51e
golang.org/x/time v0.0.0-20220609170525-579cf78fd858
google.golang.org/api v0.86.0
google.golang.org/api v0.87.0
gopkg.in/natefinch/lumberjack.v2 v2.0.0
)
@ -155,8 +155,8 @@ require (
golang.org/x/tools v0.1.11 // indirect
golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/genproto v0.0.0-20220711200234-e2551ce405a2 // indirect
google.golang.org/grpc v1.47.0 // indirect
google.golang.org/genproto v0.0.0-20220712132514-bdd2acd4974d // indirect
google.golang.org/grpc v1.48.0 // indirect
google.golang.org/protobuf v1.28.0 // indirect
gopkg.in/ini.v1 v1.66.6 // indirect
gopkg.in/square/go-jose.v2 v2.6.0 // indirect

10
go.sum
View file

@ -1115,8 +1115,9 @@ google.golang.org/api v0.78.0/go.mod h1:1Sg78yoMLOhlQTeF+ARBoytAcH1NNyyl390YMy6r
google.golang.org/api v0.80.0/go.mod h1:xY3nI94gbvBrE0J6NHXhxOmW97HG7Khjkku6AFB3Hyg=
google.golang.org/api v0.84.0/go.mod h1:NTsGnUFJMYROtiquksZHBWtHfeMC7iYthki7Eq3pa8o=
google.golang.org/api v0.85.0/go.mod h1:AqZf8Ep9uZ2pyTvgL+x0D3Zt0eoT9b5E8fmzfu6FO2g=
google.golang.org/api v0.86.0 h1:ZAnyOHQFIuWso1BodVfSaRyffD74T9ERGFa3k1fNk/U=
google.golang.org/api v0.86.0/go.mod h1:+Sem1dnrKlrXMR/X0bPnMWyluQe4RsNoYfmNLhOIkzw=
google.golang.org/api v0.87.0 h1:pUQVF/F+X7Tl1lo4LJoJf5BOpjtmINU80p9XpYTU2p4=
google.golang.org/api v0.87.0/go.mod h1:+Sem1dnrKlrXMR/X0bPnMWyluQe4RsNoYfmNLhOIkzw=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
@ -1223,8 +1224,8 @@ google.golang.org/genproto v0.0.0-20220616135557-88e70c0c3a90/go.mod h1:KEWEmljW
google.golang.org/genproto v0.0.0-20220617124728-180714bec0ad/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA=
google.golang.org/genproto v0.0.0-20220624142145-8cd45d7dbd1f/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA=
google.golang.org/genproto v0.0.0-20220628213854-d9e0b6570c03/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA=
google.golang.org/genproto v0.0.0-20220711200234-e2551ce405a2 h1:MzI+35zsW9oep697+BRlTWM296xmUQ5XDgyGuvZUIVo=
google.golang.org/genproto v0.0.0-20220711200234-e2551ce405a2/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA=
google.golang.org/genproto v0.0.0-20220712132514-bdd2acd4974d h1:YbuF5+kdiC516xIP60RvlHeFbY9sRDR73QsAGHpkeVw=
google.golang.org/genproto v0.0.0-20220712132514-bdd2acd4974d/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
@ -1255,8 +1256,9 @@ google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ5
google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ=
google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
google.golang.org/grpc v1.46.2/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
google.golang.org/grpc v1.47.0 h1:9n77onPX5F3qfFCqjy9dhn8PbNQsIKeVU04J9G7umt8=
google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
google.golang.org/grpc v1.48.0 h1:rQOsyJ/8+ufEDJd/Gdsz7HG220Mh9HAhFHRGnIjda0w=
google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=

View file

@ -348,7 +348,7 @@ func TestMain(m *testing.M) {
logger.ErrorToConsole("error initializing MFA: %v", err)
os.Exit(1)
}
err = plugin.Initialize(pluginsConfig, true)
err = plugin.Initialize(pluginsConfig, "debug")
if err != nil {
logger.ErrorToConsole("error initializing plugin: %v", err)
os.Exit(1)

View file

@ -104,7 +104,7 @@ type Manager struct {
}
// Initialize initializes the configured plugins
func Initialize(configs []Config, logVerbose bool) error {
func Initialize(configs []Config, logLevel string) error {
logger.Debug(logSender, "", "initialize")
Handler = Manager{
Configs: configs,
@ -112,7 +112,7 @@ func Initialize(configs []Config, logVerbose bool) error {
closed: 0,
authScopes: -1,
}
setLogLevel(logVerbose)
setLogLevel(logLevel)
if len(configs) == 0 {
return nil
}
@ -733,11 +733,16 @@ func (m *Manager) Cleanup() {
}
}
func setLogLevel(logVerbose bool) {
if logVerbose {
pluginsLogLevel = hclog.Debug
} else {
func setLogLevel(logLevel string) {
switch logLevel {
case "info":
pluginsLogLevel = hclog.Info
case "warn":
pluginsLogLevel = hclog.Warn
case "error":
pluginsLogLevel = hclog.Error
default:
pluginsLogLevel = hclog.Debug
}
}

View file

@ -38,7 +38,7 @@ type Service struct {
PortableMode int
PortableUser dataprovider.User
LogCompress bool
LogVerbose bool
LogLevel string
LogUTCTime bool
LoadDataClean bool
LoadDataFrom string
@ -49,9 +49,16 @@ type Service struct {
}
func (s *Service) initLogger() {
logLevel := zerolog.DebugLevel
if !s.LogVerbose {
var logLevel zerolog.Level
switch s.LogLevel {
case "info":
logLevel = zerolog.InfoLevel
case "warn":
logLevel = zerolog.WarnLevel
case "error":
logLevel = zerolog.ErrorLevel
default:
logLevel = zerolog.DebugLevel
}
if !filepath.IsAbs(s.LogFilePath) && util.IsFileInputValid(s.LogFilePath) {
s.LogFilePath = filepath.Join(s.ConfigDir, s.LogFilePath)
@ -69,8 +76,8 @@ func (s *Service) initLogger() {
func (s *Service) Start(disableAWSInstallationCode bool) error {
s.initLogger()
logger.Info(logSender, "", "starting SFTPGo %v, config dir: %v, config file: %v, log max size: %v log max backups: %v "+
"log max age: %v log verbose: %v, log compress: %v, log utc time: %v, load data from: %#v", version.GetAsString(), s.ConfigDir, s.ConfigFile,
s.LogMaxSize, s.LogMaxBackups, s.LogMaxAge, s.LogVerbose, s.LogCompress, s.LogUTCTime, s.LoadDataFrom)
"log max age: %v log level: %v, log compress: %v, log utc time: %v, load data from: %#v", version.GetAsString(), s.ConfigDir, s.ConfigFile,
s.LogMaxSize, s.LogMaxBackups, s.LogMaxAge, s.LogLevel, s.LogCompress, s.LogUTCTime, s.LoadDataFrom)
// in portable mode we don't read configuration from file
if s.PortableMode != 1 {
err := config.LoadConfig(s.ConfigDir, s.ConfigFile)
@ -118,7 +125,7 @@ func (s *Service) initializeServices(disableAWSInstallationCode bool) error {
logger.ErrorToConsole("unable to initialize MFA: %v", err)
return err
}
if err := plugin.Initialize(config.GetPluginsConfig(), s.LogVerbose); err != nil {
if err := plugin.Initialize(config.GetPluginsConfig(), s.LogLevel); err != nil {
logger.Error(logSender, "", "unable to initialize plugin system: %v", err)
logger.ErrorToConsole("unable to initialize plugin system: %v", err)
return err