Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 11 additions & 3 deletions src/TraceEvent/EventPipe/EventPipeMetadata.cs
Original file line number Diff line number Diff line change
Expand Up @@ -453,7 +453,7 @@ private DynamicTraceEventData.PayloadFetch ParseType(
// Fill out the payload fetch object based on the TypeCode.
switch (typeCode)
{
case EventPipeTypeCode.Boolean:
case EventPipeTypeCode.Boolean32:
{
payloadFetch.Type = typeof(bool);
payloadFetch.Size = 4; // We follow windows conventions and use 4 bytes for bool.
Expand Down Expand Up @@ -667,6 +667,13 @@ private DynamicTraceEventData.PayloadFetch ParseType(
payloadFetch = DynamicTraceEventData.PayloadFetch.DataLocPayloadFetch(offset, elementType);
break;
}
case EventPipeTypeCode.Boolean8:
{
payloadFetch.Type = typeof(bool);
payloadFetch.Size = 1;
payloadFetch.Offset = offset;
break;
}
default:
{
throw new FormatException($"Field {fieldName}: Typecode {typeCode} is not supported.");
Expand All @@ -679,7 +686,7 @@ private DynamicTraceEventData.PayloadFetch ParseType(
enum EventPipeTypeCode
{
Object = 1, // Concatenate together all of the encoded fields
Boolean = 3, // A 4-byte LE integer with value 0=false and 1=true.
Boolean32 = 3, // A 4-byte LE integer with value 0=false and 1=true.
UTF16CodeUnit = 4, // a 2-byte UTF16 code unit
SByte = 5, // 1-byte signed integer
Byte = 6, // 1-byte unsigned integer
Expand All @@ -701,7 +708,8 @@ enum EventPipeTypeCode
FixedLengthArray = 22, // New in V6: A fixed-length array of elements. The length is determined by the metadata.
UTF8CodeUnit = 23, // New in V6: A single UTF8 code unit (1 byte).
RelLoc = 24, // New in V6: An array at a relative location within the payload.
DataLoc = 25 // New in V6: An absolute data location within the payload.
DataLoc = 25, // New in V6: An absolute data location within the payload.
Boolean8 = 26 // New in V6: A 1 byte boolean with value 0=false and 1=true.
}

private void ParseOptionalMetadataV6OrGreater(ref SpanReader reader)
Expand Down
7 changes: 4 additions & 3 deletions src/TraceEvent/EventPipe/NetTraceFormat.md
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,7 @@ Type format is:
enum TypeCode
{
Object = 1, // Concatenate together all of the encoded fields
Boolean = 3, // A 4-byte LE integer with value 0=false and 1=true.
Boolean32 = 3, // A 4-byte LE integer with value 0=false and 1=true.
UTF16CodeUnit = 4, // a 2-byte UTF16 code unit (Often this is a character, but some characters need more than one code unit to encode)
SByte = 5, // 1-byte signed integer
Byte = 6, // 1-byte unsigned integer
Expand All @@ -306,9 +306,10 @@ enum TypeCode
RelLoc = 24, // New in V6: An array at a relative location within the payload.
// Format: 4 bytes where the high 16 bits are size and low 16 bits are position relative to after this field.
// Size is measured in bytes, not elements. The element type must be fixed sized.
DataLoc = 25 // New in V6: An absolute data location within the payload.
DataLoc = 25, // New in V6: An absolute data location within the payload.
// Format: 4 bytes where the high 16 bits are size and low 16 bits are position relative to start of the event parameters buffer.
// Size is measured in bytes, not elements. The element type must be fixed sized.
Boolean8 = 26 // New in V6: A 1-byte boolean where 0=false and 1=true.
}
```

Expand Down Expand Up @@ -560,7 +561,7 @@ Last, we are taking the opportunity to simplify the metadata encoding format. Th
1. Metadata rows are no longer encoded with EventHeaders.
2. Most of the metadata fields are now optional and the top-level format of a metadata row was redesigned.
3. The 2nd copy of field information that was added by V2Params in version 5 has been removed. It only existed to support adding array support in a non-breaking way and now arrays are supported in the same FieldDescriptions as all the other types.
4. New payload field types were added: VarInt, VarUInt, FixedLengthArray, UTF8CodeUnit, RelLoc, and DataLoc.
4. New payload field types were added: VarInt, VarUInt, FixedLengthArray, UTF8CodeUnit, RelLoc, DataLoc, and Boolean8. The existing Boolean type was renamed to Boolean32 to avoid ambiguity.
5. Strings in the metadata are now UTF8 rather than UTF16

#### Extended support for event labels
Expand Down
103 changes: 99 additions & 4 deletions src/TraceEvent/TraceEvent.Tests/Parsing/EventPipeParsing.cs
Original file line number Diff line number Diff line change
Expand Up @@ -980,7 +980,7 @@ public void ParseV6Metadata()
writer.WriteHeaders();
writer.WriteMetadataBlock(new EventMetadata(1, "TestProvider", "TestEvent1", 15,
new MetadataParameter("Param1", MetadataTypeCode.Int16),
new MetadataParameter("Param2", MetadataTypeCode.Boolean)),
new MetadataParameter("Param2", MetadataTypeCode.Boolean32)),
new EventMetadata(2, "TestProvider", "TestEvent2", 16),
new EventMetadata(3, "TestProvider", "TestEvent3", 17));
writer.WriteThreadBlock(w =>
Expand Down Expand Up @@ -1383,7 +1383,7 @@ public void ParseV6MetadataObjectParam()
new MetadataParameter("Param1", new ObjectMetadataType(
new MetadataParameter("NestedParam1", MetadataTypeCode.Int32),
new MetadataParameter("NestedParam2", MetadataTypeCode.Byte))),
new MetadataParameter("Param2", MetadataTypeCode.Boolean)));
new MetadataParameter("Param2", MetadataTypeCode.Boolean32)));
writer.WriteThreadBlock(w =>
{
w.WriteThreadEntry(999, 0, 0);
Expand Down Expand Up @@ -1414,6 +1414,100 @@ public void ParseV6MetadataObjectParam()
Assert.Equal(1, eventCount);
}

[Fact]
public void ParseV6MetadataBoolean8Param()
{
EventPipeWriterV6 writer = new EventPipeWriterV6();
writer.WriteHeaders();
writer.WriteMetadataBlock(new EventMetadata(1, "TestProvider", "TestEvent1", 15,
new MetadataParameter("Param1", MetadataTypeCode.Boolean8),
new MetadataParameter("Param2", MetadataTypeCode.Boolean8)));
writer.WriteThreadBlock(w =>
{
w.WriteThreadEntry(999, 0, 0);
});
writer.WriteEventBlock(w =>
{
w.WriteEventBlob(1, 999, 1, new byte[] { 1, 0 });
});
writer.WriteEndBlock();
MemoryStream stream = new MemoryStream(writer.ToArray());
EventPipeEventSource source = new EventPipeEventSource(stream);
int eventCount = 0;
source.Dynamic.All += e =>
{
eventCount++;
Assert.Equal($"TestEvent1", e.EventName);
Assert.Equal("TestProvider", e.ProviderName);
Assert.Equal(2, e.PayloadNames.Length);
Assert.Equal("Param1", e.PayloadNames[0]);
Assert.Equal("Param2", e.PayloadNames[1]);
Assert.Equal(true, e.PayloadValue(0));
Assert.Equal(false, e.PayloadValue(1));
};
source.Process();
Assert.Equal(1, eventCount);
}

[Fact]
public void ParseV6MetadataBoolean8ArrayAndObjectParam()
{
EventPipeWriterV6 writer = new EventPipeWriterV6();
writer.WriteHeaders();
writer.WriteMetadataBlock(new EventMetadata(1, "TestProvider", "TestEvent1", 15,
new MetadataParameter("Param1", new ArrayMetadataType(new MetadataType(MetadataTypeCode.Boolean8))),
new MetadataParameter("Param2", new ObjectMetadataType(
new MetadataParameter("HasValue", MetadataTypeCode.Boolean8),
new MetadataParameter("Value", new MetadataType(MetadataTypeCode.Int32))))));
writer.WriteThreadBlock(w =>
{
w.WriteThreadEntry(999, 0, 0);
});
writer.WriteEventBlock(w =>
{
// Param1 = [true, false, true]
// Param2 = { NestedParam1 = false, NestedParam2 = [false, true] }
w.WriteEventBlob(1, 999, 1, p =>
{
// Param1
p.Write((ushort)3);
p.Write((byte)1);
p.Write((byte)0);
p.Write((byte)1);
// Param2
p.Write((byte)1);
p.Write((int)184);
});
});
writer.WriteEndBlock();
MemoryStream stream = new MemoryStream(writer.ToArray());
EventPipeEventSource source = new EventPipeEventSource(stream);
int eventCount = 0;
source.Dynamic.All += e =>
{
eventCount++;
Assert.Equal($"TestEvent1", e.EventName);
Assert.Equal("TestProvider", e.ProviderName);
Assert.Equal(2, e.PayloadNames.Length);
Assert.Equal("Param1", e.PayloadNames[0]);
Assert.Equal("Param2", e.PayloadNames[1]);
// Param1
Assert.Equal(typeof(bool[]), e.PayloadValue(0).GetType());
bool[] param1 = (bool[])e.PayloadValue(0);
Assert.Equal(3, param1.Length);
Assert.True(param1[0]);
Assert.False(param1[1]);
Assert.True(param1[2]);
// Param2
var o = (DynamicTraceEventData.StructValue)e.PayloadValue(1);
Assert.Equal(2, o.Count);
Assert.True((bool)o["HasValue"]);
Assert.Equal(184, (int)o["Value"]);
};
source.Process();
Assert.Equal(1, eventCount);
}

[Fact] //V6
public void ParseV6OptionalMetadata()
{
Expand Down Expand Up @@ -2696,7 +2790,7 @@ public DataLocMetadataType(MetadataType elementType) : base(MetadataTypeCode.Dat
public enum MetadataTypeCode
{
Object = 1, // Concatenate together all of the encoded fields
Boolean = 3, // A 4-byte LE integer with value 0=false and 1=true.
Boolean32 = 3, // A 4-byte LE integer with value 0=false and 1=true.
UTF16CodeUnit = 4, // a 2-byte UTF16 code unit
SByte = 5, // 1-byte signed integer
Byte = 6, // 1-byte unsigned integer
Expand All @@ -2717,7 +2811,8 @@ public enum MetadataTypeCode
FixedLengthArray = 22, // New in V6: A fixed-length array of elements. The size is determined by the metadata.
UTF8CodeUnit = 23, // New in V6: A single UTF8 code unit (1 byte).
RelLoc = 24, // New in V6: An array at a relative location within the payload.
DataLoc = 25 // New in V6: An absolute data location within the payload.
DataLoc = 25, // New in V6: An absolute data location within the payload.
Boolean8 = 26 // New in V6: A 1-byte boolean with value 0=false and 1=true.
}

public class EventPayloadWriter
Expand Down