diff --git a/.nuget/NuGet.exe b/.nuget/NuGet.exe
index 9f8781d..6bb79fe 100644
Binary files a/.nuget/NuGet.exe and b/.nuget/NuGet.exe differ
diff --git a/README.md b/README.md
index c568d07..5c3c642 100644
--- a/README.md
+++ b/README.md
@@ -33,6 +33,7 @@ service/environment.
- `NotToBeDisplayedDomainList`(optional) - It will be used when logging host name by excluding these strings in service name attribute
e.g. domain: ".xyz.com", host: "abc.xyz.com" will be logged as "abc" only
- `ExcludedPathList`(optional) - Path list that is not needed for tracing. Each item must start with "/".
+- `Create128BitTraceId` - Create new traces using 128 bit (32 hex character) traceId
```csharp
@@ -166,3 +167,5 @@ ZipkinTracer is (c) Medidata Solutions Worldwide and owned by its major contribu
* [Kenya Matsumoto](https://github.com/kenyamat)
* [Brent Villanueva](https://github.com/bvillanueva-mdsol)
* [Laszlo Schreck](https://github.com/lschreck-mdsol)
+* [Jordi Carres](https://github.com/jcarres-mdsol)
+* [Herry Kurniawan](https://github.com/hkurniawan-mdsol)
diff --git a/src/Medidata.ZipkinTracer.Core/App_Packages/LibLog.4.2/LibLog.cs b/src/Medidata.ZipkinTracer.Core/App_Packages/LibLog.4.2/LibLog.cs
index 45e6da7..22f356c 100644
--- a/src/Medidata.ZipkinTracer.Core/App_Packages/LibLog.4.2/LibLog.cs
+++ b/src/Medidata.ZipkinTracer.Core/App_Packages/LibLog.4.2/LibLog.cs
@@ -422,11 +422,6 @@ interface ILogProvider
static class LogProvider
{
#if !LIBLOG_PROVIDERS_ONLY
- ///
- /// The disable logging environment variable. If the environment variable is set to 'true', then logging
- /// will be disabled.
- ///
- public const string DisableLoggingEnvironmentVariable = "Medidata.ZipkinTracer.Core_LIBLOG_DISABLE";
private const string NullLogProvider = "Current Log Provider is not set. Call SetCurrentLogProvider " +
"with a non-null value first.";
private static dynamic s_currentLogProvider;
@@ -517,15 +512,17 @@ static ILog GetCurrentClassLogger()
/// Gets a logger for the specified type.
///
/// The type whose name will be used for the logger.
+ /// If the type is null then this name will be used as the log name instead
/// An instance of
#if LIBLOG_PUBLIC
public
#else
internal
#endif
- static ILog GetLogger(Type type)
+ static ILog GetLogger(Type type, string fallbackTypeName = "System.Object")
{
- return GetLogger(type.FullName);
+ // If the type passed in is null then fallback to the type name specified
+ return GetLogger(type != null ? type.FullName : fallbackTypeName);
}
///
@@ -541,7 +538,7 @@ static ILog GetLogger(Type type)
static ILog GetLogger(string name)
{
ILogProvider logProvider = CurrentLogProvider ?? ResolveLogProvider();
- return logProvider == null
+ return logProvider == null
? NoOpLogger.Instance
: (ILog)new LoggerExecutionWrapper(logProvider.GetLogger(name), () => IsDisabled);
}
@@ -693,15 +690,6 @@ public bool Log(LogLevel logLevel, Func messageFunc, Exception exception
{
return false;
}
-#if !LIBLOG_PORTABLE
- var envVar = Environment.GetEnvironmentVariable(LogProvider.DisableLoggingEnvironmentVariable);
-
- if (envVar != null && envVar.Equals("true", StringComparison.OrdinalIgnoreCase))
- {
- return false;
- }
-#endif
-
if (messageFunc == null)
{
return _logger(logLevel, null);
@@ -757,7 +745,7 @@ internal abstract class LogProviderBase : ILogProvider
protected LogProviderBase()
{
- _lazyOpenNdcMethod
+ _lazyOpenNdcMethod
= new Lazy(GetOpenNdcMethod);
_lazyOpenMdcMethod
= new Lazy(GetOpenMdcMethod);
@@ -871,6 +859,55 @@ internal class NLogLogger
{
private readonly dynamic _logger;
+ private static Func _logEventInfoFact;
+
+ private static readonly object _levelTrace;
+ private static readonly object _levelDebug;
+ private static readonly object _levelInfo;
+ private static readonly object _levelWarn;
+ private static readonly object _levelError;
+ private static readonly object _levelFatal;
+
+ static NLogLogger()
+ {
+ try
+ {
+ var logEventLevelType = Type.GetType("NLog.LogLevel, NLog");
+ if (logEventLevelType == null)
+ {
+ throw new InvalidOperationException("Type NLog.LogLevel was not found.");
+ }
+
+ var levelFields = logEventLevelType.GetFieldsPortable().ToList();
+ _levelTrace = levelFields.First(x => x.Name == "Trace").GetValue(null);
+ _levelDebug = levelFields.First(x => x.Name == "Debug").GetValue(null);
+ _levelInfo = levelFields.First(x => x.Name == "Info").GetValue(null);
+ _levelWarn = levelFields.First(x => x.Name == "Warn").GetValue(null);
+ _levelError = levelFields.First(x => x.Name == "Error").GetValue(null);
+ _levelFatal = levelFields.First(x => x.Name == "Fatal").GetValue(null);
+
+ var logEventInfoType = Type.GetType("NLog.LogEventInfo, NLog");
+ if (logEventInfoType == null)
+ {
+ throw new InvalidOperationException("Type NLog.LogEventInfo was not found.");
+ }
+ MethodInfo createLogEventInfoMethodInfo = logEventInfoType.GetMethodPortable("Create",
+ logEventLevelType, typeof(string), typeof(Exception), typeof(IFormatProvider), typeof(string), typeof(object[]));
+ ParameterExpression loggerNameParam = Expression.Parameter(typeof(string));
+ ParameterExpression levelParam = Expression.Parameter(typeof(object));
+ ParameterExpression messageParam = Expression.Parameter(typeof(string));
+ ParameterExpression exceptionParam = Expression.Parameter(typeof(Exception));
+ UnaryExpression levelCast = Expression.Convert(levelParam, logEventLevelType);
+ MethodCallExpression createLogEventInfoMethodCall = Expression.Call(null,
+ createLogEventInfoMethodInfo,
+ levelCast, loggerNameParam, exceptionParam,
+ Expression.Constant(null, typeof(IFormatProvider)), messageParam, Expression.Constant(null, typeof(object[])));
+ _logEventInfoFact = Expression.Lambda>(createLogEventInfoMethodCall,
+ loggerNameParam, levelParam, messageParam, exceptionParam).Compile();
+ }
+ catch { }
+ }
+
internal NLogLogger(dynamic logger)
{
_logger = logger;
@@ -885,6 +922,43 @@ public bool Log(LogLevel logLevel, Func messageFunc, Exception exception
}
messageFunc = LogMessageFormatter.SimulateStructuredLogging(messageFunc, formatParameters);
+ if (_logEventInfoFact != null)
+ {
+ if (IsLogLevelEnable(logLevel))
+ {
+ var nlogLevel = this.TranslateLevel(logLevel);
+ Type s_callerStackBoundaryType;
+#if !LIBLOG_PORTABLE
+ StackTrace stack = new StackTrace();
+ Type thisType = GetType();
+ Type knownType0 = typeof(LoggerExecutionWrapper);
+ Type knownType1 = typeof(LogExtensions);
+ //Maybe inline, so we may can't found any LibLog classes in stack
+ s_callerStackBoundaryType = null;
+ for (var i = 0; i < stack.FrameCount; i++)
+ {
+ var declaringType = stack.GetFrame(i).GetMethod().DeclaringType;
+ if (!IsInTypeHierarchy(thisType, declaringType) &&
+ !IsInTypeHierarchy(knownType0, declaringType) &&
+ !IsInTypeHierarchy(knownType1, declaringType))
+ {
+ if (i > 1)
+ s_callerStackBoundaryType = stack.GetFrame(i - 1).GetMethod().DeclaringType;
+ break;
+ }
+ }
+#else
+ s_callerStackBoundaryType = null;
+#endif
+ if (s_callerStackBoundaryType != null)
+ _logger.Log(s_callerStackBoundaryType, _logEventInfoFact(_logger.Name, nlogLevel, messageFunc(), exception));
+ else
+ _logger.Log(_logEventInfoFact(_logger.Name, nlogLevel, messageFunc(), exception));
+ return true;
+ }
+ return false;
+ }
+
if(exception != null)
{
return LogException(logLevel, messageFunc, exception);
@@ -937,6 +1011,19 @@ public bool Log(LogLevel logLevel, Func messageFunc, Exception exception
return false;
}
+ private static bool IsInTypeHierarchy(Type currentType, Type checkType)
+ {
+ while (currentType != null && currentType != typeof(object))
+ {
+ if (currentType == checkType)
+ {
+ return true;
+ }
+ currentType = currentType.GetBaseTypePortable();
+ }
+ return false;
+ }
+
[SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")]
private bool LogException(LogLevel logLevel, Func messageFunc, Exception exception)
{
@@ -1006,6 +1093,27 @@ private bool IsLogLevelEnable(LogLevel logLevel)
return _logger.IsTraceEnabled;
}
}
+
+ private object TranslateLevel(LogLevel logLevel)
+ {
+ switch (logLevel)
+ {
+ case LogLevel.Trace:
+ return _levelTrace;
+ case LogLevel.Debug:
+ return _levelDebug;
+ case LogLevel.Info:
+ return _levelInfo;
+ case LogLevel.Warn:
+ return _levelWarn;
+ case LogLevel.Error:
+ return _levelError;
+ case LogLevel.Fatal:
+ return _levelFatal;
+ default:
+ throw new ArgumentOutOfRangeException("logLevel", logLevel, null);
+ }
+ }
}
}
@@ -1129,7 +1237,9 @@ internal class Log4NetLogger
private readonly object _levelError;
private readonly object _levelFatal;
private readonly Func