//===============================================================================
// LibLog
//
// https://github.com/damianh/LibLog
//===============================================================================
// Copyright © 2011-2014 Damian Hickey. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//===============================================================================
#pragma warning disable 1591
namespace DotNetOpenAuth.Logging
{
using System.Collections.Generic;
using DotNetOpenAuth.Logging.LogProviders;
using System;
using System.Diagnostics;
using System.Globalization;
///
/// Simple interface that represent a logger.
///
public interface ILog
{
///
/// Log a message the specified log level.
///
/// The log level.
/// The message function.
/// An optional exception.
/// true if the message was logged. Otherwise false.
///
/// Note to implementers: the message func should not be called if the loglevel is not enabled
/// so as not to incur performance penalties.
///
/// To check IsEnabled call Log with only LogLevel and check the return value, no event will be written
///
bool Log(LogLevel logLevel, Func messageFunc, Exception exception = null);
}
///
/// The log level.
///
public enum LogLevel
{
Trace,
Debug,
Info,
Warn,
Error,
Fatal
}
public static class LogExtensions
{
public static bool IsDebugEnabled(this ILog logger)
{
GuardAgainstNullLogger(logger);
return logger.Log(LogLevel.Debug, null);
}
public static bool IsErrorEnabled(this ILog logger)
{
GuardAgainstNullLogger(logger);
return logger.Log(LogLevel.Error, null);
}
public static bool IsFatalEnabled(this ILog logger)
{
GuardAgainstNullLogger(logger);
return logger.Log(LogLevel.Fatal, null);
}
public static bool IsInfoEnabled(this ILog logger)
{
GuardAgainstNullLogger(logger);
return logger.Log(LogLevel.Info, null);
}
public static bool IsTraceEnabled(this ILog logger)
{
GuardAgainstNullLogger(logger);
return logger.Log(LogLevel.Trace, null);
}
public static bool IsWarnEnabled(this ILog logger)
{
GuardAgainstNullLogger(logger);
return logger.Log(LogLevel.Warn, null);
}
public static void Debug(this ILog logger, Func messageFunc)
{
GuardAgainstNullLogger(logger);
logger.Log(LogLevel.Debug, messageFunc);
}
public static void Debug(this ILog logger, string message)
{
if (logger.IsDebugEnabled())
{
logger.Log(LogLevel.Debug, message.AsFunc());
}
}
public static void DebugFormat(this ILog logger, string message, params object[] args)
{
if (logger.IsDebugEnabled())
{
logger.LogFormat(LogLevel.Debug, message, args);
}
}
public static void DebugException(this ILog logger, string message, Exception exception)
{
if (logger.IsDebugEnabled())
{
logger.Log(LogLevel.Debug, message.AsFunc(), exception);
}
}
public static void Error(this ILog logger, Func messageFunc)
{
logger.Log(LogLevel.Error, messageFunc);
}
public static void Error(this ILog logger, string message)
{
if (logger.IsErrorEnabled())
{
logger.Log(LogLevel.Error, message.AsFunc());
}
}
public static void ErrorFormat(this ILog logger, string message, params object[] args)
{
if (logger.IsErrorEnabled())
{
logger.LogFormat(LogLevel.Error, message, args);
}
}
public static void ErrorException(this ILog logger, string message, Exception exception)
{
if (logger.IsErrorEnabled())
{
logger.Log(LogLevel.Error, message.AsFunc(), exception);
}
}
public static void Fatal(this ILog logger, Func messageFunc)
{
logger.Log(LogLevel.Fatal, messageFunc);
}
public static void Fatal(this ILog logger, string message)
{
if (logger.IsFatalEnabled())
{
logger.Log(LogLevel.Fatal, message.AsFunc());
}
}
public static void FatalFormat(this ILog logger, string message, params object[] args)
{
if (logger.IsFatalEnabled())
{
logger.LogFormat(LogLevel.Fatal, message, args);
}
}
public static void FatalException(this ILog logger, string message, Exception exception)
{
if (logger.IsFatalEnabled())
{
logger.Log(LogLevel.Fatal, message.AsFunc(), exception);
}
}
public static void Info(this ILog logger, Func messageFunc)
{
GuardAgainstNullLogger(logger);
logger.Log(LogLevel.Info, messageFunc);
}
public static void Info(this ILog logger, string message)
{
if (logger.IsInfoEnabled())
{
logger.Log(LogLevel.Info, message.AsFunc());
}
}
public static void InfoFormat(this ILog logger, string message, params object[] args)
{
if (logger.IsInfoEnabled())
{
logger.LogFormat(LogLevel.Info, message, args);
}
}
public static void InfoException(this ILog logger, string message, Exception exception)
{
if (logger.IsInfoEnabled())
{
logger.Log(LogLevel.Info, message.AsFunc(), exception);
}
}
public static void Trace(this ILog logger, Func messageFunc)
{
GuardAgainstNullLogger(logger);
logger.Log(LogLevel.Trace, messageFunc);
}
public static void Trace(this ILog logger, string message)
{
if (logger.IsTraceEnabled())
{
logger.Log(LogLevel.Trace, message.AsFunc());
}
}
public static void TraceFormat(this ILog logger, string message, params object[] args)
{
if (logger.IsTraceEnabled())
{
logger.LogFormat(LogLevel.Trace, message, args);
}
}
public static void TraceException(this ILog logger, string message, Exception exception)
{
if (logger.IsTraceEnabled())
{
logger.Log(LogLevel.Trace, message.AsFunc(), exception);
}
}
public static void Warn(this ILog logger, Func messageFunc)
{
GuardAgainstNullLogger(logger);
logger.Log(LogLevel.Warn, messageFunc);
}
public static void Warn(this ILog logger, string message)
{
if (logger.IsWarnEnabled())
{
logger.Log(LogLevel.Warn, message.AsFunc());
}
}
public static void WarnFormat(this ILog logger, string message, params object[] args)
{
if (logger.IsWarnEnabled())
{
logger.LogFormat(LogLevel.Warn, message, args);
}
}
public static void WarnException(this ILog logger, string message, Exception exception)
{
if (logger.IsWarnEnabled())
{
logger.Log(LogLevel.Warn, message.AsFunc(), exception);
}
}
private static void GuardAgainstNullLogger(ILog logger)
{
if (logger == null)
{
throw new ArgumentNullException("logger");
}
}
private static void LogFormat(this ILog logger, LogLevel logLevel, string message, params object[] args)
{
var result = string.Format(CultureInfo.InvariantCulture, message, args);
logger.Log(logLevel, result.AsFunc());
}
// Avoid the closure allocation, see https://gist.github.com/AArnott/d285feef75c18f6ecd2b
private static Func AsFunc(this T value) where T : class
{
return value.Return;
}
private static T Return(this T value)
{
return value;
}
}
///
/// Represents a way to get a
///
public interface ILogProvider
{
ILog GetLogger(string name);
}
///
/// Provides a mechanism to create instances of objects.
///
public static class LogProvider
{
private static ILogProvider _currentLogProvider;
///
/// Gets a logger for the specified type.
///
/// The type whose name will be used for the logger.
/// An instance of
public static ILog For()
{
return GetLogger(typeof(T));
}
///
/// Gets a logger for the current class.
///
/// An instance of
public static ILog GetCurrentClassLogger()
{
var stackFrame = new StackFrame(1, false);
return GetLogger(stackFrame.GetMethod().DeclaringType);
}
///
/// Gets a logger for the specified type.
///
/// The type whose name will be used for the logger.
/// An instance of
public static ILog GetLogger(Type type)
{
return GetLogger(type.FullName);
}
///
/// Gets a logger with the specified name.
///
/// The name.
/// An instance of
public static ILog GetLogger(string name)
{
ILogProvider logProvider = _currentLogProvider ?? ResolveLogProvider();
return logProvider == null ? new NoOpLogger() : (ILog)new LoggerExecutionWrapper(logProvider.GetLogger(name));
}
///
/// Sets the current log provider.
///
/// The log provider.
public static void SetCurrentLogProvider(ILogProvider logProvider)
{
_currentLogProvider = logProvider;
}
public delegate bool IsLoggerAvailable();
public delegate ILogProvider CreateLogProvider();
public static readonly List> LogProviderResolvers =
new List>
{
new Tuple(SerilogLogProvider.IsLoggerAvailable, () => new SerilogLogProvider()),
new Tuple(NLogLogProvider.IsLoggerAvailable, () => new NLogLogProvider()),
new Tuple(Log4NetLogProvider.IsLoggerAvailable, () => new Log4NetLogProvider()),
new Tuple(EntLibLogProvider.IsLoggerAvailable, () => new EntLibLogProvider()),
new Tuple(LoupeLogProvider.IsLoggerAvailable, () => new LoupeLogProvider())
};
private static ILogProvider ResolveLogProvider()
{
try
{
foreach(var providerResolver in LogProviderResolvers)
{
if(providerResolver.Item1())
{
return providerResolver.Item2();
}
}
}
catch (Exception ex)
{
Console.WriteLine(
"Exception occured resolving a log provider. Logging for this assembly {0} is disabled. {1}",
typeof(LogProvider).Assembly.FullName,
ex);
}
return null;
}
public class NoOpLogger : ILog
{
public bool Log(LogLevel logLevel, Func messageFunc, Exception exception)
{
return false;
}
}
}
public class LoggerExecutionWrapper : ILog
{
private readonly ILog _logger;
public const string FailedToGenerateLogMessage = "Failed to generate log message";
public ILog WrappedLogger
{
get { return _logger; }
}
public LoggerExecutionWrapper(ILog logger)
{
_logger = logger;
}
public bool Log(LogLevel logLevel, Func messageFunc, Exception exception = null)
{
if (messageFunc == null)
{
return _logger.Log(logLevel, null);
}
Func wrappedMessageFunc = () =>
{
try
{
return messageFunc();
}
catch (Exception ex)
{
Log(LogLevel.Error, () => FailedToGenerateLogMessage, ex);
}
return null;
};
return _logger.Log(logLevel, wrappedMessageFunc, exception);
}
}
}
namespace DotNetOpenAuth.Logging.LogProviders
{
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;
using System.Threading;
public class NLogLogProvider : ILogProvider
{
private readonly Func _getLoggerByNameDelegate;
private static bool _providerIsAvailableOverride = true;
public NLogLogProvider()
{
if (!IsLoggerAvailable())
{
throw new InvalidOperationException("NLog.LogManager not found");
}
_getLoggerByNameDelegate = GetGetLoggerMethodCall();
}
public static bool ProviderIsAvailableOverride
{
get { return _providerIsAvailableOverride; }
set { _providerIsAvailableOverride = value; }
}
public ILog GetLogger(string name)
{
return new NLogLogger(_getLoggerByNameDelegate(name));
}
public static bool IsLoggerAvailable()
{
return ProviderIsAvailableOverride && GetLogManagerType() != null;
}
private static Type GetLogManagerType()
{
return Type.GetType("NLog.LogManager, NLog");
}
private static Func GetGetLoggerMethodCall()
{
Type logManagerType = GetLogManagerType();
MethodInfo method = logManagerType.GetMethod("GetLogger", new[] { typeof(string) });
ParameterExpression nameParam = Expression.Parameter(typeof(string), "name");
MethodCallExpression methodCall = Expression.Call(null, method, new Expression[] { nameParam });
return Expression.Lambda>(methodCall, new[] { nameParam }).Compile();
}
public class NLogLogger : ILog
{
private readonly dynamic _logger;
internal NLogLogger(dynamic logger)
{
_logger = logger;
}
public bool Log(LogLevel logLevel, Func messageFunc, Exception exception)
{
if (messageFunc == null)
{
return IsLogLevelEnable(logLevel);
}
if(exception != null)
{
return LogException(logLevel, messageFunc, exception);
}
switch (logLevel)
{
case LogLevel.Debug:
if (_logger.IsDebugEnabled)
{
_logger.Debug(messageFunc());
return true;
}
break;
case LogLevel.Info:
if (_logger.IsInfoEnabled)
{
_logger.Info(messageFunc());
return true;
}
break;
case LogLevel.Warn:
if (_logger.IsWarnEnabled)
{
_logger.Warn(messageFunc());
return true;
}
break;
case LogLevel.Error:
if (_logger.IsErrorEnabled)
{
_logger.Error(messageFunc());
return true;
}
break;
case LogLevel.Fatal:
if (_logger.IsFatalEnabled)
{
_logger.Fatal(messageFunc());
return true;
}
break;
default:
if (_logger.IsTraceEnabled)
{
_logger.Trace(messageFunc());
return true;
}
break;
}
return false;
}
private bool LogException(LogLevel logLevel, Func messageFunc, Exception exception)
{
switch (logLevel)
{
case LogLevel.Debug:
if (_logger.IsDebugEnabled)
{
_logger.DebugException(messageFunc(), exception);
return true;
}
break;
case LogLevel.Info:
if (_logger.IsInfoEnabled)
{
_logger.InfoException(messageFunc(), exception);
return true;
}
break;
case LogLevel.Warn:
if (_logger.IsWarnEnabled)
{
_logger.WarnException(messageFunc(), exception);
return true;
}
break;
case LogLevel.Error:
if (_logger.IsErrorEnabled)
{
_logger.ErrorException(messageFunc(), exception);
return true;
}
break;
case LogLevel.Fatal:
if (_logger.IsFatalEnabled)
{
_logger.FatalException(messageFunc(), exception);
return true;
}
break;
default:
if (_logger.IsTraceEnabled)
{
_logger.TraceException(messageFunc(), exception);
return true;
}
break;
}
return false;
}
private bool IsLogLevelEnable(LogLevel logLevel)
{
switch (logLevel)
{
case LogLevel.Debug:
return _logger.IsDebugEnabled;
case LogLevel.Info:
return _logger.IsInfoEnabled;
case LogLevel.Warn:
return _logger.IsWarnEnabled;
case LogLevel.Error:
return _logger.IsErrorEnabled;
case LogLevel.Fatal:
return _logger.IsFatalEnabled;
default:
return _logger.IsTraceEnabled;
}
}
}
}
public class Log4NetLogProvider : ILogProvider
{
private readonly Func _getLoggerByNameDelegate;
private static bool _providerIsAvailableOverride = true;
public Log4NetLogProvider()
{
if (!IsLoggerAvailable())
{
throw new InvalidOperationException("log4net.LogManager not found");
}
_getLoggerByNameDelegate = GetGetLoggerMethodCall();
}
public static bool ProviderIsAvailableOverride
{
get { return _providerIsAvailableOverride; }
set { _providerIsAvailableOverride = value; }
}
public ILog GetLogger(string name)
{
return new Log4NetLogger(_getLoggerByNameDelegate(name));
}
public static bool IsLoggerAvailable()
{
return ProviderIsAvailableOverride && GetLogManagerType() != null;
}
private static Type GetLogManagerType()
{
return Type.GetType("log4net.LogManager, log4net");
}
private static Func GetGetLoggerMethodCall()
{
Type logManagerType = GetLogManagerType();
MethodInfo method = logManagerType.GetMethod("GetLogger", new[] { typeof(string) });
ParameterExpression nameParam = Expression.Parameter(typeof(string), "name");
MethodCallExpression methodCall = Expression.Call(null, method, new Expression[] { nameParam });
return Expression.Lambda>(methodCall, new[] { nameParam }).Compile();
}
public class Log4NetLogger : ILog
{
private readonly dynamic _logger;
internal Log4NetLogger(dynamic logger)
{
_logger = logger;
}
public bool Log(LogLevel logLevel, Func messageFunc, Exception exception)
{
if (messageFunc == null)
{
return IsLogLevelEnable(logLevel);
}
if (exception != null)
{
return LogException(logLevel, messageFunc, exception);
}
switch (logLevel)
{
case LogLevel.Info:
if (_logger.IsInfoEnabled)
{
_logger.Info(messageFunc());
return true;
}
break;
case LogLevel.Warn:
if (_logger.IsWarnEnabled)
{
_logger.Warn(messageFunc());
return true;
}
break;
case LogLevel.Error:
if (_logger.IsErrorEnabled)
{
_logger.Error(messageFunc());
return true;
}
break;
case LogLevel.Fatal:
if (_logger.IsFatalEnabled)
{
_logger.Fatal(messageFunc());
return true;
}
break;
default:
if (_logger.IsDebugEnabled)
{
_logger.Debug(messageFunc()); // Log4Net doesn't have a 'Trace' level, so all Trace messages are written as 'Debug'
return true;
}
break;
}
return false;
}
private bool LogException(LogLevel logLevel, Func messageFunc, Exception exception)
{
switch (logLevel)
{
case LogLevel.Info:
if (_logger.IsDebugEnabled)
{
_logger.Info(messageFunc(), exception);
return true;
}
break;
case LogLevel.Warn:
if (_logger.IsWarnEnabled)
{
_logger.Warn(messageFunc(), exception);
return true;
}
break;
case LogLevel.Error:
if (_logger.IsErrorEnabled)
{
_logger.Error(messageFunc(), exception);
return true;
}
break;
case LogLevel.Fatal:
if (_logger.IsFatalEnabled)
{
_logger.Fatal(messageFunc(), exception);
return true;
}
break;
default:
if (_logger.IsDebugEnabled)
{
_logger.Debug(messageFunc(), exception);
return true;
}
break;
}
return false;
}
private bool IsLogLevelEnable(LogLevel logLevel)
{
switch (logLevel)
{
case LogLevel.Debug:
return _logger.IsDebugEnabled;
case LogLevel.Info:
return _logger.IsInfoEnabled;
case LogLevel.Warn:
return _logger.IsWarnEnabled;
case LogLevel.Error:
return _logger.IsErrorEnabled;
case LogLevel.Fatal:
return _logger.IsFatalEnabled;
default:
return _logger.IsDebugEnabled;
}
}
}
}
public class EntLibLogProvider : ILogProvider
{
private const string TypeTemplate = "Microsoft.Practices.EnterpriseLibrary.Logging.{0}, Microsoft.Practices.EnterpriseLibrary.Logging";
private static bool _providerIsAvailableOverride = true;
private static readonly Type LogEntryType;
private static readonly Type LoggerType;
private static readonly Action WriteLogEntry;
private static Func ShouldLogEntry;
static EntLibLogProvider()
{
LogEntryType = Type.GetType(string.Format(TypeTemplate, "LogEntry"));
LoggerType = Type.GetType(string.Format(TypeTemplate, "Logger"));
if (LogEntryType == null || LoggerType == null)
{
return;
}
WriteLogEntry = GetWriteLogEntry();
ShouldLogEntry = GetShouldLogEntry();
}
public EntLibLogProvider()
{
if (!IsLoggerAvailable())
{
throw new InvalidOperationException("Microsoft.Practices.EnterpriseLibrary.Logging.Logger not found");
}
}
public static bool ProviderIsAvailableOverride
{
get { return _providerIsAvailableOverride; }
set { _providerIsAvailableOverride = value; }
}
public ILog GetLogger(string name)
{
return new EntLibLogger(name, WriteLogEntry, ShouldLogEntry);
}
public static bool IsLoggerAvailable()
{
return ProviderIsAvailableOverride && LogEntryType != null;
}
private static Action GetWriteLogEntry()
{
// new LogEntry(...)
var logNameParameter = Expression.Parameter(typeof(string), "logName");
var messageParameter = Expression.Parameter(typeof(string), "message");
var severityParameter = Expression.Parameter(typeof(TraceEventType), "severity");
MemberInitExpression memberInit = GetWriteLogExpression(messageParameter, severityParameter, logNameParameter);
//Logger.Write(new LogEntry(....));
MethodInfo writeLogEntryMethod = LoggerType.GetMethod("Write", new[] { LogEntryType });
var writeLogEntryExpression = Expression.Call(writeLogEntryMethod, memberInit);
return Expression.Lambda>(
writeLogEntryExpression,
logNameParameter,
messageParameter,
severityParameter).Compile();
}
private static Func GetShouldLogEntry()
{
// new LogEntry(...)
var logNameParameter = Expression.Parameter(typeof(string), "logName");
var severityParameter = Expression.Parameter(typeof(TraceEventType), "severity");
MemberInitExpression memberInit = GetWriteLogExpression(Expression.Constant("***dummy***"), severityParameter, logNameParameter);
//Logger.Write(new LogEntry(....));
MethodInfo writeLogEntryMethod = LoggerType.GetMethod("ShouldLog", new[] { LogEntryType });
var writeLogEntryExpression = Expression.Call(writeLogEntryMethod, memberInit);
return Expression.Lambda>(
writeLogEntryExpression,
logNameParameter,
severityParameter).Compile();
}
private static MemberInitExpression GetWriteLogExpression(Expression message,
ParameterExpression severityParameter, ParameterExpression logNameParameter)
{
var entryType = LogEntryType;
MemberInitExpression memberInit = Expression.MemberInit(Expression.New(entryType), new MemberBinding[]
{
Expression.Bind(entryType.GetProperty("Message"), message),
Expression.Bind(entryType.GetProperty("Severity"), severityParameter),
Expression.Bind(entryType.GetProperty("TimeStamp"),
Expression.Property(null, typeof (DateTime).GetProperty("UtcNow"))),
Expression.Bind(entryType.GetProperty("Categories"),
Expression.ListInit(
Expression.New(typeof (List)),
typeof (List).GetMethod("Add", new[] {typeof (string)}),
logNameParameter))
});
return memberInit;
}
public class EntLibLogger : ILog
{
private readonly string _loggerName;
private readonly Action _writeLog;
private readonly Func _shouldLog;
internal EntLibLogger(string loggerName, Action writeLog, Func shouldLog)
{
_loggerName = loggerName;
_writeLog = writeLog;
_shouldLog = shouldLog;
}
public bool Log(LogLevel logLevel, Func messageFunc, Exception exception)
{
var severity = MapSeverity(logLevel);
if (messageFunc == null)
{
return _shouldLog(_loggerName, severity);
}
if (exception != null)
{
return LogException(logLevel, messageFunc, exception);
}
_writeLog(_loggerName, messageFunc(), severity);
return true;
}
public bool LogException(LogLevel logLevel, Func messageFunc, Exception exception)
{
var severity = MapSeverity(logLevel);
var message = messageFunc() + Environment.NewLine + exception;
_writeLog(_loggerName, message, severity);
return true;
}
private static TraceEventType MapSeverity(LogLevel logLevel)
{
switch (logLevel)
{
case LogLevel.Fatal:
return TraceEventType.Critical;
case LogLevel.Error:
return TraceEventType.Error;
case LogLevel.Warn:
return TraceEventType.Warning;
case LogLevel.Info:
return TraceEventType.Information;
default:
return TraceEventType.Verbose;
}
}
}
}
public class SerilogLogProvider : ILogProvider
{
private readonly Func _getLoggerByNameDelegate;
private static bool _providerIsAvailableOverride = true;
public SerilogLogProvider()
{
if (!IsLoggerAvailable())
{
throw new InvalidOperationException("Serilog.Log not found");
}
_getLoggerByNameDelegate = GetForContextMethodCall();
}
public static bool ProviderIsAvailableOverride
{
get { return _providerIsAvailableOverride; }
set { _providerIsAvailableOverride = value; }
}
public ILog GetLogger(string name)
{
return new SerilogLogger(_getLoggerByNameDelegate(name));
}
public static bool IsLoggerAvailable()
{
return ProviderIsAvailableOverride && GetLogManagerType() != null;
}
private static Type GetLogManagerType()
{
return Type.GetType("Serilog.Log, Serilog");
}
private static Func GetForContextMethodCall()
{
Type logManagerType = GetLogManagerType();
MethodInfo method = logManagerType.GetMethod("ForContext", new[] { typeof(string), typeof(object), typeof(bool) });
ParameterExpression propertyNameParam = Expression.Parameter(typeof(string), "propertyName");
ParameterExpression valueParam = Expression.Parameter(typeof(object), "value");
ParameterExpression destructureObjectsParam = Expression.Parameter(typeof(bool), "destructureObjects");
MethodCallExpression methodCall = Expression.Call(null, method, new Expression[]
{
propertyNameParam,
valueParam,
destructureObjectsParam
});
var func = Expression.Lambda>(methodCall, new[]
{
propertyNameParam,
valueParam,
destructureObjectsParam
}).Compile();
return name => func("Name", name, false);
}
public class SerilogLogger : ILog
{
private readonly object _logger;
private static readonly object DebugLevel;
private static readonly object ErrorLevel;
private static readonly object FatalLevel;
private static readonly object InformationLevel;
private static readonly object VerboseLevel;
private static readonly object WarningLevel;
private static readonly Func