diff --git a/FluentFTP.Logging/FluentFTP.Logging.csproj b/FluentFTP.Logging/FluentFTP.Logging.csproj new file mode 100644 index 000000000..673f785fe --- /dev/null +++ b/FluentFTP.Logging/FluentFTP.Logging.csproj @@ -0,0 +1,19 @@ + + + + netstandard2.0 + 10.0 + + + + + + + + + + + + + + diff --git a/FluentFTP.Logging/MicrosoftLoggingAdapter.cs b/FluentFTP.Logging/MicrosoftLoggingAdapter.cs new file mode 100644 index 000000000..f1f1ee8f2 --- /dev/null +++ b/FluentFTP.Logging/MicrosoftLoggingAdapter.cs @@ -0,0 +1,21 @@ +using Microsoft.Extensions.Logging; + +namespace FluentFTP.Logging { + public sealed class MicrosoftLoggingAdapter : IFluentLogger { + private readonly ILogger adaptee; + + public MicrosoftLoggingAdapter(ILogger adaptee) => + this.adaptee = adaptee; + + public void Log(LogEntry entry) => + adaptee.Log(ToLevel(entry.Severity), 0, entry.Message, entry.Exception, (s, _) => s); + + private static LogLevel ToLevel(FtpTraceLevel s) => s switch { + FtpTraceLevel.Verbose => LogLevel.Debug, + FtpTraceLevel.Info => LogLevel.Information, + FtpTraceLevel.Warn => LogLevel.Warning, + FtpTraceLevel.Error => LogLevel.Error, + _ => LogLevel.Information + }; + } +} \ No newline at end of file diff --git a/FluentFTP.sln b/FluentFTP.sln index dd7997630..3642df699 100644 --- a/FluentFTP.sln +++ b/FluentFTP.sln @@ -7,11 +7,13 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FluentFTP", "FluentFTP\Flue EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CSharpExamples", "FluentFTP.CSharpExamples\CSharpExamples.csproj", "{49B11591-C942-479F-A864-AB2738E50EF0}" EndProject -Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "VBExamples", "FluentFTP.VBExamples\VBExamples.vbproj", "{FC62AA30-F9F0-4DC1-A9EA-51A24C624973}" +Project("{778DAE3C-4631-46EA-AA77-85C1314464D9}") = "VBExamples", "FluentFTP.VBExamples\VBExamples.vbproj", "{FC62AA30-F9F0-4DC1-A9EA-51A24C624973}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FluentFTP.Tests", "FluentFTP.Tests\FluentFTP.Tests.csproj", "{0B17384E-6849-46D0-B880-2F97FE11A1B3}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FluentFTP.Xunit", "FluentFTP.Xunit\FluentFTP.Xunit.csproj", "{78BBB136-352C-4C06-A133-630C8AC57575}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FluentFTP.Xunit", "FluentFTP.Xunit\FluentFTP.Xunit.csproj", "{78BBB136-352C-4C06-A133-630C8AC57575}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FluentFTP.Logging", "FluentFTP.Logging\FluentFTP.Logging.csproj", "{611163CE-C9A0-45A6-9090-F7068AEF8D6B}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -61,6 +63,14 @@ Global {78BBB136-352C-4C06-A133-630C8AC57575}.Release|Any CPU.Build.0 = Release|Any CPU {78BBB136-352C-4C06-A133-630C8AC57575}.Release|x64.ActiveCfg = Release|Any CPU {78BBB136-352C-4C06-A133-630C8AC57575}.Release|x64.Build.0 = Release|Any CPU + {611163CE-C9A0-45A6-9090-F7068AEF8D6B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {611163CE-C9A0-45A6-9090-F7068AEF8D6B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {611163CE-C9A0-45A6-9090-F7068AEF8D6B}.Debug|x64.ActiveCfg = Debug|Any CPU + {611163CE-C9A0-45A6-9090-F7068AEF8D6B}.Debug|x64.Build.0 = Debug|Any CPU + {611163CE-C9A0-45A6-9090-F7068AEF8D6B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {611163CE-C9A0-45A6-9090-F7068AEF8D6B}.Release|Any CPU.Build.0 = Release|Any CPU + {611163CE-C9A0-45A6-9090-F7068AEF8D6B}.Release|x64.ActiveCfg = Release|Any CPU + {611163CE-C9A0-45A6-9090-F7068AEF8D6B}.Release|x64.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/FluentFTP/Client/AsyncFtpClient.cs b/FluentFTP/Client/AsyncFtpClient.cs index 41b934158..ddcd85a0f 100644 --- a/FluentFTP/Client/AsyncFtpClient.cs +++ b/FluentFTP/Client/AsyncFtpClient.cs @@ -2,7 +2,7 @@ using System.Net; using System.Threading; using FluentFTP.Client.BaseClient; -using Microsoft.Extensions.Logging; +using FluentFTP.Logging; namespace FluentFTP { @@ -32,7 +32,7 @@ public AsyncFtpClient() : base(null) { /// /// Creates a new instance of an async FTP Client, with the given host and credentials. /// - public AsyncFtpClient(string host, int port = 0, FtpConfig config = null, ILogger logger = null) : base(config) { + public AsyncFtpClient(string host, int port = 0, FtpConfig config = null, IFluentLogger logger = null) : base(config) { // set host Host = host ?? throw new ArgumentNullException(nameof(host)); @@ -49,7 +49,7 @@ public AsyncFtpClient(string host, int port = 0, FtpConfig config = null, ILogge /// /// Creates a new instance of an async FTP Client, with the given host and credentials. /// - public AsyncFtpClient(string host, string user, string pass, int port = 0, FtpConfig config = null, ILogger logger = null) : base(config) { + public AsyncFtpClient(string host, string user, string pass, int port = 0, FtpConfig config = null, IFluentLogger logger = null) : base(config) { // set host Host = host ?? throw new ArgumentNullException(nameof(host)); @@ -71,7 +71,7 @@ public AsyncFtpClient(string host, string user, string pass, int port = 0, FtpCo /// /// Creates a new instance of an async FTP Client, with the given host and credentials. /// - public AsyncFtpClient(string host, NetworkCredential credentials, int port = 0, FtpConfig config = null, ILogger logger = null) : base(config) { + public AsyncFtpClient(string host, NetworkCredential credentials, int port = 0, FtpConfig config = null, IFluentLogger logger = null) : base(config) { // set host Host = host ?? throw new ArgumentNullException(nameof(host)); diff --git a/FluentFTP/Client/BaseClient/Logger.cs b/FluentFTP/Client/BaseClient/Logger.cs index 065d5948f..4c12c1925 100644 --- a/FluentFTP/Client/BaseClient/Logger.cs +++ b/FluentFTP/Client/BaseClient/Logger.cs @@ -3,7 +3,7 @@ using System.Linq; using System.Reflection; using FluentFTP.Helpers; -using Microsoft.Extensions.Logging; +using FluentFTP.Logging; namespace FluentFTP.Client.BaseClient { public partial class BaseFtpClient { @@ -28,7 +28,7 @@ protected void LogFunction(string function, object[] args = null) { var fullMessage = ("> " + function + "(" + args.ItemsToString().Join(", ") + ")"); // log to modern logger if given - m_logger?.LogInformation(fullMessage); + m_logger?.Log(FtpTraceLevel.Info, fullMessage); // log to legacy logger if given m_legacyLogger?.Invoke(FtpTraceLevel.Verbose, fullMessage); @@ -48,7 +48,7 @@ protected void Log(FtpTraceLevel eventType, string message) { // log to modern logger if given if (m_logger != null) { - LogToLogger(eventType, message); + m_logger.Log(eventType, message); } // log to legacy logger if given @@ -69,7 +69,7 @@ protected void LogWithPrefix(FtpTraceLevel eventType, string message) { // log to attached logger if given if (m_logger != null) { - LogToLogger(eventType, fullMessage); + m_logger.Log(eventType, message); } // log to legacy logger if given @@ -79,29 +79,6 @@ protected void LogWithPrefix(FtpTraceLevel eventType, string message) { LogToDebugOrConsole(fullMessage); } - /// - /// Log a message to the attached logger. - /// - private void LogToLogger(FtpTraceLevel eventType, string message) { - switch (eventType) { - case FtpTraceLevel.Verbose: - m_logger.LogDebug(message); - break; - - case FtpTraceLevel.Info: - m_logger.LogInformation(message); - break; - - case FtpTraceLevel.Warn: - m_logger.LogWarning(message); - break; - - case FtpTraceLevel.Error: - m_logger.LogError(message); - break; - } - } - /// /// Log a message to the debug output and console. /// diff --git a/FluentFTP/Client/BaseClient/Properties.cs b/FluentFTP/Client/BaseClient/Properties.cs index 8b01e0890..80c46fa8b 100644 --- a/FluentFTP/Client/BaseClient/Properties.cs +++ b/FluentFTP/Client/BaseClient/Properties.cs @@ -9,8 +9,8 @@ using FluentFTP.Servers; using FluentFTP.Helpers; using System.Net.Sockets; -using Microsoft.Extensions.Logging; using System.Threading; +using FluentFTP.Logging; namespace FluentFTP.Client.BaseClient { @@ -18,12 +18,12 @@ namespace FluentFTP.Client.BaseClient { public partial class BaseFtpClient { - private ILogger m_logger = null; + private IFluentLogger m_logger = null; /// /// Should the function calls be logged in Verbose mode? /// - public ILogger Logger { + public IFluentLogger Logger { get => m_logger; set => m_logger = value; } diff --git a/FluentFTP/Client/FtpClient.cs b/FluentFTP/Client/FtpClient.cs index b7c460f95..4ff8e677e 100644 --- a/FluentFTP/Client/FtpClient.cs +++ b/FluentFTP/Client/FtpClient.cs @@ -1,7 +1,7 @@ using System; using System.Net; using FluentFTP.Client.BaseClient; -using Microsoft.Extensions.Logging; +using FluentFTP.Logging; namespace FluentFTP { @@ -31,7 +31,7 @@ public FtpClient() : base(null) { /// /// Creates a new instance of a synchronous FTP Client, with the given host and credentials. /// - public FtpClient(string host, int port = 0, FtpConfig config = null, ILogger logger = null) : base(config) { + public FtpClient(string host, int port = 0, FtpConfig config = null, IFluentLogger logger = null) : base(config) { // set host Host = host ?? throw new ArgumentNullException(nameof(host)); @@ -48,7 +48,7 @@ public FtpClient(string host, int port = 0, FtpConfig config = null, ILogger log /// /// Creates a new instance of a synchronous FTP Client, with the given host and credentials. /// - public FtpClient(string host, string user, string pass, int port = 0, FtpConfig config = null, ILogger logger = null) : base(config) { + public FtpClient(string host, string user, string pass, int port = 0, FtpConfig config = null, IFluentLogger logger = null) : base(config) { // set host Host = host ?? throw new ArgumentNullException(nameof(host)); @@ -70,7 +70,7 @@ public FtpClient(string host, string user, string pass, int port = 0, FtpConfig /// /// Creates a new instance of a synchronous FTP Client, with the given host and credentials. /// - public FtpClient(string host, NetworkCredential credentials, int port = 0, FtpConfig config = null, ILogger logger = null) : base(config) { + public FtpClient(string host, NetworkCredential credentials, int port = 0, FtpConfig config = null, IFluentLogger logger = null) : base(config) { // set host Host = host ?? throw new ArgumentNullException(nameof(host)); diff --git a/FluentFTP/Client/Interfaces/IAsyncFtpClient.cs b/FluentFTP/Client/Interfaces/IAsyncFtpClient.cs index fa3b8c84f..bf5fad472 100644 --- a/FluentFTP/Client/Interfaces/IAsyncFtpClient.cs +++ b/FluentFTP/Client/Interfaces/IAsyncFtpClient.cs @@ -1,6 +1,5 @@ using FluentFTP.Rules; using FluentFTP.Servers; -using Microsoft.Extensions.Logging; using System; using System.Collections.Generic; using System.Globalization; @@ -31,7 +30,7 @@ public interface IAsyncFtpClient : IDisposable, IBaseFtpClient { Task> AutoDetect(bool firstOnly = true, bool cloneConnection = true, CancellationToken token = default(CancellationToken)); Task Connect(CancellationToken token = default(CancellationToken)); Task Connect(FtpProfile profile, CancellationToken token = default(CancellationToken)); - Task Connect(bool reConnect, CancellationToken token = default(CancellationToken)); + Task Connect(bool reConnect, CancellationToken token = default(CancellationToken)); Task Disconnect(CancellationToken token = default(CancellationToken)); Task Execute(string command, CancellationToken token = default(CancellationToken)); Task GetReply(CancellationToken token = default(CancellationToken)); diff --git a/FluentFTP/Client/Interfaces/IBaseFtpClient.cs b/FluentFTP/Client/Interfaces/IBaseFtpClient.cs index 69b48358e..082ea2592 100644 --- a/FluentFTP/Client/Interfaces/IBaseFtpClient.cs +++ b/FluentFTP/Client/Interfaces/IBaseFtpClient.cs @@ -1,6 +1,6 @@ -using FluentFTP.Rules; +using FluentFTP.Logging; +using FluentFTP.Rules; using FluentFTP.Servers; -using Microsoft.Extensions.Logging; using System; using System.Collections.Generic; using System.Globalization; @@ -22,7 +22,7 @@ public interface IBaseFtpClient { #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member FtpConfig Config { get; set; } - ILogger Logger { get; set; } + IFluentLogger Logger { get; set; } bool IsDisposed { get; } bool IsConnected { get; } string Host { get; set; } diff --git a/FluentFTP/Client/Interfaces/IFtpClient.cs b/FluentFTP/Client/Interfaces/IFtpClient.cs index f795d6ce7..f7923985c 100644 --- a/FluentFTP/Client/Interfaces/IFtpClient.cs +++ b/FluentFTP/Client/Interfaces/IFtpClient.cs @@ -1,6 +1,5 @@ using FluentFTP.Rules; using FluentFTP.Servers; -using Microsoft.Extensions.Logging; using System; using System.Collections.Generic; using System.Globalization; @@ -31,7 +30,7 @@ public interface IFtpClient : IDisposable, IBaseFtpClient { FtpProfile AutoConnect(); void Connect(); void Connect(FtpProfile profile); - void Connect(bool reConnect); + void Connect(bool reConnect); void Disconnect(); FtpReply Execute(string command); FtpReply GetReply(); diff --git a/FluentFTP/FluentFTP.csproj b/FluentFTP/FluentFTP.csproj index 9db971857..dbb54ef8b 100644 --- a/FluentFTP/FluentFTP.csproj +++ b/FluentFTP/FluentFTP.csproj @@ -57,10 +57,6 @@ - - - - diff --git a/FluentFTP/Logging/IFluentLogger.cs b/FluentFTP/Logging/IFluentLogger.cs new file mode 100644 index 000000000..8267d5f76 --- /dev/null +++ b/FluentFTP/Logging/IFluentLogger.cs @@ -0,0 +1,5 @@ +namespace FluentFTP.Logging { + public interface IFluentLogger { + void Log(LogEntry entry); + } +} diff --git a/FluentFTP/Logging/LogEntry.cs b/FluentFTP/Logging/LogEntry.cs new file mode 100644 index 000000000..ee4bf58d6 --- /dev/null +++ b/FluentFTP/Logging/LogEntry.cs @@ -0,0 +1,15 @@ +using System; + +namespace FluentFTP.Logging { + public readonly struct LogEntry { + public FtpTraceLevel Severity { get; } + public string Message { get; } + public Exception Exception { get; } + + public LogEntry(FtpTraceLevel severity, string msg, Exception ex = null) { + Severity = severity; + Message = msg; + Exception = ex; + } + } +} diff --git a/FluentFTP/Logging/LoggerExtensions.cs b/FluentFTP/Logging/LoggerExtensions.cs new file mode 100644 index 000000000..09d57196f --- /dev/null +++ b/FluentFTP/Logging/LoggerExtensions.cs @@ -0,0 +1,8 @@ +using System; + +namespace FluentFTP.Logging { + public static class LoggerExtensions { + public static void Log(this IFluentLogger logger, FtpTraceLevel eventType, string message, Exception ex = null) => + logger.Log(new LogEntry(eventType, message, ex)); + } +}