mirror of
https://github.com/rwinkhart/go-winio.git
synced 2026-08-29 21:36:48 -04:00
Add ETW support for arrays
This commit is contained in:
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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{
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user