diff --git a/src/Essential.Diagnostics.SeqTraceListener/Diagnostics/SeqTraceListener.cs b/src/Essential.Diagnostics.SeqTraceListener/Diagnostics/SeqTraceListener.cs index eb3f723..73709d0 100644 --- a/src/Essential.Diagnostics.SeqTraceListener/Diagnostics/SeqTraceListener.cs +++ b/src/Essential.Diagnostics.SeqTraceListener/Diagnostics/SeqTraceListener.cs @@ -44,6 +44,7 @@ public class SeqTraceListener : TraceListenerBase "batchTimeout", "BatchTimeout", "batchtimeout", "batchTimeOut", "BatchTimeOut", "maxQueueSize", "MaxQueueSize", "maxqueuesize", "maxRetries", "MaxRetries", "maxretries", + "processDictionaryData", "ProcessDictionaryData", "processdictionarydata", }; /// @@ -275,6 +276,26 @@ public int MaxRetries } } + /// + /// Gets or sets whether a single data of type IDictionary<string,object> is treated as structured data. Default is true. + /// + public bool ProcessDictionaryData + { + get + { + var processDictionaryData = true; + if (Attributes.ContainsKey("processDictionaryData")) + { + bool.TryParse(Attributes["processDictionaryData"], out processDictionaryData); + } + return processDictionaryData; + } + set + { + Attributes["processDictionaryData"] = value.ToString(CultureInfo.InvariantCulture); + } + } + /// /// Allowed attributes for this trace listener. /// @@ -459,7 +480,8 @@ private TraceData CreateTraceData(TraceEventCache eventCache, string source, Tra && (messageArgs == null || messageArgs.Length == 0) && data != null && data.Length == 1 - && (data[0] is IStructuredData || data[0] is IDictionary)) + && (data[0] is IStructuredData || + (data[0] is IDictionary && ProcessDictionaryData))) { var structuredData = (IDictionary)data[0]; AddStructuredData(properties, structuredData, ref exception, ref messageFormat); diff --git a/src/Tests/Essential.Diagnostics.SeqTraceListener.Tests/SeqStructuredDataTests.cs b/src/Tests/Essential.Diagnostics.SeqTraceListener.Tests/SeqStructuredDataTests.cs index 3ba7f3a..6b470a7 100644 --- a/src/Tests/Essential.Diagnostics.SeqTraceListener.Tests/SeqStructuredDataTests.cs +++ b/src/Tests/Essential.Diagnostics.SeqTraceListener.Tests/SeqStructuredDataTests.cs @@ -289,7 +289,6 @@ public void SeqStructuredRecursiveDictionaryShouldStop() StringAssert.Contains(requestBody, "\"b\":{\"X\":2,\"Y\":{\"A\":1,\"B\":\"System.Collections.Generic.Dictionary`2[System.String,System.Object]\"}}"); } - [TestMethod] public void SeqHandlesStructuredDictionary() { @@ -321,6 +320,36 @@ public void SeqHandlesStructuredDictionary() StringAssert.DoesNotMatch(requestBody, regexData); } + [TestMethod] + public void SeqIgnoresStructuredDictionaryWhenTurnedOff() + { + var mockRequestFactory = new MockHttpWebRequestFactory(); + mockRequestFactory.ResponseQueue.Enqueue( + new MockHttpWebResponse(HttpStatusCode.OK, null) + ); + + var listener = new SeqTraceListener("http://testuri"); + listener.BatchSize = 0; + listener.BatchSender.HttpWebRequestFactory = mockRequestFactory; + listener.ProcessDictionaryData = false; + + var dictionaryData = new Dictionary() { + { "MessageTemplate", "{a}" }, + { "a", 1 } + }; + listener.TraceData(null, "TestSource", TraceEventType.Warning, 1, dictionaryData); + + Assert.AreEqual(1, mockRequestFactory.RequestsCreated.Count); + + var request = mockRequestFactory.RequestsCreated[0]; + var requestBody = request.RequestBody; + Console.WriteLine(requestBody); + var regexTemplateData = new Regex("\"MessageTemplate\":\"{Data}\""); + StringAssert.Matches(requestBody, regexTemplateData); + var regexData = new Regex("\"Data\":"); + StringAssert.Matches(requestBody, regexData); + } + [TestMethod] public void SeqStructuredCustomObject() {