diff --git a/cmd/cmd.go b/cmd/cmd.go index 8b06b096a..2535b5f94 100644 --- a/cmd/cmd.go +++ b/cmd/cmd.go @@ -21,6 +21,7 @@ import ( "sync" "time" + systemd "github.com/iguanesolutions/go-systemd/v5" "github.com/pkg/errors" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/accounting" @@ -364,6 +365,12 @@ func StartStats() func() { // initConfig is run by cobra after initialising the flags 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 fslog.InitLogging() @@ -379,6 +386,13 @@ func initConfig() { // Write the args for debug purposes 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 _, err = rcserver.Start(&rcflags.Opt) if err != nil { diff --git a/cmd/mountlib/mount.go b/cmd/mountlib/mount.go index 98de51f25..4a3e9e31c 100644 --- a/cmd/mountlib/mount.go +++ b/cmd/mountlib/mount.go @@ -11,7 +11,7 @@ import ( "syscall" "time" - "github.com/okzk/sdnotify" + sysdnotify "github.com/iguanesolutions/go-systemd/v5/notify" "github.com/pkg/errors" "github.com/rclone/rclone/cmd" "github.com/rclone/rclone/fs" @@ -448,13 +448,13 @@ func Mount(VFS *vfs.VFS, mountpoint string, mount MountFn, opt *Options) error { // Unmount on exit fnHandle := atexit.Register(func() { + _ = sysdnotify.Stopping() _ = unmount() - _ = sdnotify.Stopping() }) defer atexit.Unregister(fnHandle) // 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") } @@ -479,8 +479,8 @@ waitloop: } } + _ = sysdnotify.Stopping() _ = unmount() - _ = sdnotify.Stopping() if err != nil { return errors.Wrap(err, "failed to umount FUSE fs") diff --git a/fs/config.go b/fs/config.go index 3c04af7de..d1fe41102 100644 --- a/fs/config.go +++ b/fs/config.go @@ -42,6 +42,7 @@ var ( type ConfigInfo struct { LogLevel LogLevel StatsLogLevel LogLevel + LogSystemdSupport bool UseJSONLog bool DryRun bool Interactive bool diff --git a/fs/config/configflags/configflags.go b/fs/config/configflags/configflags.go index 275e64d05..08cd74b39 100644 --- a/fs/config/configflags/configflags.go +++ b/fs/config/configflags/configflags.go @@ -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, &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.LogSystemdSupport, "log-systemd", "", fs.Config.LogSystemdSupport, "Activate systemd integration for the logger.") } // ParseHeaders converts the strings passed in via the header flags into HTTPOptions diff --git a/fs/log.go b/fs/log.go index 3baf00400..4bba8a922 100644 --- a/fs/log.go +++ b/fs/log.go @@ -4,6 +4,7 @@ import ( "fmt" "log" + sysdjournald "github.com/iguanesolutions/go-systemd/v5/journald" "github.com/pkg/errors" "github.com/sirupsen/logrus" ) @@ -70,7 +71,28 @@ func (l *LogLevel) Type() string { // LogPrint sends the text to the logger of level 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) } diff --git a/fs/log/log.go b/fs/log/log.go index 48c0bd45a..f505b99c3 100644 --- a/fs/log/log.go +++ b/fs/log/log.go @@ -90,14 +90,19 @@ func Stack(o interface{}, info string) { func InitLogging() { flagsStr := "," + Opt.Format + "," var flags int - if strings.Contains(flagsStr, ",date,") { - flags |= log.Ldate - } - if strings.Contains(flagsStr, ",time,") { - flags |= log.Ltime - } - if strings.Contains(flagsStr, ",microseconds,") { - flags |= log.Lmicroseconds + if !fs.Config.LogSystemdSupport { + if strings.Contains(flagsStr, ",date,") { + flags |= log.Ldate + } + if strings.Contains(flagsStr, ",time,") { + flags |= log.Ltime + } + if strings.Contains(flagsStr, ",microseconds,") { + flags |= log.Lmicroseconds + } + if strings.Contains(flagsStr, ",UTC,") { + flags |= log.LUTC + } } if strings.Contains(flagsStr, ",longfile,") { flags |= log.Llongfile @@ -105,9 +110,6 @@ func InitLogging() { if strings.Contains(flagsStr, ",shortfile,") { flags |= log.Lshortfile } - if strings.Contains(flagsStr, ",UTC,") { - flags |= log.LUTC - } log.SetFlags(flags) // Log file output diff --git a/go.mod b/go.mod index a8a257675..21e95089d 100644 --- a/go.mod +++ b/go.mod @@ -22,6 +22,7 @@ require ( github.com/gogo/protobuf v1.3.1 // indirect github.com/google/go-querystring v1.0.0 // indirect 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/jzelinskie/whirlpool v0.0.0-20170603002051-c19460b8caa6 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/swift v1.0.52 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/pkg/errors v0.9.1 github.com/pkg/sftp v1.11.0 diff --git a/go.sum b/go.sum index 5319ab629..4b5ec2d63 100644 --- a/go.sum +++ b/go.sum @@ -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/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/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/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= 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/go.mod h1:IuKpRQcYE1Tfu+oAQqaLisqDeXgjyyltCfsaoYN18NQ= 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.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.0 h1:Iw5WCbBcaAAd0fpRb1c9r5YCylv4XDoCSigm1zLevwU=