/// <summary> /// Writes an extended event, where the values of the event are the /// combined properties of any number of values. This method is /// intended for use in advanced logging scenarios that support a /// dynamic set of event context providers. /// This method does a quick check on whether this event is enabled. /// </summary> /// <param name="eventName"> /// The name for the event. If null, the name from eventTypes is used. /// (Note that providing the event name via the name parameter is slightly /// less efficient than using the name from eventTypes.) /// </param> /// <param name="options"> /// Optional overrides for the event, such as the level, keyword, opcode, /// activityId, and relatedActivityId. Any settings not specified by options /// are obtained from eventTypes. /// </param> /// <param name="eventTypes"> /// Information about the event and the types of the values in the event. /// Must not be null. Note that the eventTypes object should be created once and /// saved. It should not be recreated for each event. /// </param> /// <param name="activityID"> /// A pointer to the activity ID GUID to log /// </param> /// <param name="childActivityID"> /// A pointer to the child activity ID to log (can be null) </param> /// <param name="values"> /// The values to include in the event. Must not be null. The number and types of /// the values must match the number and types of the fields described by the /// eventTypes parameter. /// </param> private unsafe void WriteMultiMerge( string eventName, ref EventSourceOptions options, TraceLoggingEventTypes eventTypes, Guid *activityID, Guid *childActivityID, params object[] values) { if (!this.IsEnabled()) { return; } byte level = (options.valuesSet & EventSourceOptions.levelSet) != 0 ? options.level : eventTypes.level; EventKeywords keywords = (options.valuesSet & EventSourceOptions.keywordsSet) != 0 ? options.keywords : eventTypes.keywords; if (this.IsEnabled((EventLevel)level, keywords)) { WriteMultiMergeInner(eventName, ref options, eventTypes, activityID, childActivityID, values); } }
// Token: 0x06007D15 RID: 32021 RVA: 0x00232AD4 File Offset: 0x00230CD4 internal void Write <T>(string eventName, T data) { EventSourceOptions eventSourceOptions = default(EventSourceOptions); this.Write <T>(eventName, ref eventSourceOptions, ref data); }
private unsafe void WriteImpl( string eventName, ref EventSourceOptions options, object data, Guid *pActivityId, Guid *pRelatedActivityId, TraceLoggingEventTypes eventTypes) { try { fixed(EventSourceOptions *pOptions = &options) { EventDescriptor descriptor; options.Opcode = options.IsOpcodeSet ? options.Opcode : GetOpcodeWithDefault(options.Opcode, eventName); var nameInfo = this.UpdateDescriptor(eventName, eventTypes, ref options, out descriptor); if (nameInfo == null) { return; } #if FEATURE_PERFTRACING IntPtr eventHandle = nameInfo.GetOrCreateEventHandle(m_eventPipeProvider, m_eventHandleMap, descriptor, eventTypes); Debug.Assert(eventHandle != IntPtr.Zero); #else IntPtr eventHandle = IntPtr.Zero; #endif #if FEATURE_MANAGED_ETW var pinCount = eventTypes.pinCount; var scratch = stackalloc byte[eventTypes.scratchSize]; var descriptors = stackalloc EventData[eventTypes.dataCount + 3]; for (int i = 0; i < eventTypes.dataCount + 3; i++) { descriptors[i] = default; } var pins = stackalloc GCHandle[pinCount]; for (int i = 0; i < pinCount; i++) pins[i] = default; fixed(byte * pMetadata0 = this.providerMetadata, pMetadata1 = nameInfo.nameMetadata, pMetadata2 = eventTypes.typeMetadata) { descriptors[0].SetMetadata(pMetadata0, this.providerMetadata.Length, 2); descriptors[1].SetMetadata(pMetadata1, nameInfo.nameMetadata.Length, 1); descriptors[2].SetMetadata(pMetadata2, eventTypes.typeMetadata.Length, 1); #endif // FEATURE_MANAGED_ETW #if (!ES_BUILD_PCL && !ES_BUILD_PN) System.Runtime.CompilerServices.RuntimeHelpers.PrepareConstrainedRegions(); #endif EventOpcode opcode = (EventOpcode)descriptor.Opcode; Guid activityId = Guid.Empty; Guid relatedActivityId = Guid.Empty; if (pActivityId == null && pRelatedActivityId == null && ((options.ActivityOptions & EventActivityOptions.Disable) == 0)) { if (opcode == EventOpcode.Start) { m_activityTracker.OnStart(m_name, eventName, 0, ref activityId, ref relatedActivityId, options.ActivityOptions); } else if (opcode == EventOpcode.Stop) { m_activityTracker.OnStop(m_name, eventName, 0, ref activityId); } if (activityId != Guid.Empty) { pActivityId = &activityId; } if (relatedActivityId != Guid.Empty) { pRelatedActivityId = &relatedActivityId; } } try { #if FEATURE_MANAGED_ETW DataCollector.ThreadInstance.Enable( scratch, eventTypes.scratchSize, descriptors + 3, eventTypes.dataCount, pins, pinCount); var info = eventTypes.typeInfos[0]; info.WriteData(TraceLoggingDataCollector.Instance, info.PropertyValueFactory(data)); this.WriteEventRaw( eventName, ref descriptor, eventHandle, pActivityId, pRelatedActivityId, (int)(DataCollector.ThreadInstance.Finish() - descriptors), (IntPtr)descriptors); #endif // FEATURE_MANAGED_ETW // TODO enable filtering for listeners. if (m_Dispatchers != null) { var eventData = (EventPayload)(eventTypes.typeInfos[0].GetData(data)); WriteToAllListeners(eventName, ref descriptor, nameInfo.tags, pActivityId, pRelatedActivityId, eventData); } } catch (Exception ex) { if (ex is EventSourceException) { throw; } else { ThrowEventSourceException(eventName, ex); } } #if FEATURE_MANAGED_ETW finally { this.WriteCleanup(pins, pinCount); } } #endif // FEATURE_MANAGED_ETW } } catch (Exception ex) { if (ex is EventSourceException) { throw; } else { ThrowEventSourceException(eventName, ex); } } }
/// <summary> /// Writes an extended event, where the values of the event are the /// combined properties of any number of values. This method is /// intended for use in advanced logging scenarios that support a /// dynamic set of event context providers. /// Attention: This API does not check whether the event is enabled or not. /// Please use WriteMultiMerge to avoid spending CPU cycles for events that are /// not enabled. /// </summary> /// <param name="eventName"> /// The name for the event. If null, the name from eventTypes is used. /// (Note that providing the event name via the name parameter is slightly /// less efficient than using the name from eventTypes.) /// </param> /// <param name="options"> /// Optional overrides for the event, such as the level, keyword, opcode, /// activityId, and relatedActivityId. Any settings not specified by options /// are obtained from eventTypes. /// </param> /// <param name="eventTypes"> /// Information about the event and the types of the values in the event. /// Must not be null. Note that the eventTypes object should be created once and /// saved. It should not be recreated for each event. /// </param> /// <param name="activityID"> /// A pointer to the activity ID GUID to log /// </param> /// <param name="childActivityID"> /// A pointer to the child activity ID to log (can be null) /// </param> /// <param name="values"> /// The values to include in the event. Must not be null. The number and types of /// the values must match the number and types of the fields described by the /// eventTypes parameter. /// </param> private unsafe void WriteMultiMergeInner( string eventName, ref EventSourceOptions options, TraceLoggingEventTypes eventTypes, Guid *activityID, Guid *childActivityID, params object[] values) { #if FEATURE_MANAGED_ETW int identity = 0; byte level = (options.valuesSet & EventSourceOptions.levelSet) != 0 ? options.level : eventTypes.level; byte opcode = (options.valuesSet & EventSourceOptions.opcodeSet) != 0 ? options.opcode : eventTypes.opcode; EventTags tags = (options.valuesSet & EventSourceOptions.tagsSet) != 0 ? options.tags : eventTypes.Tags; EventKeywords keywords = (options.valuesSet & EventSourceOptions.keywordsSet) != 0 ? options.keywords : eventTypes.keywords; var nameInfo = eventTypes.GetNameInfo(eventName ?? eventTypes.Name, tags); if (nameInfo == null) { return; } identity = nameInfo.identity; EventDescriptor descriptor = new EventDescriptor(identity, level, opcode, (long)keywords); #if FEATURE_PERFTRACING IntPtr eventHandle = nameInfo.GetOrCreateEventHandle(m_eventPipeProvider, m_eventHandleMap, descriptor, eventTypes); Debug.Assert(eventHandle != IntPtr.Zero); #else IntPtr eventHandle = IntPtr.Zero; #endif var pinCount = eventTypes.pinCount; var scratch = stackalloc byte[eventTypes.scratchSize]; var descriptors = stackalloc EventData[eventTypes.dataCount + 3]; for (int i = 0; i < eventTypes.dataCount + 3; i++) { descriptors[i] = default; } var pins = stackalloc GCHandle[pinCount]; for (int i = 0; i < pinCount; i++) pins[i] = default; fixed(byte * pMetadata0 = this.providerMetadata, pMetadata1 = nameInfo.nameMetadata, pMetadata2 = eventTypes.typeMetadata) { descriptors[0].SetMetadata(pMetadata0, this.providerMetadata.Length, 2); descriptors[1].SetMetadata(pMetadata1, nameInfo.nameMetadata.Length, 1); descriptors[2].SetMetadata(pMetadata2, eventTypes.typeMetadata.Length, 1); #if (!ES_BUILD_PCL && !ES_BUILD_PN) System.Runtime.CompilerServices.RuntimeHelpers.PrepareConstrainedRegions(); #endif try { DataCollector.ThreadInstance.Enable( scratch, eventTypes.scratchSize, descriptors + 3, eventTypes.dataCount, pins, pinCount); for (int i = 0; i < eventTypes.typeInfos.Length; i++) { var info = eventTypes.typeInfos[i]; info.WriteData(TraceLoggingDataCollector.Instance, info.PropertyValueFactory(values[i])); } this.WriteEventRaw( eventName, ref descriptor, eventHandle, activityID, childActivityID, (int)(DataCollector.ThreadInstance.Finish() - descriptors), (IntPtr)descriptors); } finally { this.WriteCleanup(pins, pinCount); } } #endif // FEATURE_MANAGED_ETW }
/// <summary> /// Writes an event associated with this activity. /// May only be called when the activity is in the Started state. /// </summary> /// <param name="eventName"> /// The name to use for the event. If null, the name is determined from /// data's type. /// </param> /// <param name="options"> /// The options to use for the event. /// </param> /// <param name="data">The data to include in the event.</param> internal void Write <T>(string eventName, EventSourceOptions options, T data) { Write(eventName, ref options, ref data); }
public void Write <T>(string eventName, ref EventSourceOptions options, ref T data);
public void Write(string eventName, EventSourceOptions options);
/// <summary> /// Writes an event to a arbitrary eventSource stamped with the activity ID of this activity. /// </summary> public void Write <T>(EventSource source, string?eventName, EventSourceOptions options, T data) { this.Write(source, eventName, ref options, ref data); }
private static IEventSourcing <TState, TStateKey> GetEventSourcing <TState, TStateKey>(this IServiceProvider serviceProvider, EventSourceOptions options) where TState : IState <TStateKey>, new() { var eventSourcing = serviceProvider.GetRequiredService <IEventSourcing <TState, TStateKey> >(); eventSourcing.Options = options; return(eventSourcing); }
private static IEventSourcing GetEventSourcing(this IServiceProvider serviceProvider, EventSourceOptions options) { var eventSourcing = serviceProvider.GetRequiredService <IEventSourcing>(); eventSourcing.Options = options; return(eventSourcing); }
/// <summary> /// Writes a trivial event associated with this activity. /// May only be called when the activity is in the Started state. /// </summary> /// <param name="eventName"> /// The name to use for the event. Must not be null. /// </param> /// <param name="options"> /// The options to use for the event. /// </param> public void Write(string?eventName, EventSourceOptions options) { EmptyStruct data = default; this.Write(this.eventSource, eventName, ref options, ref data); }
/// <summary> /// Writes an event associated with this activity. /// May only be called when the activity is in the Started state. /// </summary> /// <param name="eventName"> /// The name to use for the event. If null, the name is determined from /// data's type. /// </param> /// <param name="data">The data to include in the event.</param> public void Write <T>(string?eventName, T data) { EventSourceOptions options = default; this.Write(this.eventSource, eventName, ref options, ref data); }
/// <summary> /// Shortcut version see Start(string eventName, EventSourceOptions options, T data). Data payload is empty. /// </summary> public EventSourceActivity Start(string?eventName, EventSourceOptions options) { EmptyStruct data = default; return(this.Start(eventName, ref options, ref data)); }
public void Write <T> (string eventName, EventSourceOptions options, T data) { }
public void WithEventSourceOptions(EventSourceOptions options) { this.configuration._eventSourceOptions.Add(options.EventSourceName, options); this.configuration._eventSourceOptionsBySource.Add(options.SourcingFullName, options); }
/// <summary> /// Writes an event associated with this activity. /// May only be called when the activity is in the Started state. /// </summary> /// <param name="eventName"> /// The name to use for the event. If null, the name is determined from /// data's type. /// </param> /// <param name="data">The data to include in the event.</param> public void Write <T>(string?eventName, T data) { var options = new EventSourceOptions(); this.Write(this.eventSource, eventName, ref options, ref data); }
/// <summary> /// Writes a trivial event associated with this activity. /// May only be called when the activity is in the Started state. /// </summary> /// <param name="eventName"> /// The name to use for the event. Must not be null. /// </param> /// <param name="options"> /// The options to use for the event. /// </param> public void Write(string?eventName, EventSourceOptions options) { var data = new EmptyStruct(); this.Write(this.eventSource, eventName, ref options, ref data); }
/// <summary> /// Writes an event associated with this activity to the eventSource associted with this activity. /// May only be called when the activity is in the Started state. /// </summary> /// <param name="eventName"> /// The name to use for the event. If null, the name is determined from /// data's type. /// </param> /// <param name="options"> /// The options to use for the event. /// </param> /// <param name="data">The data to include in the event.</param> public void Write <T>(string eventName, EventSourceOptions options, T data) { this.Write(this.eventSource, eventName, ref options, ref data); }
/// <summary> /// Te /// </summary> /// <param name="listener"></param> private void Test_Write_T(Listener listener) { TestUtilities.CheckNoEventSourcesRunning("Start"); using (var logger = new EventSource("EventSourceName")) { var tests = new List <SubTest>(); /*************************************************************************/ tests.Add(new SubTest("Write/Basic/String", delegate() { logger.Write("Greeting", new { msg = "Hello, world!" }); }, delegate(Event evt) { Assert.Equal(logger.Name, evt.ProviderName); Assert.Equal("Greeting", evt.EventName); Assert.Equal("Hello, world!", evt.PayloadValue(0, "msg")); })); /*************************************************************************/ decimal myMoney = 300; tests.Add(new SubTest("Write/Basic/decimal", delegate() { logger.Write("Decimal", new { money = myMoney }); }, delegate(Event evt) { Assert.Equal(logger.Name, evt.ProviderName); Assert.Equal("Decimal", evt.EventName); var eventMoney = evt.PayloadValue(0, "money"); // TOD FIX ME - Fix TraceEvent to return decimal instead of double. //Assert.Equal((decimal)eventMoney, (decimal)300); })); /*************************************************************************/ DateTime now = DateTime.Now; tests.Add(new SubTest("Write/Basic/DateTime", delegate() { logger.Write("DateTime", new { nowTime = now }); }, delegate(Event evt) { Assert.Equal(logger.Name, evt.ProviderName); Assert.Equal("DateTime", evt.EventName); var eventNow = evt.PayloadValue(0, "nowTime"); Assert.Equal(eventNow, now); })); /*************************************************************************/ byte[] byteArray = { 0, 1, 2, 3 }; tests.Add(new SubTest("Write/Basic/byte[]", delegate() { logger.Write("Bytes", new { bytes = byteArray }); }, delegate(Event evt) { Assert.Equal(logger.Name, evt.ProviderName); Assert.Equal("Bytes", evt.EventName); var eventArray = evt.PayloadValue(0, "bytes"); Array.Equals(eventArray, byteArray); })); /*************************************************************************/ int?nullableInt = 12; tests.Add(new SubTest("Write/Basic/int?/12", delegate() { logger.Write("Int12", new { nInteger = nullableInt }); }, delegate(Event evt) { Assert.Equal(logger.Name, evt.ProviderName); Assert.Equal("Int12", evt.EventName); var payload = evt.PayloadValue(0, "nInteger"); Assert.Equal(nullableInt, TestUtilities.UnwrapNullable <int>(payload)); })); /*************************************************************************/ int?nullableInt2 = null; tests.Add(new SubTest("Write/Basic/int?/null", delegate() { logger.Write("IntNull", new { nInteger = nullableInt2 }); }, delegate(Event evt) { Assert.Equal(logger.Name, evt.ProviderName); Assert.Equal("IntNull", evt.EventName); var payload = evt.PayloadValue(0, "nInteger"); Assert.Equal(nullableInt2, TestUtilities.UnwrapNullable <int>(payload)); })); ///*************************************************************************/ DateTime?nullableDate = DateTime.Now; tests.Add(new SubTest("Write/Basic/DateTime?/Now", delegate() { logger.Write("DateTimeNow", new { nowTime = nullableDate }); }, delegate(Event evt) { Assert.Equal(logger.Name, evt.ProviderName); Assert.Equal("DateTimeNow", evt.EventName); var payload = evt.PayloadValue(0, "nowTime"); Assert.Equal(nullableDate, TestUtilities.UnwrapNullable <DateTime>(payload)); })); /*************************************************************************/ DateTime?nullableDate2 = null; tests.Add(new SubTest("Write/Basic/DateTime?/Null", delegate() { logger.Write("DateTimeNull", new { nowTime = nullableDate2 }); }, delegate(Event evt) { Assert.Equal(logger.Name, evt.ProviderName); Assert.Equal("DateTimeNull", evt.EventName); var payload = evt.PayloadValue(0, "nowTime"); Assert.Equal(nullableDate2, TestUtilities.UnwrapNullable <DateTime>(payload)); })); /*************************************************************************/ tests.Add(new SubTest("Write/Basic/PartBOnly", delegate() { // log just a PartB logger.Write("UserInfo", new EventSourceOptions { Keywords = EventKeywords.None }, new { _1 = new PartB_UserInfo { UserName = "******" } }); }, delegate(Event evt) { Assert.Equal(logger.Name, evt.ProviderName); Assert.Equal("UserInfo", evt.EventName); var structValue = evt.PayloadValue(0, "PartB_UserInfo"); var structValueAsDictionary = structValue as IDictionary <string, object>; Assert.NotNull(structValueAsDictionary); Assert.Equal("Someone Else", structValueAsDictionary["UserName"]); })); /*************************************************************************/ tests.Add(new SubTest("Write/Basic/PartBAndC", delegate() { // log a PartB and a PartC logger.Write("Duration", new EventSourceOptions { Keywords = EventKeywords.None }, new { _1 = new PartB_UserInfo { UserName = "******" }, msec = 10 }); }, delegate(Event evt) { Assert.Equal(logger.Name, evt.ProviderName); Assert.Equal("Duration", evt.EventName); var structValue = evt.PayloadValue(0, "PartB_UserInfo"); var structValueAsDictionary = structValue as IDictionary <string, object>; Assert.NotNull(structValueAsDictionary); Assert.Equal("Myself", structValueAsDictionary["UserName"]); Assert.Equal(10, evt.PayloadValue(1, "msec")); })); /*************************************************************************/ /*************************** ENUM TESTING *******************************/ /*************************************************************************/ /*************************************************************************/ GenerateEnumTest <Color>(ref tests, logger, Color.Green); GenerateEnumTest <ColorUInt32>(ref tests, logger, ColorUInt32.Green); GenerateEnumTest <ColorByte>(ref tests, logger, ColorByte.Green); GenerateEnumTest <ColorSByte>(ref tests, logger, ColorSByte.Green); GenerateEnumTest <ColorInt16>(ref tests, logger, ColorInt16.Green); GenerateEnumTest <ColorUInt16>(ref tests, logger, ColorUInt16.Green); GenerateEnumTest <ColorInt64>(ref tests, logger, ColorInt64.Green); GenerateEnumTest <ColorUInt64>(ref tests, logger, ColorUInt64.Green); /*************************************************************************/ /*************************** ARRAY TESTING *******************************/ /*************************************************************************/ /*************************************************************************/ GenerateArrayTest <bool>(ref tests, logger, new bool[] { false, true, false }); GenerateArrayTest <byte>(ref tests, logger, new byte[] { 1, 10, 100 }); GenerateArrayTest <sbyte>(ref tests, logger, new sbyte[] { 1, 10, 100 }); GenerateArrayTest <short>(ref tests, logger, new short[] { 1, 10, 100 }); GenerateArrayTest <ushort>(ref tests, logger, new ushort[] { 1, 10, 100 }); GenerateArrayTest <int>(ref tests, logger, new int[] { 1, 10, 100 }); GenerateArrayTest <uint>(ref tests, logger, new uint[] { 1, 10, 100 }); GenerateArrayTest <long>(ref tests, logger, new long[] { 1, 10, 100 }); GenerateArrayTest <ulong>(ref tests, logger, new ulong[] { 1, 10, 100 }); GenerateArrayTest <char>(ref tests, logger, new char[] { 'a', 'c', 'b' }); GenerateArrayTest <double>(ref tests, logger, new double[] { 1, 10, 100 }); GenerateArrayTest <float>(ref tests, logger, new float[] { 1, 10, 100 }); GenerateArrayTest <IntPtr>(ref tests, logger, new IntPtr[] { (IntPtr)1, (IntPtr)10, (IntPtr)100 }); GenerateArrayTest <UIntPtr>(ref tests, logger, new UIntPtr[] { (UIntPtr)1, (UIntPtr)10, (UIntPtr)100 }); GenerateArrayTest <Guid>(ref tests, logger, new Guid[] { Guid.Empty, new Guid("121a11ee-3bcb-49cc-b425-f4906fb14f72") }); /*************************************************************************/ /*********************** DICTIONARY TESTING ******************************/ /*************************************************************************/ var dict = new Dictionary <string, string>() { { "elem1", "10" }, { "elem2", "20" } }; var dictInt = new Dictionary <string, int>() { { "elem1", 10 }, { "elem2", 20 } }; /*************************************************************************/ tests.Add(new SubTest("Write/Dict/EventWithStringDict_C", delegate() { // log a dictionary logger.Write("EventWithStringDict_C", new { myDict = dict, s = "end" }); }, delegate(Event evt) { Assert.Equal(logger.Name, evt.ProviderName); Assert.Equal("EventWithStringDict_C", evt.EventName); var keyValues = evt.PayloadValue(0, "myDict"); IDictionary <string, object> vDict = GetDictionaryFromKeyValueArray(keyValues); Assert.Equal("10", vDict["elem1"]); Assert.Equal("20", vDict["elem2"]); Assert.Equal("end", evt.PayloadValue(1, "s")); })); /*************************************************************************/ tests.Add(new SubTest("Write/Dict/EventWithStringDict_BC", delegate() { // log a PartB and a dictionary as a PartC logger.Write("EventWithStringDict_BC", new { PartB_UserInfo = new { UserName = "******", LogTime = "Now" }, PartC_Dict = dict, s = "end" }); }, delegate(Event evt) { Assert.Equal(logger.Name, evt.ProviderName); Assert.Equal("EventWithStringDict_BC", evt.EventName); var structValue = evt.PayloadValue(0, "PartB_UserInfo"); var structValueAsDictionary = structValue as IDictionary <string, object>; Assert.NotNull(structValueAsDictionary); Assert.Equal("Me", structValueAsDictionary["UserName"]); Assert.Equal("Now", structValueAsDictionary["LogTime"]); var keyValues = evt.PayloadValue(1, "PartC_Dict"); var vDict = GetDictionaryFromKeyValueArray(keyValues); Assert.NotNull(dict); Assert.Equal("10", vDict["elem1"]); // string values. Assert.Equal("20", vDict["elem2"]); Assert.Equal("end", evt.PayloadValue(2, "s")); })); /*************************************************************************/ tests.Add(new SubTest("Write/Dict/EventWithIntDict_BC", delegate() { // log a Dict<string, int> as a PartC logger.Write("EventWithIntDict_BC", new { PartB_UserInfo = new { UserName = "******", LogTime = "Now" }, PartC_Dict = dictInt, s = "end" }); }, delegate(Event evt) { Assert.Equal(logger.Name, evt.ProviderName); Assert.Equal("EventWithIntDict_BC", evt.EventName); var structValue = evt.PayloadValue(0, "PartB_UserInfo"); var structValueAsDictionary = structValue as IDictionary <string, object>; Assert.NotNull(structValueAsDictionary); Assert.Equal("Me", structValueAsDictionary["UserName"]); Assert.Equal("Now", structValueAsDictionary["LogTime"]); var keyValues = evt.PayloadValue(1, "PartC_Dict"); var vDict = GetDictionaryFromKeyValueArray(keyValues); Assert.NotNull(vDict); Assert.Equal(10, vDict["elem1"]); // Notice they are integers, not strings. Assert.Equal(20, vDict["elem2"]); Assert.Equal("end", evt.PayloadValue(2, "s")); })); /*************************************************************************/ /**************************** Empty Event TESTING ************************/ /*************************************************************************/ tests.Add(new SubTest("Write/Basic/Message", delegate() { logger.Write("EmptyEvent"); }, delegate(Event evt) { Assert.Equal(logger.Name, evt.ProviderName); Assert.Equal("EmptyEvent", evt.EventName); })); /*************************************************************************/ /**************************** EventSourceOptions TESTING *****************/ /*************************************************************************/ EventSourceOptions options = new EventSourceOptions(); options.Level = EventLevel.LogAlways; options.Keywords = EventKeywords.All; options.Opcode = EventOpcode.Info; options.Tags = EventTags.None; tests.Add(new SubTest("Write/Basic/MessageOptions", delegate() { logger.Write("EmptyEvent", options); }, delegate(Event evt) { Assert.Equal(logger.Name, evt.ProviderName); Assert.Equal("EmptyEvent", evt.EventName); })); tests.Add(new SubTest("Write/Basic/WriteOfTWithOptios", delegate() { logger.Write("OptionsEvent", options, new { OptionsEvent = "test options!" }); }, delegate(Event evt) { Assert.Equal(logger.Name, evt.ProviderName); Assert.Equal("OptionsEvent", evt.EventName); Assert.Equal("test options!", evt.PayloadValue(0, "OptionsEvent")); })); tests.Add(new SubTest("Write/Basic/WriteOfTWithRefOptios", delegate() { var v = new { OptionsEvent = "test ref options!" }; logger.Write("RefOptionsEvent", ref options, ref v); }, delegate(Event evt) { Assert.Equal(logger.Name, evt.ProviderName); Assert.Equal("RefOptionsEvent", evt.EventName); Assert.Equal("test ref options!", evt.PayloadValue(0, "OptionsEvent")); })); tests.Add(new SubTest("Write/Basic/WriteOfTWithNullString", delegate() { string nullString = null; logger.Write("NullStringEvent", new { a = (string)null, b = nullString }); }, delegate(Event evt) { Assert.Equal(logger.Name, evt.ProviderName); Assert.Equal("NullStringEvent", evt.EventName); Assert.Equal("", evt.PayloadValue(0, "a")); Assert.Equal("", evt.PayloadValue(1, "b")); })); // This test only applies to ETW and will fail on EventListeners due to different behavior // for strings with embedded NULL characters. Test_Write_T_AddEtwTests(listener, tests, logger); Guid activityId = new Guid("00000000-0000-0000-0000-000000000001"); Guid relActivityId = new Guid("00000000-0000-0000-0000-000000000002"); tests.Add(new SubTest("Write/Basic/WriteOfTWithOptios", delegate() { var v = new { ActivityMsg = "test activity!" }; logger.Write("ActivityEvent", ref options, ref activityId, ref relActivityId, ref v); }, delegate(Event evt) { Assert.Equal(logger.Name, evt.ProviderName); Assert.Equal("ActivityEvent", evt.EventName); Assert.Equal("test activity!", evt.PayloadValue(0, "ActivityMsg")); })); // If you only wish to run one or several of the tests you can filter them here by // Uncommenting the following line. // tests = tests.FindAll(test => Regex.IsMatch(test.Name, "Write/Basic/EventII")); // Here is where we actually run tests. First test the ETW path EventTestHarness.RunTests(tests, listener, logger); } TestUtilities.CheckNoEventSourcesRunning("Stop"); }
private unsafe void WriteMultiMergeInner( string eventName, ref EventSourceOptions options, TraceLoggingEventTypes eventTypes, Guid *activityID, Guid *childActivityID, params object[] values) { int identity = 0; byte level = (options.valuesSet & EventSourceOptions.levelSet) != 0 ? options.level : eventTypes.level; byte opcode = (options.valuesSet & EventSourceOptions.opcodeSet) != 0 ? options.opcode : eventTypes.opcode; EventTags tags = (options.valuesSet & EventSourceOptions.tagsSet) != 0 ? options.tags : eventTypes.Tags; EventKeywords keywords = (options.valuesSet & EventSourceOptions.keywordsSet) != 0 ? options.keywords : eventTypes.keywords; var nameInfo = eventTypes.GetNameInfo(eventName ?? eventTypes.Name, tags); if (nameInfo == null) { return; } identity = nameInfo.identity; EventDescriptor descriptor = new EventDescriptor(identity, level, opcode, (long)keywords); var pinCount = eventTypes.pinCount; var scratch = stackalloc byte[eventTypes.scratchSize]; var descriptors = stackalloc EventData[eventTypes.dataCount + 3]; var pins = stackalloc GCHandle[pinCount]; fixed(byte * pMetadata0 = this.providerMetadata, pMetadata1 = nameInfo.nameMetadata, pMetadata2 = eventTypes.typeMetadata) { descriptors[0].SetMetadata(pMetadata0, this.providerMetadata.Length, 2); descriptors[1].SetMetadata(pMetadata1, nameInfo.nameMetadata.Length, 1); descriptors[2].SetMetadata(pMetadata2, eventTypes.typeMetadata.Length, 1); #if !ES_BUILD_PCL System.Runtime.CompilerServices.RuntimeHelpers.PrepareConstrainedRegions(); #endif try { DataCollector.ThreadInstance.Enable( scratch, eventTypes.scratchSize, descriptors + 3, eventTypes.dataCount, pins, pinCount); for (int i = 0; i < eventTypes.typeInfos.Length; i++) { eventTypes.typeInfos[i].WriteObjectData(TraceLoggingDataCollector.Instance, values[i]); } this.WriteEventRaw( eventName, ref descriptor, activityID, childActivityID, (int)(DataCollector.ThreadInstance.Finish() - descriptors), (IntPtr)descriptors); } finally { this.WriteCleanup(pins, pinCount); } } }
public void Write <T>(string eventName, ref EventSourceOptions options, ref Guid activityId, ref Guid relatedActivityId, ref T data);
internal unsafe void WriteMultiMerge( string eventName, ref EventSourceOptions options, TraceLoggingEventTypes eventTypes, Guid *activityID, Guid *childActivityID, EventData *data) { if (!this.IsEnabled()) { return; } fixed(EventSourceOptions *pOptions = &options) { EventDescriptor descriptor; var nameInfo = this.UpdateDescriptor(eventName, eventTypes, ref options, out descriptor); if (nameInfo == null) { return; } // We make a descriptor for each EventData, and because we morph strings to counted strings // we may have 2 for each arg, so we allocate enough for this. var descriptors = stackalloc EventData[eventTypes.dataCount + eventTypes.typeInfos.Length * 2 + 3]; fixed(byte * pMetadata0 = this.providerMetadata, pMetadata1 = nameInfo.nameMetadata, pMetadata2 = eventTypes.typeMetadata) { descriptors[0].SetMetadata(pMetadata0, this.providerMetadata.Length, 2); descriptors[1].SetMetadata(pMetadata1, nameInfo.nameMetadata.Length, 1); descriptors[2].SetMetadata(pMetadata2, eventTypes.typeMetadata.Length, 1); int numDescrs = 3; for (int i = 0; i < eventTypes.typeInfos.Length; i++) { // Until M3, we need to morph strings to a counted representation // When TDH supports null terminated strings, we can remove this. if (eventTypes.typeInfos[i].DataType == typeof(string)) { // Write out the size of the string descriptors[numDescrs].m_Ptr = (long)&descriptors[numDescrs + 1].m_Size; descriptors[numDescrs].m_Size = 2; numDescrs++; descriptors[numDescrs].m_Ptr = data[i].m_Ptr; descriptors[numDescrs].m_Size = data[i].m_Size - 2; // Remove the null terminator numDescrs++; } else { descriptors[numDescrs].m_Ptr = data[i].m_Ptr; descriptors[numDescrs].m_Size = data[i].m_Size; // old conventions for bool is 4 bytes, but meta-data assumes 1. if (data[i].m_Size == 4 && eventTypes.typeInfos[i].DataType == typeof(bool)) { descriptors[numDescrs].m_Size = 1; } numDescrs++; } } this.WriteEventRaw( eventName, ref descriptor, activityID, childActivityID, numDescrs, (IntPtr)descriptors); } } }
/// <summary> /// Writes an event associated with this activity. /// May only be called when the activity is in the Started state. /// </summary> /// <param name="eventName"> /// The name to use for the event. If null, the name is determined from /// data's type. /// </param> /// <param name="data">The data to include in the event.</param> internal void Write <T>(string eventName, T data) { var options = new EventSourceOptions(); Write(eventName, ref options, ref data); }
private unsafe void WriteImpl <T>( string eventName, ref EventSourceOptions options, ref T data, Guid *pActivityId, Guid *pRelatedActivityId) { try { var eventTypes = SimpleEventTypes <T> .Instance; fixed(EventSourceOptions *pOptions = &options) { EventDescriptor descriptor; options.Opcode = options.IsOpcodeSet ? options.Opcode : GetOpcodeWithDefault(options.Opcode, eventName); var nameInfo = this.UpdateDescriptor(eventName, eventTypes, ref options, out descriptor); if (nameInfo == null) { return; } var pinCount = eventTypes.pinCount; var scratch = stackalloc byte[eventTypes.scratchSize]; var descriptors = stackalloc EventData[eventTypes.dataCount + 3]; var pins = stackalloc GCHandle[pinCount]; fixed(byte * pMetadata0 = this.providerMetadata, pMetadata1 = nameInfo.nameMetadata, pMetadata2 = eventTypes.typeMetadata) { descriptors[0].SetMetadata(pMetadata0, this.providerMetadata.Length, 2); descriptors[1].SetMetadata(pMetadata1, nameInfo.nameMetadata.Length, 1); descriptors[2].SetMetadata(pMetadata2, eventTypes.typeMetadata.Length, 1); #if !ES_BUILD_PCL System.Runtime.CompilerServices.RuntimeHelpers.PrepareConstrainedRegions(); #endif EventOpcode opcode = (EventOpcode)descriptor.Opcode; Guid activityId = Guid.Empty; Guid relatedActivityId = Guid.Empty; if (pActivityId == null && pRelatedActivityId == null && ((options.ActivityOptions & EventActivityOptions.Disable) == 0)) { if (opcode == EventOpcode.Start) { m_activityTracker.OnStart(m_name, eventName, 0, ref activityId, ref relatedActivityId, options.ActivityOptions); } else if (opcode == EventOpcode.Stop) { m_activityTracker.OnStop(m_name, eventName, 0, ref activityId); } if (activityId != Guid.Empty) { pActivityId = &activityId; } if (relatedActivityId != Guid.Empty) { pRelatedActivityId = &relatedActivityId; } } try { DataCollector.ThreadInstance.Enable( scratch, eventTypes.scratchSize, descriptors + 3, eventTypes.dataCount, pins, pinCount); eventTypes.typeInfo.WriteData(TraceLoggingDataCollector.Instance, ref data); this.WriteEventRaw( eventName, ref descriptor, pActivityId, pRelatedActivityId, (int)(DataCollector.ThreadInstance.Finish() - descriptors), (IntPtr)descriptors); // if (m_Dispatchers != null) { var eventData = (EventPayload)(eventTypes.typeInfo.GetData(data)); WriteToAllListeners(eventName, ref descriptor, nameInfo.tags, pActivityId, eventData); } } catch (Exception ex) { if (ex is EventSourceException) { throw; } else { ThrowEventSourceException(eventName, ex); } } finally { this.WriteCleanup(pins, pinCount); } } } } catch (Exception ex) { if (ex is EventSourceException) { throw; } else { ThrowEventSourceException(eventName, ex); } } }
/// <summary> /// Initializes a new instance of the EventSourceActivity class that /// is attached to the specified event source. The new activity will /// not be attached to any parent activity. /// The activity is created in the Initialized state. Call Start() to /// write the activity's Start event. /// </summary> /// <param name="eventSource"> /// The event source to which the activity events should be written. /// </param> /// <param name="startStopOptions"> /// The options to use for the start and stop events of the activity. /// Note that the Opcode property will be ignored. /// </param> internal EventSourceActivity(EventSource eventSource, EventSourceOptions startStopOptions) : this(eventSource, startStopOptions, Guid.Empty) { }
/// <summary> /// Writes a Start event with the specified name and data. If the start event is not active (because the provider /// is not on or keyword-level indicates the event is off, then the returned activity is simply the 'this' pointer /// and it is effectively like start did not get called. /// /// A new activityID GUID is generated and the returned /// EventSourceActivity remembers this activity and will mark every event (including the start stop and any writes) /// with this activityID. In addition the Start activity will log a 'relatedActivityID' that was the activity /// ID before the start event. This way event processors can form a linked list of all the activities that /// caused this one (directly or indirectly). /// </summary> /// <param name="eventName"> /// The name to use for the event. It is strongly suggested that this name end in 'Start' (e.g. DownloadStart). /// If you do this, then the Stop() method will automatically replace the 'Start' suffix with a 'Stop' suffix. /// </param> /// <param name="options">Allow options (keywords, level) to be set for the write associated with this start /// These will also be used for the stop event.</param> /// <param name="data">The data to include in the event.</param> public EventSourceActivity Start <T>(string?eventName, EventSourceOptions options, T data) { return(this.Start(eventName, ref options, ref data)); }
/// <summary> /// Writes an extended event, where the values of the event have already /// been serialized in "data". /// </summary> /// <param name="eventName"> /// The name for the event. If null, the name from eventTypes is used. /// (Note that providing the event name via the name parameter is slightly /// less efficient than using the name from eventTypes.) /// </param> /// <param name="options"> /// Optional overrides for the event, such as the level, keyword, opcode, /// activityId, and relatedActivityId. Any settings not specified by options /// are obtained from eventTypes. /// </param> /// <param name="eventTypes"> /// Information about the event and the types of the values in the event. /// Must not be null. Note that the eventTypes object should be created once and /// saved. It should not be recreated for each event. /// </param> /// <param name="activityID"> /// A pointer to the activity ID GUID to log /// </param> /// <param name="childActivityID"> /// A pointer to the child activity ID to log (can be null) /// </param> /// <param name="data"> /// The previously serialized values to include in the event. Must not be null. /// The number and types of the values must match the number and types of the /// fields described by the eventTypes parameter. /// </param> internal unsafe void WriteMultiMerge( string eventName, ref EventSourceOptions options, TraceLoggingEventTypes eventTypes, Guid *activityID, Guid *childActivityID, EventData *data) { #if FEATURE_MANAGED_ETW if (!this.IsEnabled()) { return; } fixed(EventSourceOptions *pOptions = &options) { EventDescriptor descriptor; var nameInfo = this.UpdateDescriptor(eventName, eventTypes, ref options, out descriptor); if (nameInfo == null) { return; } #if FEATURE_PERFTRACING IntPtr eventHandle = nameInfo.GetOrCreateEventHandle(m_eventPipeProvider, m_eventHandleMap, descriptor, eventTypes); Debug.Assert(eventHandle != IntPtr.Zero); #else IntPtr eventHandle = IntPtr.Zero; #endif // We make a descriptor for each EventData, and because we morph strings to counted strings // we may have 2 for each arg, so we allocate enough for this. var descriptorsLength = eventTypes.dataCount + eventTypes.typeInfos.Length * 2 + 3; var descriptors = stackalloc EventData[descriptorsLength]; for (int i = 0; i < descriptorsLength; i++) { descriptors[i] = default; fixed(byte * pMetadata0 = this.providerMetadata, pMetadata1 = nameInfo.nameMetadata, pMetadata2 = eventTypes.typeMetadata) { descriptors[0].SetMetadata(pMetadata0, this.providerMetadata.Length, 2); descriptors[1].SetMetadata(pMetadata1, nameInfo.nameMetadata.Length, 1); descriptors[2].SetMetadata(pMetadata2, eventTypes.typeMetadata.Length, 1); int numDescrs = 3; for (int i = 0; i < eventTypes.typeInfos.Length; i++) { descriptors[numDescrs].m_Ptr = data[i].m_Ptr; descriptors[numDescrs].m_Size = data[i].m_Size; // old conventions for bool is 4 bytes, but meta-data assumes 1. if (data[i].m_Size == 4 && eventTypes.typeInfos[i].DataType == typeof(bool)) { descriptors[numDescrs].m_Size = 1; } numDescrs++; } this.WriteEventRaw( eventName, ref descriptor, eventHandle, activityID, childActivityID, numDescrs, (IntPtr)descriptors); } } #endif // FEATURE_MANAGED_ETW }
/// <summary> /// Shortcut version see Start(string eventName, EventSourceOptions options, T data). Data payload is empty. /// </summary> public EventSourceActivity Start(string?eventName, EventSourceOptions options) { var data = new EmptyStruct(); return(this.Start(eventName, ref options, ref data)); }
public virtual void RelatedEvent(EventLevel level, string eventName, EventMetadata metadata, Keywords keyword) { EventSourceOptions options = this.CreateDefaultOptions(level, keyword); this.WriteEvent(eventName, metadata, ref options); }
/// <summary> /// Shortcut version see Start(string eventName, EventSourceOptions options, T data) Options is empty (no keywords /// and level==Info) /// </summary> public EventSourceActivity Start <T>(string?eventName, T data) { var options = new EventSourceOptions(); return(this.Start(eventName, ref options, ref data)); }