Closed gsteinbacher closed 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!
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.Buffer
1..ctor(IEnumerable1 source) at System.Linq.Enumerable.ToArray[TSource](IEnumerable
1 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.ConcurrentDictionary
2.GetOrAdd(TKey key, Func2 valueFactory) at EventSourceProxy.EventSourceImplementer.GetEventSource(Type type) at EventSourceProxy.EventSourceImplementer.GetEventSourceAs[T]() at System.Lazy
1.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.
This is due to one of the parameters not having a default constructor. This is fixed in v3.0.6.
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?