Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion Src/StackifyLib/Config.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using StackifyLib.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
using StackifyLib.Utils;

namespace StackifyLib
{
Expand Down Expand Up @@ -110,6 +110,15 @@ public static void LoadSettings()
LoggingJsonMaxFields = maxFields;
}
}

var loggingJsonMaxDepth = Get("Stackify.Logging.JsonMaxDepth", "5");
if (string.IsNullOrWhiteSpace(loggingJsonMaxDepth) == false)
{
if (int.TryParse(loggingJsonMaxDepth, out int maxDepth) && maxDepth > 0 && maxDepth < 20)
{
LoggingJsonMaxDepth = maxDepth;
}
}
}
catch (Exception ex)
{
Expand Down Expand Up @@ -152,6 +161,8 @@ public static void LoadSettings()

public static int LoggingJsonMaxFields { get; set; } = 50;

public static int LoggingJsonMaxDepth { get; set; } = 5;


/// <summary>
/// Attempts to fetch a setting value given the key.
Expand Down
12 changes: 11 additions & 1 deletion Src/StackifyLib/Internal/Logs/LogClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using StackifyLib.Utils;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Threading;
Expand Down Expand Up @@ -315,8 +316,17 @@ internal HttpClient.StackifyWebResponse SendLogsByGroups(LogMsg[] messages)

var groups = SplitLogsToGroups(messages);

string jsonData = JsonConvert.SerializeObject(groups, new JsonSerializerSettings() { NullValueHandling = NullValueHandling.Ignore });
var settings = new JsonSerializerSettings() { MaxDepth = Config.LoggingJsonMaxDepth, NullValueHandling = NullValueHandling.Ignore };

string jsonData;
using (var writer = new StringWriter())
{
using (var jsonWriter = new MaxDepthJsonTextWriter(writer, settings))
{
JsonSerializer.CreateDefault().Serialize(jsonWriter, groups);
jsonData = writer.ToString();
}
}

string urlToUse = (_HttpClient.BaseAPIUrl) + "Log/SaveMultipleGroups";

Expand Down
56 changes: 56 additions & 0 deletions Src/StackifyLib/Internal/MaxDepthJsonTextWriter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using Newtonsoft.Json;

namespace StackifyLib.Internal
{
/// <summary>
/// Source: https://stackoverflow.com/a/29684280/10100417
/// </summary>
public class MaxDepthJsonTextWriter : JsonTextWriter
{
public int? MaxDepth { get; set; }
public int MaxObservedDepth { get; private set; }

public MaxDepthJsonTextWriter(TextWriter writer, JsonSerializerSettings settings) : base(writer)
{
this.MaxDepth = (settings == null ? null : settings.MaxDepth);
this.MaxObservedDepth = 0;
}

public MaxDepthJsonTextWriter(TextWriter writer, int? maxDepth) : base(writer)
{
this.MaxDepth = maxDepth;
}

public override void WriteStartArray()
{
base.WriteStartArray();
CheckDepth();
}

public override void WriteStartConstructor(string name)
{
base.WriteStartConstructor(name);
CheckDepth();
}

public override void WriteStartObject()
{
base.WriteStartObject();
CheckDepth();
}

private void CheckDepth()
{
MaxObservedDepth = Math.Max(MaxObservedDepth, Top);

if (Top > MaxDepth)
{
throw new JsonSerializationException(string.Format("Depth {0} Exceeds MaxDepth {1} at path \"{2}\"", Top, MaxDepth, Path));
}
}
}
}
6 changes: 3 additions & 3 deletions Src/StackifyLib/StackifyLib.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,15 @@
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
<GenerateAssemblyCopyrightAttribute>false</GenerateAssemblyCopyrightAttribute>
<Version>2.1.2</Version>
<Version>2.1.3</Version>
<Authors>StackifyLib</Authors>
<PackageProjectUrl>https://github.com/stackify/stackify-api-dotnet</PackageProjectUrl>
<PackageLicenseUrl>https://github.com/stackify/stackify-api-dotnet/blob/master/LICENSE</PackageLicenseUrl>
<RepositoryUrl>https://github.com/stackify/stackify-api-dotnet</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<PackageIconUrl>https://stackify.com/wp-content/uploads/2017/02/stk.png</PackageIconUrl>
<AssemblyVersion>2.1.2.0</AssemblyVersion>
<FileVersion>2.1.2.0</FileVersion>
<AssemblyVersion>2.1.3.0</AssemblyVersion>
<FileVersion>2.1.3.0</FileVersion>
</PropertyGroup>

<ItemGroup>
Expand Down
35 changes: 27 additions & 8 deletions Src/StackifyLib/Utils/HelperFunctions.cs
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

using StackifyLib.Internal;

namespace StackifyLib.Utils
{
public class HelperFunctions
{
static List<string> _BadTypes = new List<string>() { "log4net.Util.SystemStringFormat", "System.Object[]" };
static JsonSerializer serializer = new JsonSerializer { ReferenceLoopHandling = ReferenceLoopHandling.Ignore };
static JsonSerializerSettings serializerSettings = new JsonSerializerSettings() { NullValueHandling = NullValueHandling.Ignore, ReferenceLoopHandling = ReferenceLoopHandling.Ignore };
private static List<string> _BadTypes = new List<string>() { "log4net.Util.SystemStringFormat", "System.Object[]" };
private static JsonSerializer serializer = new JsonSerializer { ReferenceLoopHandling = ReferenceLoopHandling.Ignore };
private static JsonSerializerSettings serializerSettings = new JsonSerializerSettings() { NullValueHandling = NullValueHandling.Ignore, ReferenceLoopHandling = ReferenceLoopHandling.Ignore };

/// <summary>
/// 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.
Expand Down Expand Up @@ -92,7 +93,7 @@ public static string SerializeDebugData(object logObject, bool serializeSimpleTy

if (type.IsArray)
{
var array = (Array) logObject;
var array = (Array)logObject;

if (array.Length > 0)
{
Expand Down Expand Up @@ -204,10 +205,28 @@ public static string SerializeDebugData(object logObject, bool serializeSimpleTy

if (jObject != null)
{
try
{
jObject = GetPrunedObject(jObject, Config.LoggingJsonMaxFields);

string json;
using (var writer = new StringWriter())
{
using (var jsonWriter = new MaxDepthJsonTextWriter(writer, Config.LoggingJsonMaxDepth))
{
JsonSerializer.CreateDefault().Serialize(jsonWriter, jObject);
json = writer.ToString();
}
}

jObject = GetPrunedObject(jObject, Config.LoggingJsonMaxFields);
return json;
}
catch (JsonSerializationException ex)
{
Utils.StackifyAPILogger.Log(ex.ToString(), true);

return JsonConvert.SerializeObject(jObject, serializerSettings);
return null;
}
}

return null;
Expand Down
56 changes: 52 additions & 4 deletions test/StackifyLib.UnitTests/JsonSerialization_Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public JsonSerialization_Tests(ITestOutputHelper output)
[Fact]
public void Should_Prune_Object()
{
var testMaxFields = GetTestObject();
var testMaxFields = GetTestObjectFields();

var result = StackifyLib.Utils.HelperFunctions.SerializeDebugData(testMaxFields, false);

Expand All @@ -41,10 +41,10 @@ public void Should_Prune_Object_Array()
{
var list = new List<object>();

var testOne = GetTestObject();
var testOne = GetTestObjectFields();
list.Add(testOne);

var testTwo = GetTestObject();
var testTwo = GetTestObjectFields();
list.Add(testTwo);

var result = StackifyLib.Utils.HelperFunctions.SerializeDebugData(list, false);
Expand All @@ -58,8 +58,56 @@ public void Should_Prune_Object_Array()
Assert.Equal(2, obj.Count);
}

[Fact]
public void Should_Throw_On_Max_Depth()
{
var obj = GetTestObjectDepth();
var result = StackifyLib.Utils.HelperFunctions.SerializeDebugData(obj, false);
Assert.Null(result);
}


private static object GetTestObjectDepth()
{
var obj = new
{
One = new
{
Two = new
{
Three = new
{
Four = new
{
Five = new
{
Six = new
{
Seven = new
{
Eight = new
{
Nine = new
{
Ten = new
{

}
}
}
}
}
}
}
}
}
}
};

return obj;
}

private static object GetTestObject()
private static object GetTestObjectFields()
{
var obj = new
{
Expand Down