Esempio n. 1
0
        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(
                        ref descriptor,
                        activityID,
                        childActivityID,
                        (int)(DataCollector.ThreadInstance.Finish() - descriptors),
                        (IntPtr)descriptors);
                }
                finally
                {
                    this.WriteCleanup(pins, pinCount);
                }
            }
        }
Esempio n. 2
0
        /// <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;
                }

                // 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);
                }
            }
#endif // FEATURE_MANAGED_ETW
        }
Esempio n. 3
0
        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_MANAGED_ETW
                    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);
#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,
                            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, 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);
                }
            }
        }
Esempio n. 4
0
        public IntPtr GetOrCreateEventHandle(EventProvider provider, TraceLoggingEventHandleTable eventHandleTable, EventDescriptor descriptor, TraceLoggingEventTypes eventTypes)
        {
            IntPtr eventHandle;

            if ((eventHandle = eventHandleTable[descriptor.EventId]) == IntPtr.Zero)
            {
                lock (eventHandleTable)
                {
                    if ((eventHandle = eventHandleTable[descriptor.EventId]) == IntPtr.Zero)
                    {
                        byte[]? metadataBlob = EventPipeMetadataGenerator.Instance.GenerateEventMetadata(
                            descriptor.EventId,
                            name,
                            (EventKeywords)descriptor.Keywords,
                            (EventLevel)descriptor.Level,
                            descriptor.Version,
                            eventTypes);
                        uint metadataLength = (metadataBlob != null) ? (uint)metadataBlob.Length : 0;

                        unsafe
                        {
                            fixed(byte *pMetadataBlob = metadataBlob)
                            {
                                // Define the event.
                                eventHandle = provider.m_eventProvider.DefineEventHandle(
                                    (uint)descriptor.EventId,
                                    name,
                                    descriptor.Keywords,
                                    descriptor.Version,
                                    descriptor.Level,
                                    pMetadataBlob,
                                    metadataLength);
                            }
                        }

                        // Cache the event handle.
                        eventHandleTable.SetEventHandle(descriptor.EventId, eventHandle);
                    }
                }
            }

            return(eventHandle);
        }
Esempio n. 5
0
        public IntPtr GetOrCreateEventHandle(EventProvider provider, EventDescriptor descriptor, TraceLoggingEventTypes eventTypes)
        {
            if (eventHandle == IntPtr.Zero)
            {
                lock (eventHandleCreationLock)
                {
                    if (eventHandle == IntPtr.Zero)
                    {
                        byte[] metadataBlob = EventPipeMetadataGenerator.Instance.GenerateEventMetadata(
                            descriptor.EventId,
                            name,
                            (EventKeywords)descriptor.Keywords,
                            (EventLevel)descriptor.Level,
                            descriptor.Version,
                            eventTypes);

                        unsafe
                        {
                            fixed(byte *pMetadataBlob = metadataBlob)
                            {
                                // Define the event.
                                eventHandle = provider.m_eventProvider.DefineEventHandle(
                                    (uint)descriptor.EventId,
                                    name,
                                    descriptor.Keywords,
                                    descriptor.Version,
                                    descriptor.Level,
                                    pMetadataBlob,
                                    (uint)metadataBlob.Length);
                            }
                        }
                    }
                }
            }

            return(eventHandle);
        }
        /// <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_eventHandleTable, 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>
        /// 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_eventHandleTable, 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
        }
Esempio n. 8
0
        public IntPtr GetOrCreateEventHandle(EventProvider provider, ConcurrentDictionary <int, IntPtr> eventHandleMap, EventDescriptor descriptor, TraceLoggingEventTypes eventTypes)
        {
            IntPtr eventHandle = IntPtr.Zero;

            if (!eventHandleMap.TryGetValue(descriptor.EventId, out eventHandle))
            {
                lock (eventHandleCreationLock)
                {
                    if (!eventHandleMap.TryGetValue(descriptor.EventId, out eventHandle))
                    {
                        byte[] metadataBlob = EventPipeMetadataGenerator.Instance.GenerateEventMetadata(
                            descriptor.EventId,
                            name,
                            (EventKeywords)descriptor.Keywords,
                            (EventLevel)descriptor.Level,
                            descriptor.Version,
                            eventTypes);
                        uint metadataLength = (metadataBlob != null) ? (uint)metadataBlob.Length : 0;

                        unsafe
                        {
                            fixed(byte *pMetadataBlob = metadataBlob)
                            {
                                // Define the event.
                                eventHandle = provider.m_eventProvider.DefineEventHandle(
                                    (uint)descriptor.EventId,
                                    name,
                                    descriptor.Keywords,
                                    descriptor.Version,
                                    descriptor.Level,
                                    pMetadataBlob,
                                    metadataLength);
                            }
                        }
                    }
                }
            }

            return(eventHandle);
        }