diff --git a/Duplicati/Library/Backend/FTP/FTPBackend.cs b/Duplicati/Library/Backend/FTP/FTPBackend.cs index 68bb91169..00a3cea94 100644 --- a/Duplicati/Library/Backend/FTP/FTPBackend.cs +++ b/Duplicati/Library/Backend/FTP/FTPBackend.cs @@ -107,6 +107,10 @@ namespace Duplicati.Library.Backend /// protected virtual string CONFIG_KEY_FTP_LOGPRIVATEINFOTOCONSOLE => "ftp-log-privateinfo-to-console"; /// + /// The configuration key for the FTP log to console + /// + protected virtual string CONFIG_KEY_FTP_LOGDIAGNOSTICS => "ftp-log-diagnostics"; + /// /// The configuration key for the FTP absolute paths option /// protected virtual string CONFIG_KEY_FTP_ABSOLUTE_PATH => "ftp-absolute-path"; @@ -198,6 +202,10 @@ namespace Duplicati.Library.Backend /// private readonly bool _logPrivateInfoToConsole; /// + /// The flag to indicate if diagnostics information should be logged + /// + private readonly bool _diagnosticsLog; + /// /// The flag to indicate if all certificates should be accepted /// private readonly bool _accepAllCertificates; @@ -240,6 +248,7 @@ namespace Duplicati.Library.Backend new CommandLineArgument(CONFIG_KEY_FTP_UPLOAD_DELAY, CommandLineArgument.ArgumentType.Timespan, Strings.DescriptionUploadDelayShort, Strings.DescriptionUploadDelayLong, DEFAULT_UPLOAD_DELAY_STRING), new CommandLineArgument(CONFIG_KEY_FTP_LOGTOCONSOLE, CommandLineArgument.ArgumentType.Boolean, Strings.DescriptionLogToConsoleShort, Strings.DescriptionLogToConsoleLong), new CommandLineArgument(CONFIG_KEY_FTP_LOGPRIVATEINFOTOCONSOLE, CommandLineArgument.ArgumentType.Boolean, Strings.DescriptionLogPrivateInfoToConsoleShort, Strings.DescriptionLogPrivateInfoToConsoleLong, "false"), + new CommandLineArgument(CONFIG_KEY_FTP_LOGDIAGNOSTICS, CommandLineArgument.ArgumentType.Boolean, Strings.DescriptionLogDiagnosticsShort, Strings.DescriptionLogDiagnosticsLong), new CommandLineArgument(CONFIG_KEY_FTP_LEGACY_FTPPASSIVE, CommandLineArgument.ArgumentType.Boolean, Strings.DescriptionFTPPassiveShort, Strings.DescriptionFTPPassiveLong, "false", null, null, Strings.FtpPassiveDeprecated), new CommandLineArgument(CONFIG_KEY_FTP_LEGACY_FTPREGULAR, CommandLineArgument.ArgumentType.Boolean, Strings.DescriptionFTPActiveShort, Strings.DescriptionFTPActiveLong, "true", null, null, Strings.FtpActiveDeprecated), new CommandLineArgument(CONFIG_KEY_FTP_LEGACY_USESSL, CommandLineArgument.ArgumentType.Boolean, Strings.DescriptionUseSSLShort, Strings.DescriptionUseSSLLong, "false", null, null, Strings.UseSslDeprecated), @@ -341,6 +350,7 @@ namespace Duplicati.Library.Backend _logToConsole = CoreUtility.ParseBoolOption(options, CONFIG_KEY_FTP_LOGTOCONSOLE); _logPrivateInfoToConsole = CoreUtility.ParseBoolOption(options, CONFIG_KEY_FTP_LOGPRIVATEINFOTOCONSOLE); + _diagnosticsLog = CoreUtility.ParseBoolOption(options, CONFIG_KEY_FTP_LOGDIAGNOSTICS); _ftpConfig = new FtpConfig { @@ -661,7 +671,8 @@ namespace Duplicati.Library.Backend Host = _url.Host, Port = _url.Port == -1 ? 21 : _url.Port, Credentials = _userInfo, - Config = _ftpConfig + Config = _ftpConfig, + Logger = _diagnosticsLog ? new DiagnosticsLogger() : null }; client.ValidateCertificate += HandleValidateCertificate; @@ -772,5 +783,22 @@ namespace Duplicati.Library.Backend return false; } + + private sealed class DiagnosticsLogger : IFtpLogger + { + private static readonly string LOGTAG = Logging.Log.LogTagFromType(); + public void Log(FtpLogEntry entry) + { + var type = entry.Severity switch + { + FtpTraceLevel.Verbose => Logging.LogMessageType.Verbose, + FtpTraceLevel.Info => Logging.LogMessageType.Information, + FtpTraceLevel.Warn => Logging.LogMessageType.Warning, + FtpTraceLevel.Error => Logging.LogMessageType.Error, + _ => Logging.LogMessageType.Information + }; + Logging.Log.WriteMessage(type, LOGTAG, "FtpLogMessage", entry.Exception, entry.Message); + } + } } } diff --git a/Duplicati/Library/Backend/FTP/Strings.cs b/Duplicati/Library/Backend/FTP/Strings.cs index cd72bda65..fa16fd2f4 100644 --- a/Duplicati/Library/Backend/FTP/Strings.cs +++ b/Duplicati/Library/Backend/FTP/Strings.cs @@ -39,6 +39,8 @@ namespace Duplicati.Library.Backend public static string DescriptionLogToConsoleShort { get { return LC.L(@"Log FTP dialog to terminal console"); } } public static string DescriptionLogPrivateInfoToConsoleLong { get { return LC.L(@"Use this option to log FTP PRIVATE info (username, password) to console for debugging purposes (DO NOT POST THIS TO THE INTERNET!)"); } } public static string DescriptionLogPrivateInfoToConsoleShort { get { return LC.L(@"Log FTP PRIVATE info to console"); } } + public static string DescriptionLogDiagnosticsShort { get { return LC.L(@"Log diagnostics information"); } } + public static string DescriptionLogDiagnosticsLong { get { return LC.L(@"Use this option to log diagnostics information to the log output. This can be useful for debugging purposes."); } } public static string MissingFolderError(string foldername, string message) { return LC.L(@"The folder {0} was not found. Message: {1}", foldername, message); } public static string ListVerifyFailure(string filename, IEnumerable files) { return LC.L(@"The file {0} was uploaded but not found afterwards. The file listing returned {1}", filename, string.Join(Environment.NewLine, files)); } public static string ListVerifySizeFailure(string filename, long actualsize, long expectedsize) { return LC.L(@"The file {0} was uploaded but the returned size was {1} and it was expected to be {2}", filename, actualsize, expectedsize); }