-
Notifications
You must be signed in to change notification settings - Fork 20
Controlling Object Serialization
Although EventSource will only log basic types, such as int and string, ESP allows you to log entire objects. By default, ESP will convert objects to JSON strings when logging in Verbose mode. (For performance reasons, by default, ESP will not serialize objects in Informational mode.)
public class SomeData
{
public long Count;
public string Name;
}
public interface IMyLogger
{
void LogSomething(int number, SomeData data);
}
var data = new SomeData() { Count = 6, Name = "Jones" };
var log = EventSourceImplementer.GetEventSourceAs<IMyLogger>();
ConsoleEventListener listener = new ConsoleEventListener();
listener.EnableEvents((EventSource)log, EventLevel.LogAlways, (EventKeywords)(-1));
log.LogSomething(11, data);
Outputs:
SourceId : 202f3f6c-8ea0-5ddb-a393-8d22d099ca64
EventId : 1
Keywords : 1
Level : Informational
Message :
Opcode : Info
Task : 65533
Version : 0
Payload : [number : 11] [data : {"Count":6,"Name":"Jones"}]
EventName : LogSomethingInfo
Timestamp : 2013-03-04T20:03:15.0719815Z
ESP has 3 built-in object serializers:
- NullObjectSerializer - all objects are serialized as null. This disables serialization of all complex types.
- JsonObjectSerializer - all objects are serialized as a JSON string. This is the default.
- ToStringObjectSerializer - all objects are serialized by calling ToString on them.
You can override the serializer by calling EventSourceImplementer.RegisterProvider for your EventSource and passing in a different serializer. You must call RegisterProvider before instantiating an EventSource of the given type:
EventSourceImplementer.RegisterProvider<IMyLogger>(new ToStringObjectSerializer());
var data = new SomeData() { Count = 6, Name = "Jones" };
var log = EventSourceImplementer.GetEventSourceAs<IMyLogger>();
ConsoleEventListener listener = new ConsoleEventListener();
listener.EnableEvents((EventSource)log, EventLevel.LogAlways, (EventKeywords)(-1));
log.LogSomething(11, data);
This outputs:
SourceId : 202f3f6c-8ea0-5ddb-a393-8d22d099ca64
EventId : 1
Keywords : 1
Level : Informational
Message :
Opcode : Info
Task : 65533
Version : 0
Payload : [number : 11] [data : ConsoleApplication2.SomeData]
EventName : LogSomethingInfo
Timestamp : 2013-03-04T20:07:17.3171035Z
By default, the JSON serializer only serializes objects when logging in verbose mode. You can change that with the TraceSerialization Attribute. You can apply the attribute to a class, interface, method, parameter, or type of a parameter.
[TraceSerialization(Level=EventLevel.LogAlways)]
public interface IMyLogger
{
void LogSomething(int number, SomeData data);
}
You can also control serialization of objects by overriding the serialization provider or implementing a custom provider:
EventSourceImplementer.RegisterProvider<IMyLogger>(new JsonObjectSerializer(EventLevel.LogAlways));
The TraceParameterProvider can also do lots of transformations on objects when logging. You could define a serializer for an Email object with a simple global rule:
TraceParameterProvider.Default
.ForAnything().With<Email>()
.Trace(e => e.From, e => e.To);
This is really powerful. Please see Controlling Logged Data for a more thorough discussion.
For more complex serialization needs, you can implement your own serializer. For example, you may only want to serialize certain types of objects, or you may want to optimize the size of the serialized data. To do this, just implement ITraceSerializationProvider.
You only need to implement one method:
-
SerializeObject(object value, TraceSerializationContext context)
- this is called at runtime to serialize the parameter. Convert the object to a string and return it.
Example:
public class MyJsonObjectSerializer : ITraceSerializationProvider
{
public override string SerializeObject(object value, TraceSerializationContext context)
{
return JsonConvert.SerializeObject(value);
}
}
EventSourceImplementer.RegisterProvider<IMyLogger>(new MyJsonObjectSerializer());
If you write your own serialization provider, we recommend that you trap any exceptions in your provider. You don't want turning on logging to affect the behavior of your code.