log: fix enabling systemd logging when using --log-file

This also moves all the systemd logging decisions to fs/log
This commit is contained in:
Nick Craig-Wood 2020-12-17 11:55:27 +00:00
parent 5ae5e1dd56
commit c98dd8755c
6 changed files with 61 additions and 53 deletions

View File

@ -21,7 +21,6 @@ import (
"sync" "sync"
"time" "time"
systemd "github.com/iguanesolutions/go-systemd/v5"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs"
"github.com/rclone/rclone/fs/accounting" "github.com/rclone/rclone/fs/accounting"
@ -376,11 +375,6 @@ func StartStats() func() {
func initConfig() { func initConfig() {
ctx := context.Background() ctx := context.Background()
ci := fs.GetConfig(ctx) ci := fs.GetConfig(ctx)
// Activate logger systemd support if systemd invocation ID is detected
_, sysdLaunch := systemd.GetInvocationID()
if sysdLaunch {
ci.LogSystemdSupport = true // used during fslog.InitLogging()
}
// Start the logger // Start the logger
fslog.InitLogging() fslog.InitLogging()
@ -398,10 +392,8 @@ func initConfig() {
fs.Debugf("rclone", "Version %q starting with parameters %q", fs.Version, os.Args) fs.Debugf("rclone", "Version %q starting with parameters %q", fs.Version, os.Args)
// Inform user about systemd log support now that we have a logger // Inform user about systemd log support now that we have a logger
if sysdLaunch { if fslog.Opt.LogSystemdSupport {
fs.Debugf("rclone", "systemd logging support automatically activated") fs.Debugf("rclone", "systemd logging support activated")
} else if ci.LogSystemdSupport {
fs.Debugf("rclone", "systemd logging support manually activated")
} }
// Start the remote control server if configured // Start the remote control server if configured

View File

@ -43,7 +43,6 @@ var (
type ConfigInfo struct { type ConfigInfo struct {
LogLevel LogLevel LogLevel LogLevel
StatsLogLevel LogLevel StatsLogLevel LogLevel
LogSystemdSupport bool
UseJSONLog bool UseJSONLog bool
DryRun bool DryRun bool
Interactive bool Interactive bool

View File

@ -124,7 +124,6 @@ func AddFlags(ci *fs.ConfigInfo, flagSet *pflag.FlagSet) {
flags.StringArrayVarP(flagSet, &downloadHeaders, "header-download", "", nil, "Set HTTP header for download transactions") flags.StringArrayVarP(flagSet, &downloadHeaders, "header-download", "", nil, "Set HTTP header for download transactions")
flags.StringArrayVarP(flagSet, &headers, "header", "", nil, "Set HTTP header for all transactions") flags.StringArrayVarP(flagSet, &headers, "header", "", nil, "Set HTTP header for all transactions")
flags.BoolVarP(flagSet, &ci.RefreshTimes, "refresh-times", "", ci.RefreshTimes, "Refresh the modtime of remote files.") flags.BoolVarP(flagSet, &ci.RefreshTimes, "refresh-times", "", ci.RefreshTimes, "Refresh the modtime of remote files.")
flags.BoolVarP(flagSet, &ci.LogSystemdSupport, "log-systemd", "", ci.LogSystemdSupport, "Activate systemd integration for the logger.")
} }
// ParseHeaders converts the strings passed in via the header flags into HTTPOptions // ParseHeaders converts the strings passed in via the header flags into HTTPOptions

View File

@ -5,7 +5,6 @@ import (
"fmt" "fmt"
"log" "log"
sysdjournald "github.com/iguanesolutions/go-systemd/v5/journald"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
) )
@ -72,28 +71,7 @@ func (l *LogLevel) Type() string {
// LogPrint sends the text to the logger of level // LogPrint sends the text to the logger of level
var LogPrint = func(level LogLevel, text string) { var LogPrint = func(level LogLevel, text string) {
var prefix string text = fmt.Sprintf("%-6s: %s", level, text)
if GetConfig(context.TODO()).LogSystemdSupport {
switch level {
case LogLevelDebug:
prefix = sysdjournald.DebugPrefix
case LogLevelInfo:
prefix = sysdjournald.InfoPrefix
case LogLevelNotice:
prefix = sysdjournald.NoticePrefix
case LogLevelWarning:
prefix = sysdjournald.WarningPrefix
case LogLevelError:
prefix = sysdjournald.ErrPrefix
case LogLevelCritical:
prefix = sysdjournald.CritPrefix
case LogLevelAlert:
prefix = sysdjournald.AlertPrefix
case LogLevelEmergency:
prefix = sysdjournald.EmergPrefix
}
}
text = fmt.Sprintf("%s%-6s: %s", prefix, level, text)
_ = log.Output(4, text) _ = log.Output(4, text)
} }

View File

@ -3,6 +3,7 @@ package log
import ( import (
"context" "context"
"fmt"
"io" "io"
"log" "log"
"os" "os"
@ -10,16 +11,19 @@ import (
"runtime" "runtime"
"strings" "strings"
systemd "github.com/iguanesolutions/go-systemd/v5"
sysdjournald "github.com/iguanesolutions/go-systemd/v5/journald"
"github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
) )
// Options contains options for the remote control server // Options contains options for controlling the logging
type Options struct { type Options struct {
File string // Log everything to this file File string // Log everything to this file
Format string // Comma separated list of log format options Format string // Comma separated list of log format options
UseSyslog bool // Use Syslog for logging UseSyslog bool // Use Syslog for logging
SyslogFacility string // Facility for syslog, e.g. KERN,USER,... SyslogFacility string // Facility for syslog, e.g. KERN,USER,...
LogSystemdSupport bool // set if using systemd logging
} }
// DefaultOpt is the default values used for Opt // DefaultOpt is the default values used for Opt
@ -91,19 +95,17 @@ func Stack(o interface{}, info string) {
func InitLogging() { func InitLogging() {
flagsStr := "," + Opt.Format + "," flagsStr := "," + Opt.Format + ","
var flags int var flags int
if !fs.GetConfig(context.Background()).LogSystemdSupport { if strings.Contains(flagsStr, ",date,") {
if strings.Contains(flagsStr, ",date,") { flags |= log.Ldate
flags |= log.Ldate }
} if strings.Contains(flagsStr, ",time,") {
if strings.Contains(flagsStr, ",time,") { flags |= log.Ltime
flags |= log.Ltime }
} if strings.Contains(flagsStr, ",microseconds,") {
if strings.Contains(flagsStr, ",microseconds,") { flags |= log.Lmicroseconds
flags |= log.Lmicroseconds }
} if strings.Contains(flagsStr, ",UTC,") {
if strings.Contains(flagsStr, ",UTC,") { flags |= log.LUTC
flags |= log.LUTC
}
} }
if strings.Contains(flagsStr, ",longfile,") { if strings.Contains(flagsStr, ",longfile,") {
flags |= log.Llongfile flags |= log.Llongfile
@ -135,9 +137,46 @@ func InitLogging() {
} }
startSysLog() startSysLog()
} }
// Activate systemd logger support if systemd invocation ID is
// detected and output is going to stderr (not logging to a file or syslog)
if !Redirected() {
if _, usingSystemd := systemd.GetInvocationID(); usingSystemd {
Opt.LogSystemdSupport = true
}
}
// Systemd logging output
if Opt.LogSystemdSupport {
startSystemdLog()
}
} }
// Redirected returns true if the log has been redirected from stdout // Redirected returns true if the log has been redirected from stdout
func Redirected() bool { func Redirected() bool {
return Opt.UseSyslog || Opt.File != "" return Opt.UseSyslog || Opt.File != ""
} }
var logLevelToStringSystemd = []string{
fs.LogLevelEmergency: sysdjournald.EmergPrefix,
fs.LogLevelAlert: sysdjournald.AlertPrefix,
fs.LogLevelCritical: sysdjournald.CritPrefix,
fs.LogLevelError: sysdjournald.ErrPrefix,
fs.LogLevelWarning: sysdjournald.WarningPrefix,
fs.LogLevelNotice: sysdjournald.NoticePrefix,
fs.LogLevelInfo: sysdjournald.InfoPrefix,
fs.LogLevelDebug: sysdjournald.DebugPrefix,
}
// Starts systemd logging
func startSystemdLog() {
log.SetFlags(0)
fs.LogPrint = func(level fs.LogLevel, text string) {
var prefix string
if level < fs.LogLevel(len(logLevelToStringSystemd)) {
prefix = logLevelToStringSystemd[level]
}
text = fmt.Sprintf("%s%-6s: %s", prefix, level, text)
_ = log.Output(4, text)
}
}

View File

@ -16,4 +16,5 @@ func AddFlags(flagSet *pflag.FlagSet) {
flags.StringVarP(flagSet, &log.Opt.Format, "log-format", "", log.Opt.Format, "Comma separated list of log format options") flags.StringVarP(flagSet, &log.Opt.Format, "log-format", "", log.Opt.Format, "Comma separated list of log format options")
flags.BoolVarP(flagSet, &log.Opt.UseSyslog, "syslog", "", log.Opt.UseSyslog, "Use Syslog for logging") flags.BoolVarP(flagSet, &log.Opt.UseSyslog, "syslog", "", log.Opt.UseSyslog, "Use Syslog for logging")
flags.StringVarP(flagSet, &log.Opt.SyslogFacility, "syslog-facility", "", log.Opt.SyslogFacility, "Facility for syslog, e.g. KERN,USER,...") flags.StringVarP(flagSet, &log.Opt.SyslogFacility, "syslog-facility", "", log.Opt.SyslogFacility, "Facility for syslog, e.g. KERN,USER,...")
flags.BoolVarP(flagSet, &log.Opt.LogSystemdSupport, "log-systemd", "", log.Opt.LogSystemdSupport, "Activate systemd integration for the logger.")
} }