enhance systemd integration

* log level identification
* manual activation with flag
* automatic systemd launch detection
This commit is contained in:
Hekmon 2020-09-18 17:37:54 +02:00 committed by Nick Craig-Wood
parent 3edc9ff0b0
commit c58023a9ba
8 changed files with 59 additions and 19 deletions

View file

@ -21,6 +21,7 @@ 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"
@ -364,6 +365,12 @@ func StartStats() func() {
// initConfig is run by cobra after initialising the flags // initConfig is run by cobra after initialising the flags
func initConfig() { func initConfig() {
// Activate logger systemd support if systemd invocation ID is detected
_, sysdLaunch := systemd.GetInvocationID()
if sysdLaunch {
fs.Config.LogSystemdSupport = true // used during fslog.InitLogging()
}
// Start the logger // Start the logger
fslog.InitLogging() fslog.InitLogging()
@ -379,6 +386,13 @@ func initConfig() {
// Write the args for debug purposes // Write the args for debug purposes
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
if sysdLaunch {
fs.Debugf("rclone", "systemd logging support automatically activated")
} else if fs.Config.LogSystemdSupport {
fs.Debugf("rclone", "systemd logging support manually activated")
}
// Start the remote control server if configured // Start the remote control server if configured
_, err = rcserver.Start(&rcflags.Opt) _, err = rcserver.Start(&rcflags.Opt)
if err != nil { if err != nil {

View file

@ -11,7 +11,7 @@ import (
"syscall" "syscall"
"time" "time"
"github.com/okzk/sdnotify" sysdnotify "github.com/iguanesolutions/go-systemd/v5/notify"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/rclone/rclone/cmd" "github.com/rclone/rclone/cmd"
"github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs"
@ -448,13 +448,13 @@ func Mount(VFS *vfs.VFS, mountpoint string, mount MountFn, opt *Options) error {
// Unmount on exit // Unmount on exit
fnHandle := atexit.Register(func() { fnHandle := atexit.Register(func() {
_ = sysdnotify.Stopping()
_ = unmount() _ = unmount()
_ = sdnotify.Stopping()
}) })
defer atexit.Unregister(fnHandle) defer atexit.Unregister(fnHandle)
// Notify systemd // Notify systemd
if err := sdnotify.Ready(); err != nil && err != sdnotify.ErrSdNotifyNoSocket { if err := sysdnotify.Ready(); err != nil {
return errors.Wrap(err, "failed to notify systemd") return errors.Wrap(err, "failed to notify systemd")
} }
@ -479,8 +479,8 @@ waitloop:
} }
} }
_ = sysdnotify.Stopping()
_ = unmount() _ = unmount()
_ = sdnotify.Stopping()
if err != nil { if err != nil {
return errors.Wrap(err, "failed to umount FUSE fs") return errors.Wrap(err, "failed to umount FUSE fs")

View file

@ -42,6 +42,7 @@ 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

@ -123,6 +123,7 @@ func AddFlags(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, &fs.Config.RefreshTimes, "refresh-times", "", fs.Config.RefreshTimes, "Refresh the modtime of remote files.") flags.BoolVarP(flagSet, &fs.Config.RefreshTimes, "refresh-times", "", fs.Config.RefreshTimes, "Refresh the modtime of remote files.")
flags.BoolVarP(flagSet, &fs.Config.LogSystemdSupport, "log-systemd", "", fs.Config.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

@ -4,6 +4,7 @@ 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"
) )
@ -70,7 +71,28 @@ 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) {
text = fmt.Sprintf("%-6s: %s", level, text) var prefix string
if Config.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

@ -90,14 +90,19 @@ func Stack(o interface{}, info string) {
func InitLogging() { func InitLogging() {
flagsStr := "," + Opt.Format + "," flagsStr := "," + Opt.Format + ","
var flags int var flags int
if strings.Contains(flagsStr, ",date,") { if !fs.Config.LogSystemdSupport {
flags |= log.Ldate if strings.Contains(flagsStr, ",date,") {
} flags |= log.Ldate
if strings.Contains(flagsStr, ",time,") { }
flags |= log.Ltime if strings.Contains(flagsStr, ",time,") {
} flags |= log.Ltime
if strings.Contains(flagsStr, ",microseconds,") { }
flags |= log.Lmicroseconds if strings.Contains(flagsStr, ",microseconds,") {
flags |= log.Lmicroseconds
}
if strings.Contains(flagsStr, ",UTC,") {
flags |= log.LUTC
}
} }
if strings.Contains(flagsStr, ",longfile,") { if strings.Contains(flagsStr, ",longfile,") {
flags |= log.Llongfile flags |= log.Llongfile
@ -105,9 +110,6 @@ func InitLogging() {
if strings.Contains(flagsStr, ",shortfile,") { if strings.Contains(flagsStr, ",shortfile,") {
flags |= log.Lshortfile flags |= log.Lshortfile
} }
if strings.Contains(flagsStr, ",UTC,") {
flags |= log.LUTC
}
log.SetFlags(flags) log.SetFlags(flags)
// Log file output // Log file output

2
go.mod
View file

@ -22,6 +22,7 @@ require (
github.com/gogo/protobuf v1.3.1 // indirect github.com/gogo/protobuf v1.3.1 // indirect
github.com/google/go-querystring v1.0.0 // indirect github.com/google/go-querystring v1.0.0 // indirect
github.com/hanwen/go-fuse/v2 v2.0.3 github.com/hanwen/go-fuse/v2 v2.0.3
github.com/iguanesolutions/go-systemd/v5 v5.0.0
github.com/jlaffaye/ftp v0.0.0-20200720194710-13949d38913e github.com/jlaffaye/ftp v0.0.0-20200720194710-13949d38913e
github.com/jzelinskie/whirlpool v0.0.0-20170603002051-c19460b8caa6 github.com/jzelinskie/whirlpool v0.0.0-20170603002051-c19460b8caa6
github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 // indirect github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 // indirect
@ -35,7 +36,6 @@ require (
github.com/ncw/go-acd v0.0.0-20171120105400-887eb06ab6a2 github.com/ncw/go-acd v0.0.0-20171120105400-887eb06ab6a2
github.com/ncw/swift v1.0.52 github.com/ncw/swift v1.0.52
github.com/nsf/termbox-go v0.0.0-20200418040025-38ba6e5628f1 github.com/nsf/termbox-go v0.0.0-20200418040025-38ba6e5628f1
github.com/okzk/sdnotify v0.0.0-20180710141335-d9becc38acbd
github.com/patrickmn/go-cache v2.1.0+incompatible github.com/patrickmn/go-cache v2.1.0+incompatible
github.com/pkg/errors v0.9.1 github.com/pkg/errors v0.9.1
github.com/pkg/sftp v1.11.0 github.com/pkg/sftp v1.11.0

4
go.sum
View file

@ -232,6 +232,8 @@ github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/huandu/xstrings v1.0.0/go.mod h1:4qWG/gcEcfX4z/mBDHJ++3ReCw9ibxbsNJbcucJdbSo= github.com/huandu/xstrings v1.0.0/go.mod h1:4qWG/gcEcfX4z/mBDHJ++3ReCw9ibxbsNJbcucJdbSo=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/iguanesolutions/go-systemd/v5 v5.0.0 h1:E4OUiBdmlD1IsClS6cmRIdzWBW8T8UBitCqYem7A1KY=
github.com/iguanesolutions/go-systemd/v5 v5.0.0/go.mod h1:VPlzL6z0rXd3HU7oLkMoEqTWBhHClInYX9rP2U/+giI=
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
@ -314,8 +316,6 @@ github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S
github.com/nsf/termbox-go v0.0.0-20200418040025-38ba6e5628f1 h1:lh3PyZvY+B9nFliSGTn5uFuqQQJGuNrD0MLCokv09ag= github.com/nsf/termbox-go v0.0.0-20200418040025-38ba6e5628f1 h1:lh3PyZvY+B9nFliSGTn5uFuqQQJGuNrD0MLCokv09ag=
github.com/nsf/termbox-go v0.0.0-20200418040025-38ba6e5628f1/go.mod h1:IuKpRQcYE1Tfu+oAQqaLisqDeXgjyyltCfsaoYN18NQ= github.com/nsf/termbox-go v0.0.0-20200418040025-38ba6e5628f1/go.mod h1:IuKpRQcYE1Tfu+oAQqaLisqDeXgjyyltCfsaoYN18NQ=
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
github.com/okzk/sdnotify v0.0.0-20180710141335-d9becc38acbd h1:+iAPaTbi1gZpcpDwe/BW1fx7Xoesv69hLNGPheoyhBs=
github.com/okzk/sdnotify v0.0.0-20180710141335-d9becc38acbd/go.mod h1:4soZNh0zW0LtYGdQ416i0jO0EIqMGcbtaspRS4BDvRQ=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.12.0 h1:Iw5WCbBcaAAd0fpRb1c9r5YCylv4XDoCSigm1zLevwU= github.com/onsi/ginkgo v1.12.0 h1:Iw5WCbBcaAAd0fpRb1c9r5YCylv4XDoCSigm1zLevwU=