Advanced EIF -or- Customizing EIF
For the past week I have been studying EIF.
I am in charge of building the Logging, Instrumentation and Exception Managing component for our product.
Of course, this component will be able to do EVERYTHING.
Specifically, we (the company I work in) want to be add the capability to add objects to a binary log by serializing them. For example: void Log(Level level, string Message, object data) . If this will be sent to a regular log, the data can be omitted. However, with a binary log I could create a custom reader who could deserialize the data object and reflect over its state.
I checked out a few Logging frameworks including: EIF, NSpring, log4net, and dotnetlog (theobjectguy).
I eventually picked EIF because of it's support of instrumentation and exception handling, (also a chance to get to better understand the Microsoft Application Blocks). However, the major drawback was that there is no code. Later on, when I started having problems, I had to start using Reflector and read IL.
<Begin Rant>My call Microsoft - Show me the source! This isn't part of your core products, this is needed by the programmers. Why not send it out, just like the application blocks? the dll's aren't even obfuscated anyway! <End Rant>
So I installed the EIF, learned all I could about it from documentation and Internet, and started working. My problems have begun. After fixing the configuration problems (If you mess the settings, it just doesn't work - no log or exception thrown), I tried creating a Custom Event by modifying the TraceMessageEvent:
<BEGIN Code>
[Serializable]
public class TraceMessageEvent : TraceEvent
{
private string message;
private object data;
/// <summary>
/// Gets or sets the data object to be serialized to binary log.
/// </summary>
public object Data
{
get { return data; }
set { data= value; }
}
/// <summary>
/// Gets or sets the message raised.
/// </summary>
public string Message
{
get { return (message == null ? String.Empty : message); }
set { message = value; }
}
/// <summary>
/// Raises a TraceMessageEvent to the EventSource passed as a parameter. The TraceMessageEvent is initialized with the message passed as a parameter.
/// </summary>
/// <param name="eventSource">The EventSource to raise the TraceEvent to.</param>
/// <param name="message">The message to initialize the TraceEvent with.</param>
/// <param name="data">The data object to initialize the TraceEvent with.</param>
public static void Raise(EventSource eventSource, string message, object data)
{
if (eventSource == null)
throw new ArgumentNullException("eventSource");
if (eventSource.IsEnabledForType(typeof(TraceMessageEvent)))
{
TraceMessageEvent e =
new TraceMessageEvent();
e.Message = message;
e.Data = data;
eventSource.Raise(e);
}
}
public
override bool PrepareForSerialization(EventSource eventSource, RequestContext requestContext)
{
if (!base.PrepareForSerialization(eventSource, requestContext))
return false;
return true;
}
}
<END Code>
if I change the data object to string (and all references of course), everything works fine. However, when I keep it as it is now, even when creating a custom sink, The events were not passed through to the sinks. By breakpointing the data getter it seems like an internal class called evaluator fails, probably because it doesn't know how to serialize object.
Does anyone have a lead how to make this work? I would also like to hear any comments about object serialization to a binary log.