using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.Remoting.Messaging; using System.ServiceModel.Dispatcher; using DotNetOpenAuth.Logging; using DotNetOpenAuth.Logging.LogProviders; using DotNetOpenAuth.OpenId.Extensions.AttributeExchange; namespace DotNetOpenAuth.OpenIdOfflineProvider { /// /// Sends logging events to a . /// /// /// /// An Appender that writes to a . /// /// /// This appender may be used stand alone if initialized with an appropriate /// writer, however it is typically used as a base class for an appender that /// can open a to write to. /// /// /// Nicko Cadell /// Gert Driesen /// Douglas de la Torre public class TextWriterLogProvider : ILogProvider { public class TextWriterLogger : ILog { private const string LogSystem = "LibLog"; private readonly string _category; private readonly WriteDelegate _logWriteDelegate; private readonly int _skipLevel; internal TextWriterLogger(string category, WriteDelegate logWriteDelegate) { _category = category; _logWriteDelegate = logWriteDelegate; _skipLevel = 1; } public bool Log(LogLevel logLevel, Func messageFunc, Exception exception) { if (messageFunc == null) { //nothing to log.. return true; } _logWriteDelegate((int)ToLogMessageSeverity(logLevel), LogSystem, _skipLevel, exception, true, 0, null, _category, null, messageFunc.Invoke()); return true; } public TraceEventType ToLogMessageSeverity(LogLevel logLevel) { switch (logLevel) { case LogLevel.Trace: return TraceEventType.Verbose; case LogLevel.Debug: return TraceEventType.Verbose; case LogLevel.Info: return TraceEventType.Information; case LogLevel.Warn: return TraceEventType.Warning; case LogLevel.Error: return TraceEventType.Error; case LogLevel.Fatal: return TraceEventType.Critical; default: throw new ArgumentOutOfRangeException("logLevel"); } } /// /// The form of the Loupe Log.Write method we're using /// internal delegate void WriteDelegate( int severity, string logSystem, int skipFrames, Exception exception, bool attributeToException, int writeMode, string detailsXml, string category, string caption, string description, params object[] args ); } private static bool _providerIsAvailableOverride = true; private readonly TextWriterLogger.WriteDelegate _logWriteDelegate; public TextWriterLogProvider() { if (!IsLoggerAvailable()) { throw new InvalidOperationException("Gibraltar.Agent.Log (Loupe) not found"); } _logWriteDelegate = GetLogWriteDelegate(); } /// /// Gets or sets a value indicating whether [provider is available override]. Used in tests. /// /// /// true if [provider is available override]; otherwise, false. /// public static bool ProviderIsAvailableOverride { get { return _providerIsAvailableOverride; } set { _providerIsAvailableOverride = value; } } public ILog GetLogger(string name) { return new TextWriterLogProvider.TextWriterLogger(name, _logWriteDelegate); } public static bool IsLoggerAvailable() { return ProviderIsAvailableOverride && GetLogManagerType() != null; } private static Type GetLogManagerType() { return Type.GetType("Gibraltar.Agent.Log, Gibraltar.Agent"); } private static TextWriterLogger.WriteDelegate GetLogWriteDelegate() { Type logManagerType = GetLogManagerType(); Type logMessageSeverityType = Type.GetType("Gibraltar.Agent.LogMessageSeverity, Gibraltar.Agent"); Type logWriteModeType = Type.GetType("Gibraltar.Agent.LogWriteMode, Gibraltar.Agent"); MethodInfo method = logManagerType.GetMethod("Write", new[] { logMessageSeverityType, typeof(string), typeof(int), typeof(Exception), typeof(bool), logWriteModeType, typeof(string), typeof(string), typeof(string), typeof(string), typeof(object[]) }); var callDelegate = (TextWriterLogger.WriteDelegate)Delegate.CreateDelegate(typeof(TextWriterLogger.WriteDelegate), method); return callDelegate; } } }