protected virtual void GetMetadata(out Guid eventSourceGuid, out string eventSourceName, out EventDescriptor[] eventDescriptors, out byte[] manifestBytes) { // // Subclasses need to override this method, and return the data from their EventSourceAttribute and EventAttribute annotations. // // eventDescriptors needs to contain one EventDescriptor for each event; the event's ID should be the same as its index in this array. // manifestBytes is a UTF-8 encoding of the ETW manifest for the type. // // This will be implemented by an IL rewriter, so we can't make this method abstract or the initial build of the subclass would fail. // throw new InvalidOperationException(SR.EventSource_ImplementGetMetadata); }
public bool Equals(EventDescriptor other) { if ((m_id != other.m_id) || (m_version != other.m_version) || (m_channel != other.m_channel) || (m_level != other.m_level) || (m_opcode != other.m_opcode) || (m_task != other.m_task) || (m_keywords != other.m_keywords)) { return false; } return true; }
internal unsafe bool WriteEvent(ref EventDescriptor eventDescriptor, Guid* childActivityID, params object[] eventPayload) { int status = 0; if (IsEnabled(eventDescriptor.Level, eventDescriptor.Keywords)) { int argCount = 0; unsafe { argCount = eventPayload.Length; if (argCount > s_etwMaxMumberArguments) { s_returnCode = WriteEventErrorCode.TooManyArgs; return false; } uint totalEventSize = 0; int index; int stringIndex = 0; List<int> stringPosition = new List<int>(s_etwAPIMaxStringCount); List<string> dataString = new List<string>(s_etwAPIMaxStringCount); EventData* userData = stackalloc EventData[argCount]; EventData* userDataPtr = (EventData*)userData; byte* dataBuffer = stackalloc byte[s_basicTypeAllocationBufferSize * argCount]; // Assume 16 chars for non-string argument byte* currentBuffer = dataBuffer; // // The loop below goes through all the arguments and fills in the data // descriptors. For strings save the location in the dataString array. // Calculates the total size of the event by adding the data descriptor // size value set in EncodeObject method. // for (index = 0; index < eventPayload.Length; index++) { if (eventPayload[index] != null) { string isString; isString = EncodeObject(ref eventPayload[index], userDataPtr, currentBuffer); currentBuffer += s_basicTypeAllocationBufferSize; totalEventSize += userDataPtr->Size; userDataPtr++; if (isString != null) { dataString.Add(isString); stringPosition.Add(index); stringIndex++; } } else { s_returnCode = WriteEventErrorCode.NullInput; return false; } } if (totalEventSize > s_traceEventMaximumSize) { s_returnCode = WriteEventErrorCode.EventTooBig; return false; } if (stringIndex < s_etwAPIMaxStringCount) { // Fast path: at most 8 string arguments // ensure we have at least s_etwAPIMaxStringCount in dataString, so that // the "fixed" statement below works while (stringIndex < s_etwAPIMaxStringCount) { dataString.Add(null); ++stringIndex; } // // now fix any string arguments and set the pointer on the data descriptor // fixed (char* v0 = dataString[0], v1 = dataString[1], v2 = dataString[2], v3 = dataString[3], v4 = dataString[4], v5 = dataString[5], v6 = dataString[6], v7 = dataString[7]) { userDataPtr = (EventData*)userData; if (dataString[0] != null) { userDataPtr[stringPosition[0]].Ptr = (ulong)v0; } if (dataString[1] != null) { userDataPtr[stringPosition[1]].Ptr = (ulong)v1; } if (dataString[2] != null) { userDataPtr[stringPosition[2]].Ptr = (ulong)v2; } if (dataString[3] != null) { userDataPtr[stringPosition[3]].Ptr = (ulong)v3; } if (dataString[4] != null) { userDataPtr[stringPosition[4]].Ptr = (ulong)v4; } if (dataString[5] != null) { userDataPtr[stringPosition[5]].Ptr = (ulong)v5; } if (dataString[6] != null) { userDataPtr[stringPosition[6]].Ptr = (ulong)v6; } if (dataString[7] != null) { userDataPtr[stringPosition[7]].Ptr = (ulong)v7; } if (childActivityID == null) status = UnsafeNativeMethods.ManifestEtw.EventWrite(m_regHandle, ref eventDescriptor, argCount, userData); else status = UnsafeNativeMethods.ManifestEtw.EventWriteTransfer(m_regHandle, ref eventDescriptor, null, childActivityID, argCount, userData); } } else { // Slow path: use pinned handles userDataPtr = (EventData*)userData; GCHandle[] rgGCHandle = new GCHandle[stringIndex]; for (int i = 0; i < stringIndex; ++i) { rgGCHandle[i] = GCHandle.Alloc(dataString[i], GCHandleType.Pinned); fixed (char* p = dataString[i]) userDataPtr[stringPosition[i]].Ptr = (ulong)p; } if (childActivityID == null) status = UnsafeNativeMethods.ManifestEtw.EventWrite(m_regHandle, ref eventDescriptor, argCount, userData); else status = UnsafeNativeMethods.ManifestEtw.EventWriteTransfer(m_regHandle, ref eventDescriptor, null, childActivityID, argCount, userData); for (int i = 0; i < stringIndex; ++i) { rgGCHandle[i].Free(); } } } } if (status != 0) { SetLastError((int)status); return false; } return true; }
internal unsafe protected bool WriteEvent(ref EventDescriptor eventDescriptor, Guid* childActivityID, int dataCount, IntPtr data) { int status; if (childActivityID == null) { status = UnsafeNativeMethods.ManifestEtw.EventWrite(m_regHandle, ref eventDescriptor, dataCount, (EventData*)data); } else { // activity transfers are supported only for events that specify the Send or Receive opcode Contract.Assert((EventOpcode)eventDescriptor.Opcode == EventOpcode.Send || (EventOpcode)eventDescriptor.Opcode == EventOpcode.Receive); status = UnsafeNativeMethods.ManifestEtw.EventWriteTransfer(m_regHandle, ref eventDescriptor, null, childActivityID, dataCount, (EventData*)data); } if (status != 0) { SetLastError(status); return false; } return true; }
public EventMetadata(EventDescriptor descriptor, EventTags tags, bool enabledForAnyListener, bool enabledForETW, string name, string message, EventParameterType[] parameterTypes) { this.Descriptor = descriptor; this.Tags = tags; this.EnabledForAnyListener = enabledForAnyListener; this.EnabledForETW = enabledForETW; this.TriggersActivityTracking = 0; this.Name = name; this.Message = message; this.Parameters = null; this.TraceLoggingEventTypes = null; this.ActivityOptions = EventActivityOptions.None; this.ParameterTypes = parameterTypes; this.HasRelatedActivityID = false; }
/// <summary> /// Call the ETW native API EventWriteTransfer and checks for invalid argument error. /// The implementation of EventWriteTransfer on some older OSes (Windows 2008) does not accept null relatedActivityId. /// So, for these cases we will retry the call with an empty Guid. /// </summary> internal static int EventWriteTransferWrapper(long registrationHandle, ref EventDescriptor eventDescriptor, Guid* activityId, Guid* relatedActivityId, int userDataCount, EventProvider.EventData* userData) { int HResult = EventWriteTransfer(registrationHandle, ref eventDescriptor, activityId, relatedActivityId, userDataCount, userData); if (HResult == ERROR_INVALID_PARAMETER && relatedActivityId == null) { Guid emptyGuid = Guid.Empty; HResult = EventWriteTransfer(registrationHandle, ref eventDescriptor, activityId, &emptyGuid, userDataCount, userData); } return HResult; }