Files
AutoSeller/FluentFTP/Helpers/FtpTrace.cs
2018-01-02 01:12:03 +09:00

275 lines
8.1 KiB
C#

#define TRACE
using System;
using System.Diagnostics;
using System.IO;
namespace FluentFTP {
/// <summary>
/// Used for transaction logging and debug information.
/// </summary>
public static class FtpTrace {
#if !CORE
private static volatile TraceSource m_traceSource = new TraceSource("FluentFTP") {
Switch = new SourceSwitch("sourceSwitch", "Verbose") { Level = SourceLevels.All }
};
static bool m_flushOnWrite = true;
/// <summary>
/// Should the trace listeners be flushed immediately after writing to them?
/// </summary>
public static bool FlushOnWrite {
get { return m_flushOnWrite; }
set { m_flushOnWrite = value; }
}
static bool m_prefix = false;
/// <summary>
/// Should the log entries be written with a prefix of "FluentFTP"?
/// Useful if you have a single TraceListener shared across multiple libraries.
/// </summary>
public static bool LogPrefix {
get { return m_prefix; }
set { m_prefix = value; }
}
/// <summary>
/// Add a TraceListner to the collection. You can use one of the predefined
/// TraceListeners in the System.Diagnostics namespace, such as ConsoleTraceListener
/// for logging to the console, or you can write your own deriving from
/// System.Diagnostics.TraceListener.
/// </summary>
/// <param name="listener">The TraceListener to add to the collection</param>
public static void AddListener(TraceListener listener) {
lock (m_traceSource) {
m_traceSource.Listeners.Add(listener);
}
}
/// <summary>
/// Remove the specified TraceListener from the collection
/// </summary>
/// <param name="listener">The TraceListener to remove from the collection.</param>
public static void RemoveListener(TraceListener listener) {
lock (m_traceSource) {
m_traceSource.Listeners.Remove(listener);
}
}
#endif
#if CORE
static bool m_LogToConsole = false;
/// <summary>
/// Should FTP communication be be logged to console?
/// </summary>
public static bool LogToConsole {
get { return m_LogToConsole; }
set { m_LogToConsole = value; }
}
static string m_LogToFile = null;
/// <summary>
/// Set this to a file path to append all FTP communication to it.
/// </summary>
public static string LogToFile {
get { return m_LogToFile; }
set { m_LogToFile = value; }
}
#endif
static bool m_functions = true;
/// <summary>
/// Should the function calls be logged in Verbose mode?
/// </summary>
public static bool LogFunctions {
get { return m_functions; }
set { m_functions = value; }
}
static bool m_IP = true;
/// <summary>
/// Should the FTP server IP addresses be included in the logs?
/// </summary>
public static bool LogIP {
get { return m_IP; }
set { m_IP = value; }
}
static bool m_username = true;
/// <summary>
/// Should the FTP usernames be included in the logs?
/// </summary>
public static bool LogUserName {
get { return m_username; }
set { m_username = value; }
}
static bool m_password = false;
/// <summary>
/// Should the FTP passwords be included in the logs?
/// </summary>
public static bool LogPassword {
get { return m_password; }
set { m_password = value; }
}
static bool m_tracing = true;
/// <summary>
/// Should we trace at all?
/// </summary>
public static bool EnableTracing
{
get { return m_tracing; }
set { m_tracing = value; }
}
/// <summary>
/// Write to the TraceListeners
/// </summary>
/// <param name="message">The message to write</param>
//[Obsolete("Use overloads with FtpTraceLevel")]
public static void Write(string message) {
Write(FtpTraceLevel.Verbose, message);
}
/// <summary>
/// Write to the TraceListeners
/// </summary>
/// <param name="message">The message to write</param>
//[Obsolete("Use overloads with FtpTraceLevel")]
public static void WriteLine(object message) {
Write(FtpTraceLevel.Verbose, message.ToString());
}
/// <summary>
/// Write to the TraceListeners
/// </summary>
/// <param name="eventType">The type of tracing event</param>
/// <param name="message">The message to write</param>
public static void WriteLine(FtpTraceLevel eventType, object message) {
Write(eventType, message.ToString());
}
/// <summary>
/// Write to the TraceListeners, adding an automatic prefix to the message based on the `eventType`
/// </summary>
/// <param name="eventType">The type of tracing event</param>
/// <param name="message">The message to write</param>
public static void WriteStatus(FtpTraceLevel eventType, object message) {
Write(eventType, TraceLevelPrefix(eventType) + message.ToString());
}
/// <summary>
/// Write to the TraceListeners, for the purpose of logging a API function call
/// </summary>
/// <param name="function">The name of the API function</param>
/// <param name="args">The args passed to the function</param>
public static void WriteFunc(string function, object[] args = null) {
if (m_functions) {
Write(FtpTraceLevel.Verbose, "");
Write(FtpTraceLevel.Verbose, "# " + function + "(" + args.ItemsToString().Join(", ") + ")");
}
}
/// <summary>
/// Write to the TraceListeners
/// </summary>
/// <param name="eventType">The type of tracing event</param>
/// <param name="message">A formattable string to write</param>
public static void Write(FtpTraceLevel eventType, string message) {
if(!EnableTracing)
return;
#if CORE
#if DEBUG
Debug.WriteLine(message);
#else
if (m_LogToConsole) {
Console.WriteLine(message);
}
if (m_LogToFile != null) {
File.AppendAllText(m_LogToFile, message + "\n");
}
#endif
#elif !CORE
if (m_prefix) {
// if prefix is wanted then use TraceEvent()
m_traceSource.TraceEvent(TraceLevelTranslation(eventType), 0, message);
} else {
// if prefix is NOT wanted then write manually
EmitEvent(m_traceSource, TraceLevelTranslation(eventType), message);
}
if (m_flushOnWrite) {
m_traceSource.Flush();
}
#endif
}
private static string TraceLevelPrefix(FtpTraceLevel level) {
switch (level) {
case FtpTraceLevel.Verbose:
return "Status: ";
case FtpTraceLevel.Info:
return "Status: ";
case FtpTraceLevel.Warn:
return "Warning: ";
case FtpTraceLevel.Error:
return "Error: ";
}
return "Status: ";
}
#if !CORE
private static TraceEventType TraceLevelTranslation(FtpTraceLevel level) {
switch (level) {
case FtpTraceLevel.Verbose:
return TraceEventType.Verbose;
case FtpTraceLevel.Info:
return TraceEventType.Information;
case FtpTraceLevel.Warn:
return TraceEventType.Warning;
case FtpTraceLevel.Error:
return TraceEventType.Error;
default:
return TraceEventType.Verbose;
}
}
static object traceSync = new object();
private static void EmitEvent(TraceSource traceSource, TraceEventType eventType, string message) {
try {
lock (traceSync) {
if (traceSource.Switch.ShouldTrace(eventType)) {
foreach (TraceListener listener in traceSource.Listeners) {
try {
listener.WriteLine(message);
listener.Flush();
} catch { }
}
}
}
} catch {
}
}
#endif
}
}