Add ETW support for arrays

This commit is contained in:
Kevin Parsons
2018-12-21 10:10:06 -08:00
parent 50cf0baa2f
commit 7c26c75173
3 changed files with 46 additions and 5 deletions
+8
View File
@@ -2,6 +2,7 @@ package etw
import (
"bytes"
"encoding/binary"
)
// EventData maintains a buffer which builds up the data for an ETW event. It
@@ -20,3 +21,10 @@ func (ed *EventData) AddString(data string) {
ed.buffer.WriteString(data)
ed.buffer.WriteByte(0)
}
// This is mostly added for testing purposes, and will be removed later, as we
// shouldn't take a dependency on binary.Write knowing how to marshal values
// correctly for TraceLogging.
func (ed *EventData) AddSimple(data interface{}) {
binary.Write(&ed.buffer, binary.LittleEndian, data)
}
+31 -5
View File
@@ -37,6 +37,9 @@ const (
InTypeCountedANSIString
InTypeStruct
InTypeCountedBinary
InTypeCountedArray InType = 32
InTypeArray InType = 64
)
// OutType specifies a hint to the event decoder for how the value should be
@@ -73,7 +76,7 @@ const (
OutTypeDateTimeUTC OutType = 38
)
// EventMetadata maintains a buffer which builds up the metadatadata for an ETW
// EventMetadata maintains a buffer which builds up the metadata for an ETW
// event. It needs to be paired with EventData which describes the event.
type EventMetadata struct {
buffer bytes.Buffer
@@ -91,10 +94,11 @@ func NewEventMetadata(name string) *EventMetadata {
}
type field struct {
name string
inType InType
outType OutType
tags uint32
name string
inType InType
outType OutType
tags uint32
countedArraySize uint16
}
func (em *EventMetadata) writeField(f field) {
@@ -112,6 +116,10 @@ func (em *EventMetadata) writeField(f field) {
em.writeTags(f.tags)
}
}
if f.countedArraySize != 0 {
binary.Write(&em.buffer, binary.LittleEndian, f.countedArraySize)
}
}
// writeTags writes out the tags value to the event metadata. Tags is a 28-bit
@@ -163,6 +171,24 @@ func WithTags(tags uint32) fieldOpt {
}
}
// WithCountedArray marks the field as being an array of a fixed number of
// elements. The number of elements is encoded directly into the field metadata.
func WithCountedArray(count uint16) fieldOpt {
return func(f *field) {
f.inType |= InTypeCountedArray
f.countedArraySize = count
}
}
// WithArray marks the field as being an array of a dynamic number of elements.
// The number of elements must be written as a uint16 to the data block,
// immediately preceeding the array elements.
func WithArray() fieldOpt {
return func(f *field) {
f.inType |= InTypeArray
}
}
// AddField appends a single field to the end of the event metadata buffer.
func (em *EventMetadata) AddField(name string, inType InType, opts ...fieldOpt) {
f := field{
+7
View File
@@ -59,6 +59,13 @@ func main() {
event.Data.AddString("Foo")
event.Metadata.AddField("TestField2", etw.InTypeANSIString)
event.Data.AddString("Bar")
event.Metadata.AddField("TestArray", etw.InTypeANSIString, etw.WithArray())
event.Data.AddSimple(uint16(5))
event.Data.AddString("Item1")
event.Data.AddString("Item2")
event.Data.AddString("Item3")
event.Data.AddString("Item4")
event.Data.AddString("Item5")
if err := provider.WriteEvent(event); err != nil {
fmt.Println(err)