public unsafe void Deserialize(EVENT_RECORD *eventRecord) { eventRecord->UserDataFixed = eventRecord->UserData; var eventRecordReader = new EventRecordReader(eventRecord); var runtimeMetadata = new RuntimeEventMetadata(eventRecord); var key = new TraceEventKey( eventRecord->ProviderId, (eventRecord->Flags & Etw.EVENT_HEADER_FLAG_CLASSIC_HEADER) != 0 ? eventRecord->Opcode : eventRecord->Id, eventRecord->Version); Action <EventRecordReader, T, EventMetadata[], RuntimeEventMetadata> action; if (this.actionTable.TryGetValue(key, out action)) { action(eventRecordReader, this.writer, this.eventMetadataTable, runtimeMetadata); } else { this.SlowLookup(eventRecord, eventRecordReader, runtimeMetadata, ref key); } }
private unsafe void SlowLookup(EVENT_RECORD *eventRecord, EventRecordReader eventRecordReader, RuntimeEventMetadata runtimeMetadata, ref TraceEventKey key) { if (this.CustomParserLookup(eventRecord, ref key)) { return; } bool isSpecialKernelTraceMetaDataEvent = false; var operand = this.BuildOperand(eventRecord, eventRecordReader, this.eventMetadataTableList.Count, ref isSpecialKernelTraceMetaDataEvent); if (operand != null) { this.eventMetadataTableList.Add(operand.Metadata); this.eventMetadataTable = this.eventMetadataTableList.ToArray(); // TODO: Need to improve this var eventRecordReaderParam = Expression.Parameter(ReaderType); var eventWriterParam = Expression.Parameter(WriterType); var eventMetadataTableParam = Expression.Parameter(EventMetadataArrayType); var runtimeMetadataParam = Expression.Parameter(RuntimeMetadataType); var parameters = new[] { eventRecordReaderParam, eventWriterParam, eventMetadataTableParam, runtimeMetadataParam }; var name = Regex.Replace(InvalidCharacters.Replace(operand.Metadata.Name, "_"), @"\s+", "_"); var body = EventTraceOperandExpressionBuilder.Build(operand, eventRecordReaderParam, eventWriterParam, eventMetadataTableParam, runtimeMetadataParam); LambdaExpression expression = Expression.Lambda <Action <EventRecordReader, T, EventMetadata[], RuntimeEventMetadata> >(body, "Read_" + name, parameters); var assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName(name), AssemblyBuilderAccess.RunAndCollect); var moduleBuilder = assemblyBuilder.DefineDynamicModule(name, name + ".dll"); var typeBuilder = moduleBuilder.DefineType(name, TypeAttributes.Public); var methodBuilder = typeBuilder.DefineMethod("Read", MethodAttributes.Public | MethodAttributes.Static, typeof(void), new[] { ReaderType, WriterType, EventMetadataArrayType, RuntimeMetadataType }); expression.CompileToMethod(methodBuilder); var action = (Action <EventRecordReader, T, EventMetadata[], RuntimeEventMetadata>)Delegate.CreateDelegate(expression.Type, typeBuilder.CreateType().GetMethod("Read")); if (isSpecialKernelTraceMetaDataEvent) { var e = (TRACE_EVENT_INFO *)eventRecord->UserDataFixed; this.actionTable.AddOrUpdate(new TraceEventKey(e->ProviderGuid, e->EventGuid == Guid.Empty ? e->Id : e->Opcode, e->Version), action); } else { this.actionTable.Add(key, action); action(eventRecordReader, this.writer, this.eventMetadataTable, runtimeMetadata); } } }
private unsafe void SlowLookup(EVENT_RECORD *eventRecord, EventRecordReader eventRecordReader, RuntimeEventMetadata runtimeMetadata, ref TraceEventKey key) { if (this.CustomParserLookup(eventRecord, ref key)) { return; } bool isSpecialKernelTraceMetaDataEvent = false; var operand = this.BuildOperand(eventRecord, eventRecordReader, this.eventMetadataTableList.Count, ref isSpecialKernelTraceMetaDataEvent); if (operand != null) { this.eventMetadataTableList.Add(operand.Metadata); this.eventMetadataTable = this.eventMetadataTableList.ToArray(); // TODO: Need to improve this var eventRecordReaderParam = Expression.Parameter(ReaderType); var eventWriterParam = Expression.Parameter(WriterType); var eventMetadataTableParam = Expression.Parameter(EventMetadataArrayType); var runtimeMetadataParam = Expression.Parameter(RuntimeMetadataType); var parameters = new[] { eventRecordReaderParam, eventWriterParam, eventMetadataTableParam, runtimeMetadataParam }; var name = Regex.Replace(InvalidCharacters.Replace(operand.Metadata.Name, "_"), @"\s+", "_"); var body = EventTraceOperandExpressionBuilder.Build(operand, eventRecordReaderParam, eventWriterParam, eventMetadataTableParam, runtimeMetadataParam); LambdaExpression expression = Expression.Lambda <Action <EventRecordReader, T, EventMetadata[], RuntimeEventMetadata> >(body, "Read_" + name, parameters); var action = (Action <EventRecordReader, T, EventMetadata[], RuntimeEventMetadata>)expression.Compile(false); if (isSpecialKernelTraceMetaDataEvent) { var e = (TRACE_EVENT_INFO *)eventRecord->UserDataFixed; this.actionTable.AddOrUpdate(new TraceEventKey(e->ProviderGuid, e->EventGuid == Guid.Empty ? e->Id : e->Opcode, e->Version), action); } else { this.actionTable.Add(key, action); action(eventRecordReader, this.writer, this.eventMetadataTable, runtimeMetadata); } } }
public void WriteEventBegin(EventMetadata metadata, RuntimeEventMetadata runtimeMetadata) { this.writer.WriteStartObject(); this.writer.WritePropertyName("Event"); this.writer.WriteStartObject(); this.writer.WritePropertyName("Timestamp"); this.writer.WriteValue(runtimeMetadata.Timestamp); this.writer.WritePropertyName("ProviderGuid"); this.writer.WriteValue(metadata.ProviderGuid); this.writer.WritePropertyName("Id"); this.writer.WriteValue(metadata.Id); this.writer.WritePropertyName("Version"); this.writer.WriteValue(metadata.Version); this.writer.WritePropertyName("ProcessId"); this.writer.WriteValue(runtimeMetadata.ProcessId); this.writer.WritePropertyName("ThreadId"); this.writer.WriteValue(runtimeMetadata.ThreadId); var activityId = runtimeMetadata.ActivityId; if (activityId != Guid.Empty) { this.writer.WritePropertyName("ActivityId"); this.writer.WriteValue(activityId); } var relatedActivityId = runtimeMetadata.RelatedActivityId; if (relatedActivityId != Guid.Empty) { this.writer.WritePropertyName("RelatedActivityId"); this.writer.WriteValue(relatedActivityId); } ulong matchId; var stacks = runtimeMetadata.GetStacks(out matchId); if (matchId != 0) { this.writer.WritePropertyName("StackMatchId"); this.writer.WriteValue(matchId); } if (stacks != null) { this.writer.WritePropertyName("Stacks"); this.writer.WriteStartArray(); for (int i = 0; i < stacks.Length; ++i) { this.writer.WriteValue(stacks[i]); } this.writer.WriteEndArray(); } this.writer.WritePropertyName("Name"); this.writer.WriteValue(metadata.Name); this.writer.WritePropertyName("Properties"); this.writer.WriteStartArray(); this.writer.WriteStartObject(); }