From 44fff1ffe334008ec166b84b37198c0ca5a1bc96 Mon Sep 17 00:00:00 2001 From: Rolf Kristensen Date: Tue, 5 Dec 2017 22:51:48 +0100 Subject: [PATCH] NLog.Targets.Stackify - Added logAllProperties for structured logging --- Src/CoreConsoleApp/CoreConsoleApp.csproj | 8 +- Src/CoreWebApp/CoreWebApp.csproj | 4 +- .../NLog.Targets.Stackify.csproj | 6 +- Src/NLog.Targets.Stackify/StackifyTarget.cs | 117 +++++++++--------- Src/StackifyLib/Utils/HelperFunctions.cs | 24 ++-- 5 files changed, 80 insertions(+), 79 deletions(-) diff --git a/Src/CoreConsoleApp/CoreConsoleApp.csproj b/Src/CoreConsoleApp/CoreConsoleApp.csproj index 8e8002e..ebe8247 100644 --- a/Src/CoreConsoleApp/CoreConsoleApp.csproj +++ b/Src/CoreConsoleApp/CoreConsoleApp.csproj @@ -21,11 +21,11 @@ - + - - - + + + diff --git a/Src/CoreWebApp/CoreWebApp.csproj b/Src/CoreWebApp/CoreWebApp.csproj index 7b25013..7392d38 100644 --- a/Src/CoreWebApp/CoreWebApp.csproj +++ b/Src/CoreWebApp/CoreWebApp.csproj @@ -36,8 +36,8 @@ - - + + diff --git a/Src/NLog.Targets.Stackify/NLog.Targets.Stackify.csproj b/Src/NLog.Targets.Stackify/NLog.Targets.Stackify.csproj index 0d9afb2..9267109 100644 --- a/Src/NLog.Targets.Stackify/NLog.Targets.Stackify.csproj +++ b/Src/NLog.Targets.Stackify/NLog.Targets.Stackify.csproj @@ -3,7 +3,7 @@ NLog.Targets.Stackify 2.0.0 - netstandard1.3;net40;net45 + netstandard1.5;net40;net45 NLog.Targets.Stackify NLog.Targets.Stackify stackify;errors;logs @@ -27,8 +27,8 @@ - - + + diff --git a/Src/NLog.Targets.Stackify/StackifyTarget.cs b/Src/NLog.Targets.Stackify/StackifyTarget.cs index 2374ad7..0e8d07e 100644 --- a/Src/NLog.Targets.Stackify/StackifyTarget.cs +++ b/Src/NLog.Targets.Stackify/StackifyTarget.cs @@ -7,9 +7,6 @@ #if NET45 || NET40 using System.Runtime.Remoting.Messaging; #endif -using System.Security; -using System.Text; -using System.Threading.Tasks; using StackifyLib; using System.Diagnostics; using StackifyLib.Internal.Logs; @@ -31,6 +28,8 @@ public class StackifyTarget : TargetWithLayout public string callContextKeys { get; set; } public bool? logMethodNames { get; set; } public bool? logAllParams { get; set; } + public bool? logAllProperties { get; set; } + public bool? logLastParameter { get; set; } private List _GlobalContextKeys = new List(); private List _MappedContextKeys = new List(); @@ -99,17 +98,13 @@ protected override void Write(LogEventInfo logEvent) { StackifyAPILogger.Log(ex.ToString()); } - } private Dictionary GetDiagnosticContextProperties() { - - Dictionary properties = new Dictionary(); - string ndc = NLog.NestedDiagnosticsContext.TopMessage; if (!String.IsNullOrEmpty(ndc)) @@ -117,14 +112,12 @@ private Dictionary GetDiagnosticContextProperties() properties["ndc"] = ndc; } - if (!_HasContextKeys) { return properties; } // GlobalDiagnosticsContext - foreach (string gdcKey in _GlobalContextKeys) { if (NLog.GlobalDiagnosticsContext.Contains(gdcKey)) @@ -137,8 +130,8 @@ private Dictionary GetDiagnosticContextProperties() } } } - // MappedDiagnosticsContext + // MappedDiagnosticsContext foreach (string mdcKey in _MappedContextKeys) { if (NLog.MappedDiagnosticsContext.Contains(mdcKey)) @@ -170,7 +163,6 @@ private Dictionary GetDiagnosticContextProperties() internal LogMsg Translate(LogEventInfo loggingEvent) { - if (loggingEvent == null) return null; @@ -180,14 +172,11 @@ internal LogMsg Translate(LogEventInfo loggingEvent) StackifyLib.Models.LogMsg msg = new LogMsg(); - if (loggingEvent.Level != null) { msg.Level = loggingEvent.Level.Name; } - - if (loggingEvent.HasStackTrace && loggingEvent.UserStackFrame != null) { var frame = loggingEvent.UserStackFrame; @@ -201,10 +190,8 @@ internal LogMsg Translate(LogEventInfo loggingEvent) msg.SrcLine = frame.GetFileLineNumber(); } } - } - //if it wasn't set above for some reason we will do it this way as a fallback if (string.IsNullOrEmpty(msg.SrcMethod)) { @@ -240,47 +227,33 @@ internal LogMsg Translate(LogEventInfo loggingEvent) msg.Msg = (formattedMessage ?? "").Trim(); object debugObject = null; - Dictionary args = new Dictionary(); - if ((loggingEvent.Parameters != null) && (loggingEvent.Parameters.Length > 0)) + if ((logAllProperties ?? true) && loggingEvent.Properties.Count > 0) { - - for (int i = 0; i < loggingEvent.Parameters.Length; i++) + Dictionary args = new Dictionary(); + foreach (KeyValuePair eventProperty in loggingEvent.Properties) { - var item = loggingEvent.Parameters[i]; - - if (item == null) + string propertyKey = eventProperty.Key.ToString(); + if (!string.IsNullOrEmpty(propertyKey)) { - continue; - } - else if (item is Exception) - { - if (loggingEvent.Exception == null) - { - loggingEvent.Exception = (Exception)item; - } - } - else if (item.ToString() == msg.Msg) - { - //ignore it. - } - else if (logAllParams ?? true) - { - args["arg" + i] = loggingEvent.Parameters[i]; - debugObject = item; - } - else - { - debugObject = item; + args[propertyKey] = eventProperty.Value; } } - if ((logAllParams ?? true) && args != null && args.Count > 1) + if ((logAllParams ?? false) && loggingEvent.Parameters != null && loggingEvent.Parameters.Length > 0) + { + debugObject = CaptureParameters(loggingEvent, msg.Msg, args); + } + else { debugObject = args; } } - + else if (loggingEvent.Parameters != null && loggingEvent.Parameters.Length > 0) + { + Dictionary args = (logAllParams ?? true) ? new Dictionary() : null; + debugObject = CaptureParameters(loggingEvent, msg.Msg, args); + } StackifyError error = null; @@ -300,13 +273,6 @@ internal LogMsg Translate(LogEventInfo loggingEvent) diags.Remove("transid"); } - - - - - - - if (debugObject != null) { msg.data = StackifyLib.Utils.HelperFunctions.SerializeDebugData(debugObject, true, diags); @@ -315,7 +281,6 @@ internal LogMsg Translate(LogEventInfo loggingEvent) { msg.data = StackifyLib.Utils.HelperFunctions.SerializeDebugData(null, false, diags); } - if (msg.Msg != null && error != null) { @@ -357,11 +322,51 @@ internal LogMsg Translate(LogEventInfo loggingEvent) msg.Msg += " #errorgoverned"; } - return msg; } + private object CaptureParameters(LogEventInfo loggingEvent, string logMessage, Dictionary args) + { + object debugObject = null; + if (args != null || (logLastParameter ?? true)) + { + for (int i = 0; i < loggingEvent.Parameters.Length; i++) + { + var item = loggingEvent.Parameters[i]; + + if (item == null) + { + continue; + } + else if (item is Exception) + { + if (loggingEvent.Exception == null) + { + loggingEvent.Exception = (Exception)item; + } + } + else if (item.ToString() == logMessage) + { + //ignore it. + } + else if (args != null) + { + args["arg" + i] = loggingEvent.Parameters[i]; + debugObject = item; + } + else + { + debugObject = item; + } + } + + if (args != null && args.Count > 1) + { + debugObject = args; + } + } - + return debugObject; + } } } diff --git a/Src/StackifyLib/Utils/HelperFunctions.cs b/Src/StackifyLib/Utils/HelperFunctions.cs index 567f3f8..62591d6 100644 --- a/Src/StackifyLib/Utils/HelperFunctions.cs +++ b/Src/StackifyLib/Utils/HelperFunctions.cs @@ -16,6 +16,7 @@ public class HelperFunctions { static List _BadTypes = new List() { "log4net.Util.SystemStringFormat", "System.Object[]" }; static JsonSerializer serializer = new JsonSerializer { ReferenceLoopHandling = ReferenceLoopHandling.Ignore }; + static JsonSerializerSettings serializerSettings = new JsonSerializerSettings() { NullValueHandling = NullValueHandling.Ignore, ReferenceLoopHandling = ReferenceLoopHandling.Ignore }; /// /// Trying to serialize something that the user passed in. Sometimes this is used to serialize what we know is additional debug and sometimes it is the primary logged item. This is why the serializeSimpleTypes exists. For additional debug stuff we always serialize it. For the primary logged object we won't because it doesn't make any sense to put a string in the json as well as the main message. It's meant for objects. @@ -126,21 +127,22 @@ public static string SerializeDebugData(object logObject, bool serializeSimpleTy } else { - if (!typeInfo.ContainsGenericParameters) { jObject.Add("objectType", type.FullName); } -#if NET451 || NET45 || NET40 else { - +#if NET451 || NET45 || NET40 var genericArgs = typeInfo.GetGenericArguments(); - - if (genericArgs.Any()) +#else + var genericArgs = typeInfo.IsGenericTypeDefinition ? + type.GetTypeInfo().GenericTypeParameters : + type.GetTypeInfo().GenericTypeArguments; +#endif + if (genericArgs != null && genericArgs.Length > 0) { var childtype = genericArgs.First(); - #if NET40 var childtypeinfo = childtype; #else @@ -161,7 +163,6 @@ public static string SerializeDebugData(object logObject, bool serializeSimpleTy jObject.Add("objectType", type.FullName); } } -#endif } } else if (token is JValue) @@ -185,7 +186,7 @@ public static string SerializeDebugData(object logObject, bool serializeSimpleTy } string data = null; - if (properties != null && properties.Any()) + if (properties != null && properties.Count > 0) { if (jObject == null) @@ -221,12 +222,7 @@ public static string SerializeDebugData(object logObject, bool serializeSimpleTy if (jObject != null) { - return JsonConvert.SerializeObject(jObject, - new JsonSerializerSettings() - { - NullValueHandling = NullValueHandling.Ignore, - ReferenceLoopHandling = ReferenceLoopHandling.Ignore - }); + return JsonConvert.SerializeObject(jObject, serializerSettings); } return null;