44
44
[ assembly: SuppressMessage ( "Microsoft.Design" , "CA1020:AvoidNamespacesWithFewTypes" , Scope = "namespace" , Target = "EasyNetQ.Logging" ) ]
45
45
[ assembly: SuppressMessage ( "Microsoft.Design" , "CA1026:DefaultParametersShouldNotBeUsed" , Scope = "member" , Target = "EasyNetQ.Logging.Logger.#Invoke(EasyNetQ.Logging.LogLevel,System.Func`1<System.String>,System.Exception,System.Object[])" ) ]
46
46
47
- // If you copied this file manually, you need to change all "EasyNetQ " so not to clash with other libraries
47
+ // If you copied this file manually, you need to change all "YourRootNameSpace " so not to clash with other libraries
48
48
// that use LibLog
49
49
#if LIBLOG_PROVIDERS_ONLY
50
50
namespace EasyNetQ . LibLog
@@ -618,7 +618,7 @@ static ILog GetCurrentClassLogger()
618
618
static ILog GetLogger ( Type type , string fallbackTypeName = "System.Object" )
619
619
{
620
620
// If the type passed in is null then fallback to the type name specified
621
- return GetLogger ( type != null ? type . FullName : fallbackTypeName ) ;
621
+ return GetLogger ( type != null ? type . ToString ( ) : fallbackTypeName ) ;
622
622
}
623
623
624
624
/// <summary>
@@ -1018,7 +1018,7 @@ internal class NLogLogger
1018
1018
{
1019
1019
private readonly dynamic _logger ;
1020
1020
1021
- private static Func < string , object , string , Exception , object > _logEventInfoFact ;
1021
+ private static Func < string , object , string , object [ ] , Exception , object > _logEventInfoFact ;
1022
1022
1023
1023
private static readonly object _levelTrace ;
1024
1024
private static readonly object _levelDebug ;
@@ -1027,6 +1027,8 @@ internal class NLogLogger
1027
1027
private static readonly object _levelError ;
1028
1028
private static readonly object _levelFatal ;
1029
1029
1030
+ private static readonly bool _structuredLoggingEnabled ;
1031
+
1030
1032
static NLogLogger ( )
1031
1033
{
1032
1034
try
@@ -1057,6 +1059,7 @@ static NLogLogger()
1057
1059
ParameterExpression loggerNameParam = Expression . Parameter ( typeof ( string ) ) ;
1058
1060
ParameterExpression levelParam = Expression . Parameter ( typeof ( object ) ) ;
1059
1061
ParameterExpression messageParam = Expression . Parameter ( typeof ( string ) ) ;
1062
+ ParameterExpression messageArgsParam = Expression . Parameter ( typeof ( object [ ] ) ) ;
1060
1063
ParameterExpression exceptionParam = Expression . Parameter ( typeof ( Exception ) ) ;
1061
1064
UnaryExpression levelCast = Expression . Convert ( levelParam , logEventLevelType ) ;
1062
1065
@@ -1066,12 +1069,14 @@ static NLogLogger()
1066
1069
loggerNameParam ,
1067
1070
Expression . Constant ( null , typeof ( IFormatProvider ) ) ,
1068
1071
messageParam ,
1069
- Expression . Constant ( null , typeof ( object [ ] ) ) ,
1072
+ messageArgsParam ,
1070
1073
exceptionParam
1071
1074
) ;
1072
1075
1073
- _logEventInfoFact = Expression . Lambda < Func < string , object , string , Exception , object > > ( newLoggingEventExpression ,
1074
- loggerNameParam , levelParam , messageParam , exceptionParam ) . Compile ( ) ;
1076
+ _logEventInfoFact = Expression . Lambda < Func < string , object , string , object [ ] , Exception , object > > ( newLoggingEventExpression ,
1077
+ loggerNameParam , levelParam , messageParam , messageArgsParam , exceptionParam ) . Compile ( ) ;
1078
+
1079
+ _structuredLoggingEnabled = IsStructuredLoggingEnabled ( ) ;
1075
1080
}
1076
1081
catch { }
1077
1082
}
@@ -1089,17 +1094,25 @@ public bool Log(LogLevel logLevel, Func<string> messageFunc, Exception exception
1089
1094
return IsLogLevelEnable ( logLevel ) ;
1090
1095
}
1091
1096
1092
- var callsiteMessageFunc = messageFunc ;
1093
- messageFunc = LogMessageFormatter . SimulateStructuredLogging ( messageFunc , formatParameters ) ;
1094
-
1095
1097
if ( _logEventInfoFact != null )
1096
1098
{
1097
1099
if ( IsLogLevelEnable ( logLevel ) )
1098
1100
{
1101
+ string formatMessage = messageFunc ( ) ;
1102
+ if ( ! _structuredLoggingEnabled )
1103
+ {
1104
+ IEnumerable < string > patternMatches ;
1105
+ formatMessage =
1106
+ LogMessageFormatter . FormatStructuredMessage ( formatMessage ,
1107
+ formatParameters ,
1108
+ out patternMatches ) ;
1109
+ formatParameters = null ; // Has been formatted, no need for parameters
1110
+ }
1111
+
1099
1112
Type callsiteLoggerType = typeof ( NLogLogger ) ;
1100
1113
#if ! LIBLOG_PORTABLE
1101
1114
// Callsite HACK - Extract the callsite-logger-type from the messageFunc
1102
- var methodType = callsiteMessageFunc . Method . DeclaringType ;
1115
+ var methodType = messageFunc . Method . DeclaringType ;
1103
1116
if ( methodType == typeof ( LogExtensions ) || ( methodType != null && methodType . DeclaringType == typeof ( LogExtensions ) ) )
1104
1117
{
1105
1118
callsiteLoggerType = typeof ( LogExtensions ) ;
@@ -1110,13 +1123,14 @@ public bool Log(LogLevel logLevel, Func<string> messageFunc, Exception exception
1110
1123
}
1111
1124
#endif
1112
1125
var nlogLevel = this . TranslateLevel ( logLevel ) ;
1113
- var nlogEvent = _logEventInfoFact ( _logger . Name , nlogLevel , messageFunc ( ) , exception ) ;
1126
+ var nlogEvent = _logEventInfoFact ( _logger . Name , nlogLevel , formatMessage , formatParameters , exception ) ;
1114
1127
_logger . Log ( callsiteLoggerType , nlogEvent ) ;
1115
1128
return true ;
1116
1129
}
1117
1130
return false ;
1118
1131
}
1119
1132
1133
+ messageFunc = LogMessageFormatter . SimulateStructuredLogging ( messageFunc , formatParameters ) ;
1120
1134
if ( exception != null )
1121
1135
{
1122
1136
return LogException ( logLevel , messageFunc , exception ) ;
@@ -1260,6 +1274,33 @@ private object TranslateLevel(LogLevel logLevel)
1260
1274
throw new ArgumentOutOfRangeException ( "logLevel" , logLevel , null ) ;
1261
1275
}
1262
1276
}
1277
+
1278
+ private static bool IsStructuredLoggingEnabled ( )
1279
+ {
1280
+ var configFactoryType = Type . GetType ( "NLog.Config.ConfigurationItemFactory, NLog" ) ;
1281
+ if ( configFactoryType != null )
1282
+ {
1283
+ PropertyInfo parseMessagesProperty = configFactoryType . GetPropertyPortable ( "ParseMessageTemplates" ) ;
1284
+ if ( parseMessagesProperty != null )
1285
+ {
1286
+ PropertyInfo defaultProperty = configFactoryType . GetPropertyPortable ( "Default" ) ;
1287
+ if ( defaultProperty != null )
1288
+ {
1289
+ object configFactoryDefault = defaultProperty . GetValue ( null , null ) ;
1290
+ if ( configFactoryDefault != null )
1291
+ {
1292
+ Nullable < bool > parseMessageTemplates = parseMessagesProperty . GetValue ( configFactoryDefault , null ) as Nullable < bool > ;
1293
+ if ( parseMessageTemplates != false )
1294
+ {
1295
+ return true ;
1296
+ }
1297
+ }
1298
+ }
1299
+ }
1300
+ }
1301
+
1302
+ return false ;
1303
+ }
1263
1304
}
1264
1305
}
1265
1306
@@ -1380,8 +1421,6 @@ private static Func<string, object> GetGetLoggerMethodCall()
1380
1421
internal class Log4NetLogger
1381
1422
{
1382
1423
private readonly dynamic _logger ;
1383
- private static Type s_callerStackBoundaryType ;
1384
- private static readonly object CallerStackBoundaryTypeSync = new object ( ) ;
1385
1424
1386
1425
private static readonly object _levelDebug ;
1387
1426
private static readonly object _levelInfo ;
@@ -1551,41 +1590,31 @@ public bool Log(LogLevel logLevel, Func<string> messageFunc, Exception exception
1551
1590
return false ;
1552
1591
}
1553
1592
1554
- string message = messageFunc ( ) ;
1555
-
1556
1593
IEnumerable < string > patternMatches ;
1557
-
1558
1594
string formattedMessage =
1559
- LogMessageFormatter . FormatStructuredMessage ( message ,
1595
+ LogMessageFormatter . FormatStructuredMessage ( messageFunc ( ) ,
1560
1596
formatParameters ,
1561
1597
out patternMatches ) ;
1562
1598
1563
- // determine correct caller - this might change due to jit optimizations with method inlining
1564
- if ( s_callerStackBoundaryType == null )
1565
- {
1566
- lock ( CallerStackBoundaryTypeSync )
1567
- {
1599
+ Type callerStackBoundaryType = typeof ( Log4NetLogger ) ;
1568
1600
#if ! LIBLOG_PORTABLE
1569
- StackTrace stack = new StackTrace ( ) ;
1570
- Type thisType = GetType ( ) ;
1571
- s_callerStackBoundaryType = Type . GetType ( "LoggerExecutionWrapper" ) ;
1572
- for ( var i = 1 ; i < stack . FrameCount ; i ++ )
1573
- {
1574
- if ( ! IsInTypeHierarchy ( thisType , stack . GetFrame ( i ) . GetMethod ( ) . DeclaringType ) )
1575
- {
1576
- s_callerStackBoundaryType = stack . GetFrame ( i - 1 ) . GetMethod ( ) . DeclaringType ;
1577
- break ;
1578
- }
1579
- }
1601
+ // Callsite HACK - Extract the callsite-logger-type from the messageFunc
1602
+ var methodType = messageFunc . Method . DeclaringType ;
1603
+ if ( methodType == typeof ( LogExtensions ) || ( methodType != null && methodType . DeclaringType == typeof ( LogExtensions ) ) )
1604
+ {
1605
+ callerStackBoundaryType = typeof ( LogExtensions ) ;
1606
+ }
1607
+ else if ( methodType == typeof ( LoggerExecutionWrapper ) || ( methodType != null && methodType . DeclaringType == typeof ( LoggerExecutionWrapper ) ) )
1608
+ {
1609
+ callerStackBoundaryType = typeof ( LoggerExecutionWrapper ) ;
1610
+ }
1580
1611
#else
1581
- s_callerStackBoundaryType = typeof ( LoggerExecutionWrapper ) ;
1612
+ callerStackBoundaryType = typeof ( LoggerExecutionWrapper ) ;
1582
1613
#endif
1583
- }
1584
- }
1585
1614
1586
1615
var translatedLevel = TranslateLevel ( logLevel ) ;
1587
1616
1588
- object loggingEvent = _createLoggingEvent ( _logger , s_callerStackBoundaryType , translatedLevel , formattedMessage , exception ) ;
1617
+ object loggingEvent = _createLoggingEvent ( _logger , callerStackBoundaryType , translatedLevel , formattedMessage , exception ) ;
1589
1618
1590
1619
PopulateProperties ( loggingEvent , patternMatches , formatParameters ) ;
1591
1620
@@ -1596,27 +1625,17 @@ public bool Log(LogLevel logLevel, Func<string> messageFunc, Exception exception
1596
1625
1597
1626
private void PopulateProperties ( object loggingEvent , IEnumerable < string > patternMatches , object [ ] formatParameters )
1598
1627
{
1599
- IEnumerable < KeyValuePair < string , object > > keyToValue =
1628
+ if ( patternMatches . Count ( ) > 0 )
1629
+ {
1630
+ IEnumerable < KeyValuePair < string , object > > keyToValue =
1600
1631
patternMatches . Zip ( formatParameters ,
1601
1632
( key , value ) => new KeyValuePair < string , object > ( key , value ) ) ;
1602
1633
1603
- foreach ( KeyValuePair < string , object > keyValuePair in keyToValue )
1604
- {
1605
- _loggingEventPropertySetter ( loggingEvent , keyValuePair . Key , keyValuePair . Value ) ;
1606
- }
1607
- }
1608
-
1609
- private static bool IsInTypeHierarchy ( Type currentType , Type checkType )
1610
- {
1611
- while ( currentType != null && currentType != typeof ( object ) )
1612
- {
1613
- if ( currentType == checkType )
1634
+ foreach ( KeyValuePair < string , object > keyValuePair in keyToValue )
1614
1635
{
1615
- return true ;
1636
+ _loggingEventPropertySetter ( loggingEvent , keyValuePair . Key , keyValuePair . Value ) ;
1616
1637
}
1617
- currentType = currentType . GetBaseTypePortable ( ) ;
1618
1638
}
1619
- return false ;
1620
1639
}
1621
1640
1622
1641
private bool IsLogLevelEnable ( LogLevel logLevel )
@@ -1790,7 +1809,6 @@ public bool Log(LogLevel logLevel, Func<string> messageFunc, Exception exception
1790
1809
return _shouldLog ( _loggerName , severity ) ;
1791
1810
}
1792
1811
1793
-
1794
1812
messageFunc = LogMessageFormatter . SimulateStructuredLogging ( messageFunc , formatParameters ) ;
1795
1813
if ( exception != null )
1796
1814
{
@@ -2297,14 +2315,13 @@ private static string ReplaceFirst(string text, string search, string replace)
2297
2315
2298
2316
public static string FormatStructuredMessage ( string targetMessage , object [ ] formatParameters , out IEnumerable < string > patternMatches )
2299
2317
{
2300
- if ( formatParameters . Length == 0 )
2318
+ if ( formatParameters == null || formatParameters . Length == 0 )
2301
2319
{
2302
2320
patternMatches = Enumerable . Empty < string > ( ) ;
2303
2321
return targetMessage ;
2304
2322
}
2305
2323
2306
- List < string > processedArguments = new List < string > ( ) ;
2307
- patternMatches = processedArguments ;
2324
+ List < string > processedArguments = null ;
2308
2325
2309
2326
foreach ( Match match in Pattern . Matches ( targetMessage ) )
2310
2327
{
@@ -2313,6 +2330,7 @@ public static string FormatStructuredMessage(string targetMessage, object[] form
2313
2330
int notUsed ;
2314
2331
if ( ! int . TryParse ( arg , out notUsed ) )
2315
2332
{
2333
+ processedArguments = processedArguments ?? new List < string > ( formatParameters . Length ) ;
2316
2334
int argumentIndex = processedArguments . IndexOf ( arg ) ;
2317
2335
if ( argumentIndex == - 1 )
2318
2336
{
@@ -2321,9 +2339,12 @@ public static string FormatStructuredMessage(string targetMessage, object[] form
2321
2339
}
2322
2340
2323
2341
targetMessage = ReplaceFirst ( targetMessage , match . Value ,
2324
- "{" + argumentIndex + match . Groups [ "format" ] . Value + "}" ) ;
2342
+ string . Concat ( "{" , argumentIndex . ToString ( ) , match . Groups [ "format" ] . Value , "}" ) ) ;
2325
2343
}
2326
2344
}
2345
+
2346
+ patternMatches = processedArguments ?? Enumerable . Empty < string > ( ) ;
2347
+
2327
2348
try
2328
2349
{
2329
2350
return string . Format ( CultureInfo . InvariantCulture , targetMessage , formatParameters ) ;
0 commit comments