jonwagner / EventSourceProxy

EventSourceProxy (ESP) is the easiest way to add scalable Event Tracing for Windows (ETW) logging to your .NET program
Other
97 stars 20 forks source link

Formatting does not seem to be working #36

Closed gsteinbacher closed 9 years ago

gsteinbacher commented 9 years ago

I have a method called...

[Event(1, Message = "Job '{0}' has started manually at {1:u}", Level = EventLevel.Informational, Opcode = EventOpcode.Start)] public abstract void StartJobManually(string jobName, DateTime startTime);

When I execute the code the string that gets logged is "Job 'Transport Person' has started manually at {1:u}" (Notice the second parameter is not included). Is this something that just isn't supported or am I doing something wrong?

jonwagner commented 9 years ago

ESP just passes the values to the .NET Framework EventSource.WriteEvent. For efficiency, the message template is sent once over the event stream and the parameters are sent in a payload.

From the framework documentation for EventAttribute.Message, it doesn't look like EventSource supports format strings.

https://msdn.microsoft.com/EN-US/library/hh393455(v=VS.110,d=hv.2).aspx

Here's a stackoverflow article that explains it:

http://stackoverflow.com/questions/23574861/escape-characters-in-etw-format-strings

But sometimes you just need formatting, so...

1) You can add trace rules like:

2) or coming in 3.0.4 (probably this weekend), you can specify the format as part of a TraceAs attribute on the parameter:

    public interface IHaveMessageFormatting
    {
        [Event(1, Message = "Job '{0}'",
        Level = EventLevel.Informational, Opcode = EventOpcode.Start)]
        void StartJobManually([TraceAs(Format="{0:u}")]DateTime startTime);
    }

Happy logging!

gsteinbacher commented 9 years ago

I upgraded to the this version and got the following exception...

System.MissingMethodException: No parameterless constructor defined for this object. at System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& bNe edSecurityCheck) at System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark) at System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark) at System.Activator.CreateInstance(Type type, Boolean nonPublic) at System.Activator.CreateInstance(Type type) at System.Linq.Enumerable.WhereSelectListIterator2.MoveNext() at System.Linq.Buffer1..ctor(IEnumerable1 source) at System.Linq.Enumerable.ToArray[TSource](IEnumerable1 source) at EventSourceProxy.TypeImplementer.ValidateEventMessage(EventAttribute eventAttribute, MethodInfo method, List1 parameters) at EventSourceProxy.TypeImplementer.EmitMethodImpl(InvocationContext invocationContext, Int32& eventId, EventKeywords autoKeyword) at EventSourceProxy.TypeImplementer.ImplementType() at EventSourceProxy.EventSourceImplementer.<GetEventSource>b__1(Type t) at System.Collections.Concurrent.ConcurrentDictionary2.GetOrAdd(TKey key, Func2 valueFactory) at EventSourceProxy.EventSourceImplementer.GetEventSource(Type type) at EventSourceProxy.EventSourceImplementer.GetEventSourceAs[T]() at System.Lazy1.CreateValue() --- End of stack trace from previous location where exception was thrown --- at System.Lazy`1.get_Value() at ArcherTech.Instrumentation.ArcherEventSource.get_Log() in c:\Development\Archer\v5.5.x\ArcherTech\ArcherTech.Instrumentation\MainEventSource.cs:line 21

Line 21 of my MainEventSource is the "get" of this propertly.

public static ArcherEventSource Log { get { return Instance.Value; } }

The Instance variable is defined like this... private static readonly Lazy<ArcherEventSource> Instance = new Lazy<ArcherEventSource>(EventSourceImplementer.GetEventSourceAs<ArcherEventSource>();

I rolled back to the previous version and this exception does not occur.

jonwagner commented 9 years ago

This is due to one of the parameters not having a default constructor. This is fixed in v3.0.6.