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); }