Skip to content

Commit

Permalink
Merge pull request #35 from nblumhardt/serilog-structures
Browse files Browse the repository at this point in the history
Serilog input: convert `StructureValue` into `IDictionary<string,object>` when possible
  • Loading branch information
karolz-ms authored Jan 11, 2017
2 parents abb6be2 + 72aa6a5 commit 7891fed
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 4 deletions.
39 changes: 35 additions & 4 deletions src/Microsoft.Diagnostics.EventFlow.Inputs.Serilog/SerilogInput.cs
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ private EventData ToEventData(LogEvent logEvent)
return eventData;
}

private object ToRawValue(LogEventPropertyValue logEventValue)
private static object ToRawValue(LogEventPropertyValue logEventValue)
{
// Special-case a few types of LogEventPropertyValue that allow us to maintain better type fidelity.
// For everything else take the default string rendering as the data.
Expand All @@ -119,20 +119,40 @@ private object ToRawValue(LogEventPropertyValue logEventValue)
SequenceValue sequenceValue = logEventValue as SequenceValue;
if (sequenceValue != null)
{
object[] arrayResult = sequenceValue.Elements.OfType<ScalarValue>().Select(e => e.Value).ToArray();
object[] arrayResult = sequenceValue.Elements.Select(e => ToRawScalar(e)).ToArray();
if (arrayResult.Length == sequenceValue.Elements.Count)
{
// All values extracted successfully, it is a flat array of scalars
return arrayResult;
}
}

StructureValue structureValue = logEventValue as StructureValue;
if (structureValue != null)
{
IDictionary<string, object> structureResult = new Dictionary<string, object>(structureValue.Properties.Count);
foreach (var property in structureValue.Properties)
{
structureResult[property.Name] = ToRawScalar(property.Value);
}

if (structureResult.Count == structureValue.Properties.Count)
{
if (structureValue.TypeTag != null)
{
structureResult["$type"] = structureValue.TypeTag;
}

return structureResult;
}
}

DictionaryValue dictionaryValue = logEventValue as DictionaryValue;
if (dictionaryValue != null)
{
IDictionary<string, object> dictionaryResult = dictionaryValue.Elements
.Where(kvPair => kvPair.Key.Value is string && kvPair.Value is ScalarValue)
.ToDictionary(kvPair => (string)kvPair.Key.Value, kvPair => ((ScalarValue)kvPair.Value).Value);
.Where(kvPair => kvPair.Key.Value is string)
.ToDictionary(kvPair => (string)kvPair.Key.Value, kvPair => ToRawScalar(kvPair.Value));
if (dictionaryResult.Count == dictionaryValue.Elements.Count)
{
return dictionaryResult;
Expand All @@ -142,5 +162,16 @@ private object ToRawValue(LogEventPropertyValue logEventValue)
// Fall back to string rendering of the value
return logEventValue.ToString();
}

private static object ToRawScalar(LogEventPropertyValue value)
{
ScalarValue scalarValue = value as ScalarValue;
if (scalarValue != null)
{
return scalarValue.Value;
}

return value.ToString();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using Moq;
using Serilog;
using Xunit;
using System.Collections.Generic;

namespace Microsoft.Diagnostics.EventFlow.Inputs.Tests
{
Expand Down Expand Up @@ -146,5 +147,25 @@ public void HandlesDuplicatePropertyNames()
Times.Exactly(2));
}
}

[Fact]
public void RepresentsStructuresAsRawDictionaries()
{
var healthReporterMock = new Mock<IHealthReporter>();
var observer = new Mock<IObserver<EventData>>();
using (var serilogInput = new SerilogInput(healthReporterMock.Object))
using (serilogInput.Subscribe(observer.Object))
{
var logger = new LoggerConfiguration().WriteTo.Observers(events => events.Subscribe(serilogInput)).CreateLogger();

var structure = new { A = "alpha", B = "bravo" };
logger.Information("Here is {@AStructure}", structure);

observer.Verify(s => s.OnNext(It.Is<EventData>(data =>
((IDictionary<string, object>)data.Payload["AStructure"])["A"].Equals("alpha") &&
((IDictionary<string, object>)data.Payload["AStructure"])["B"].Equals("bravo")
)));
}
}
}
}

0 comments on commit 7891fed

Please sign in to comment.