From 063573a7d1a106a806d1c181a6fb13b07e232596 Mon Sep 17 00:00:00 2001 From: Kevin Parsons Date: Mon, 18 Mar 2019 23:43:37 -0700 Subject: [PATCH 1/2] Reduce exported surface area of ETW package --- internal/etw/etw.go | 2 +- internal/etw/eventdata.go | 46 +++--- internal/etw/eventdescriptor.go | 24 +-- internal/etw/eventmetadata.go | 160 ++++++++++---------- internal/etw/eventopt.go | 8 +- internal/etw/fieldopt.go | 244 +++++++++++++++---------------- internal/etw/provider.go | 22 +-- internal/etw/sample/sample.go | 29 ---- internal/etw/zsyscall_windows.go | 2 +- 9 files changed, 254 insertions(+), 283 deletions(-) diff --git a/internal/etw/etw.go b/internal/etw/etw.go index 88214fb..a958b26 100644 --- a/internal/etw/etw.go +++ b/internal/etw/etw.go @@ -11,5 +11,5 @@ package etw //sys eventRegister(providerId *windows.GUID, callback uintptr, callbackContext uintptr, providerHandle *providerHandle) (win32err error) = advapi32.EventRegister //sys eventUnregister(providerHandle providerHandle) (win32err error) = advapi32.EventUnregister -//sys eventWriteTransfer(providerHandle providerHandle, descriptor *EventDescriptor, activityID *windows.GUID, relatedActivityID *windows.GUID, dataDescriptorCount uint32, dataDescriptors *eventDataDescriptor) (win32err error) = advapi32.EventWriteTransfer +//sys eventWriteTransfer(providerHandle providerHandle, descriptor *eventDescriptor, activityID *windows.GUID, relatedActivityID *windows.GUID, dataDescriptorCount uint32, dataDescriptors *eventDataDescriptor) (win32err error) = advapi32.EventWriteTransfer //sys eventSetInformation(providerHandle providerHandle, class eventInfoClass, information uintptr, length uint32) (win32err error) = advapi32.EventSetInformation diff --git a/internal/etw/eventdata.go b/internal/etw/eventdata.go index 32cf568..79dc10a 100644 --- a/internal/etw/eventdata.go +++ b/internal/etw/eventdata.go @@ -5,61 +5,61 @@ import ( "encoding/binary" ) -// EventData maintains a buffer which builds up the data for an ETW event. It +// eventData maintains a buffer which builds up the data for an ETW event. It // needs to be paired with EventMetadata which describes the event. -type EventData struct { +type eventData struct { buffer bytes.Buffer } -// Bytes returns the raw binary data containing the event data. The returned +// bytes returns the raw binary data containing the event data. The returned // value is not copied from the internal buffer, so it can be mutated by the -// EventData object after it is returned. -func (ed *EventData) Bytes() []byte { +// eventData object after it is returned. +func (ed *eventData) bytes() []byte { return ed.buffer.Bytes() } -// WriteString appends a string, including the null terminator, to the buffer. -func (ed *EventData) WriteString(data string) { +// writeString appends a string, including the null terminator, to the buffer. +func (ed *eventData) writeString(data string) { ed.buffer.WriteString(data) ed.buffer.WriteByte(0) } -// WriteInt8 appends a int8 to the buffer. -func (ed *EventData) WriteInt8(value int8) { +// writeInt8 appends a int8 to the buffer. +func (ed *eventData) writeInt8(value int8) { ed.buffer.WriteByte(uint8(value)) } -// WriteInt16 appends a int16 to the buffer. -func (ed *EventData) WriteInt16(value int16) { +// writeInt16 appends a int16 to the buffer. +func (ed *eventData) writeInt16(value int16) { binary.Write(&ed.buffer, binary.LittleEndian, value) } -// WriteInt32 appends a int32 to the buffer. -func (ed *EventData) WriteInt32(value int32) { +// writeInt32 appends a int32 to the buffer. +func (ed *eventData) writeInt32(value int32) { binary.Write(&ed.buffer, binary.LittleEndian, value) } -// WriteInt64 appends a int64 to the buffer. -func (ed *EventData) WriteInt64(value int64) { +// writeInt64 appends a int64 to the buffer. +func (ed *eventData) writeInt64(value int64) { binary.Write(&ed.buffer, binary.LittleEndian, value) } -// WriteUint8 appends a uint8 to the buffer. -func (ed *EventData) WriteUint8(value uint8) { +// writeUint8 appends a uint8 to the buffer. +func (ed *eventData) writeUint8(value uint8) { ed.buffer.WriteByte(value) } -// WriteUint16 appends a uint16 to the buffer. -func (ed *EventData) WriteUint16(value uint16) { +// writeUint16 appends a uint16 to the buffer. +func (ed *eventData) writeUint16(value uint16) { binary.Write(&ed.buffer, binary.LittleEndian, value) } -// WriteUint32 appends a uint32 to the buffer. -func (ed *EventData) WriteUint32(value uint32) { +// writeUint32 appends a uint32 to the buffer. +func (ed *eventData) writeUint32(value uint32) { binary.Write(&ed.buffer, binary.LittleEndian, value) } -// WriteUint64 appends a uint64 to the buffer. -func (ed *EventData) WriteUint64(value uint64) { +// writeUint64 appends a uint64 to the buffer. +func (ed *eventData) writeUint64(value uint64) { binary.Write(&ed.buffer, binary.LittleEndian, value) } diff --git a/internal/etw/eventdescriptor.go b/internal/etw/eventdescriptor.go index 23980b3..b16ad57 100644 --- a/internal/etw/eventdescriptor.go +++ b/internal/etw/eventdescriptor.go @@ -28,24 +28,24 @@ const ( ) // EventDescriptor represents various metadata for an ETW event. -type EventDescriptor struct { +type eventDescriptor struct { id uint16 version uint8 - Channel Channel - Level Level - Opcode uint8 - Task uint16 - Keyword uint64 + channel Channel + level Level + opcode uint8 + task uint16 + keyword uint64 } // NewEventDescriptor returns an EventDescriptor initialized for use with // TraceLogging. -func NewEventDescriptor() *EventDescriptor { +func newEventDescriptor() *eventDescriptor { // Standard TraceLogging events default to the TraceLogging channel, and // verbose level. - return &EventDescriptor{ - Channel: ChannelTraceLogging, - Level: LevelVerbose, + return &eventDescriptor{ + channel: ChannelTraceLogging, + level: LevelVerbose, } } @@ -53,7 +53,7 @@ func NewEventDescriptor() *EventDescriptor { // should uniquely identify the other event metadata (contained in // EventDescriptor, and field metadata). Only the lower 24 bits of this value // are relevant. -func (ed *EventDescriptor) Identity() uint32 { +func (ed *eventDescriptor) identity() uint32 { return (uint32(ed.version) << 16) | uint32(ed.id) } @@ -61,7 +61,7 @@ func (ed *EventDescriptor) Identity() uint32 { // should uniquely identify the other event metadata (contained in // EventDescriptor, and field metadata). Only the lower 24 bits of this value // are relevant. -func (ed *EventDescriptor) SetIdentity(identity uint32) { +func (ed *eventDescriptor) setIdentity(identity uint32) { ed.id = uint16(identity) ed.version = uint8(identity >> 16) } diff --git a/internal/etw/eventmetadata.go b/internal/etw/eventmetadata.go index e97ede0..6fdc126 100644 --- a/internal/etw/eventmetadata.go +++ b/internal/etw/eventmetadata.go @@ -5,107 +5,107 @@ import ( "encoding/binary" ) -// InType indicates the type of data contained in the ETW event. -type InType byte +// inType indicates the type of data contained in the ETW event. +type inType byte -// Various InType definitions for TraceLogging. These must match the definitions +// Various inType definitions for TraceLogging. These must match the definitions // found in TraceLoggingProvider.h in the Windows SDK. const ( - InTypeNull InType = iota - InTypeUnicodeString - InTypeANSIString - InTypeInt8 - InTypeUint8 - InTypeInt16 - InTypeUint16 - InTypeInt32 - InTypeUint32 - InTypeInt64 - InTypeUint64 - InTypeFloat - InTypeDouble - InTypeBool32 - InTypeBinary - InTypeGUID - InTypePointerUnsupported - InTypeFileTime - InTypeSystemTime - InTypeSID - InTypeHexInt32 - InTypeHexInt64 - InTypeCountedString - InTypeCountedANSIString - InTypeStruct - InTypeCountedBinary - InTypeCountedArray InType = 32 - InTypeArray InType = 64 + inTypeNull inType = iota + inTypeUnicodeString + inTypeANSIString + inTypeInt8 + inTypeUint8 + inTypeInt16 + inTypeUint16 + inTypeInt32 + inTypeUint32 + inTypeInt64 + inTypeUint64 + inTypeFloat + inTypeDouble + inTypeBool32 + inTypeBinary + inTypeGUID + inTypePointerUnsupported + inTypeFileTime + inTypeSystemTime + inTypeSID + inTypeHexInt32 + inTypeHexInt64 + inTypeCountedString + inTypeCountedANSIString + inTypeStruct + inTypeCountedBinary + inTypeCountedArray inType = 32 + inTypeArray inType = 64 ) -// OutType specifies a hint to the event decoder for how the value should be +// outType specifies a hint to the event decoder for how the value should be // formatted. -type OutType byte +type outType byte -// Various OutType definitions for TraceLogging. These must match the +// Various outType definitions for TraceLogging. These must match the // definitions found in TraceLoggingProvider.h in the Windows SDK. const ( - // OutTypeDefault indicates that the default formatting for the InType will + // outTypeDefault indicates that the default formatting for the inType will // be used by the event decoder. - OutTypeDefault OutType = iota - OutTypeNoPrint - OutTypeString - OutTypeBoolean - OutTypeHex - OutTypePID - OutTypeTID - OutTypePort - OutTypeIPv4 - OutTypeIPv6 - OutTypeSocketAddress - OutTypeXML - OutTypeJSON - OutTypeWin32Error - OutTypeNTStatus - OutTypeHResult - OutTypeFileTime - OutTypeSigned - OutTypeUnsigned - OutTypeUTF8 OutType = 35 - OutTypePKCS7WithTypeInfo OutType = 36 - OutTypeCodePointer OutType = 37 - OutTypeDateTimeUTC OutType = 38 + outTypeDefault outType = iota + outTypeNoPrint + outTypeString + outTypeBoolean + outTypeHex + outTypePID + outTypeTID + outTypePort + outTypeIPv4 + outTypeIPv6 + outTypeSocketAddress + outTypeXML + outTypeJSON + outTypeWin32Error + outTypeNTStatus + outTypeHResult + outTypeFileTime + outTypeSigned + outTypeUnsigned + outTypeUTF8 outType = 35 + outTypePKCS7WithTypeInfo outType = 36 + outTypeCodePointer outType = 37 + outTypeDateTimeUTC outType = 38 ) -// EventMetadata maintains a buffer which builds up the metadata 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 { +type eventMetadata struct { buffer bytes.Buffer } -// Bytes returns the raw binary data containing the event metadata. Before being +// bytes returns the raw binary data containing the event metadata. Before being // returned, the current size of the buffer is written to the start of the // buffer. The returned value is not copied from the internal buffer, so it can -// be mutated by the EventMetadata object after it is returned. -func (em *EventMetadata) Bytes() []byte { +// be mutated by the eventMetadata object after it is returned. +func (em *eventMetadata) bytes() []byte { // Finalize the event metadata buffer by filling in the buffer length at the // beginning. binary.LittleEndian.PutUint16(em.buffer.Bytes(), uint16(em.buffer.Len())) return em.buffer.Bytes() } -// WriteEventHeader writes the metadata for the start of an event to the buffer. +// writeEventHeader writes the metadata for the start of an event to the buffer. // This specifies the event name and tags. -func (em *EventMetadata) WriteEventHeader(name string, tags uint32) { +func (em *eventMetadata) writeEventHeader(name string, tags uint32) { binary.Write(&em.buffer, binary.LittleEndian, uint16(0)) // Length placeholder em.writeTags(tags) em.buffer.WriteString(name) em.buffer.WriteByte(0) // Null terminator for name } -func (em *EventMetadata) writeField(name string, inType InType, outType OutType, tags uint32, arrSize uint16) { +func (em *eventMetadata) writeFieldInner(name string, inType inType, outType outType, tags uint32, arrSize uint16) { em.buffer.WriteString(name) em.buffer.WriteByte(0) // Null terminator for name - if outType == OutTypeDefault && tags == 0 { + if outType == outTypeDefault && tags == 0 { em.buffer.WriteByte(byte(inType)) } else { em.buffer.WriteByte(byte(inType | 128)) @@ -129,7 +129,7 @@ func (em *EventMetadata) writeField(name string, inType InType, outType OutType, // bytes, each containing 7 bits of tag value, with the high bit set if there is // more tag data in the following byte. This allows for a more compact // representation when not all of the tag bits are needed. -func (em *EventMetadata) writeTags(tags uint32) { +func (em *eventMetadata) writeTags(tags uint32) { // Only use the top 28 bits of the tags value. tags &= 0xfffffff @@ -150,28 +150,28 @@ func (em *EventMetadata) writeTags(tags uint32) { } } -// WriteField writes the metadata for a simple field to the buffer. -func (em *EventMetadata) WriteField(name string, inType InType, outType OutType, tags uint32) { - em.writeField(name, inType, outType, tags, 0) +// writeField writes the metadata for a simple field to the buffer. +func (em *eventMetadata) writeField(name string, inType inType, outType outType, tags uint32) { + em.writeFieldInner(name, inType, outType, tags, 0) } -// WriteArray writes the metadata for an array field to the buffer. The number +// writeArray writes the metadata for an array field to the buffer. The number // of elements in the array must be written as a uint16 in the event data, // immediately preceeding the event data. -func (em *EventMetadata) WriteArray(name string, inType InType, outType OutType, tags uint32) { - em.writeField(name, inType|InTypeArray, outType, tags, 0) +func (em *eventMetadata) writeArray(name string, inType inType, outType outType, tags uint32) { + em.writeFieldInner(name, inType|inTypeArray, outType, tags, 0) } -// WriteCountedArray writes the metadata for an array field to the buffer. The +// writeCountedArray writes the metadata for an array field to the buffer. The // size of a counted array is fixed, and the size is written into the metadata // directly. -func (em *EventMetadata) WriteCountedArray(name string, count uint16, inType InType, outType OutType, tags uint32) { - em.writeField(name, inType|InTypeCountedArray, outType, tags, count) +func (em *eventMetadata) writeCountedArray(name string, count uint16, inType inType, outType outType, tags uint32) { + em.writeFieldInner(name, inType|inTypeCountedArray, outType, tags, count) } -// WriteStruct writes the metadata for a nested struct to the buffer. The struct +// writeStruct writes the metadata for a nested struct to the buffer. The struct // contains the next N fields in the metadata, where N is specified by the // fieldCount argument. -func (em *EventMetadata) WriteStruct(name string, fieldCount uint8, tags uint32) { - em.writeField(name, InTypeStruct, OutType(fieldCount), tags, 0) +func (em *eventMetadata) writeStruct(name string, fieldCount uint8, tags uint32) { + em.writeFieldInner(name, inTypeStruct, outType(fieldCount), tags, 0) } diff --git a/internal/etw/eventopt.go b/internal/etw/eventopt.go index 2c82edd..33ad6a4 100644 --- a/internal/etw/eventopt.go +++ b/internal/etw/eventopt.go @@ -5,7 +5,7 @@ import ( ) type eventOptions struct { - descriptor *EventDescriptor + descriptor *eventDescriptor activityID *windows.GUID relatedActivityID *windows.GUID tags uint32 @@ -24,7 +24,7 @@ func WithEventOpts(opts ...EventOpt) []EventOpt { // WithLevel specifies the level of the event to be written. func WithLevel(level Level) EventOpt { return func(options *eventOptions) { - options.descriptor.Level = level + options.descriptor.level = level } } @@ -32,13 +32,13 @@ func WithLevel(level Level) EventOpt { // of this option are OR'd together. func WithKeyword(keyword uint64) EventOpt { return func(options *eventOptions) { - options.descriptor.Keyword |= keyword + options.descriptor.keyword |= keyword } } func WithChannel(channel Channel) EventOpt { return func(options *eventOptions) { - options.descriptor.Channel = channel + options.descriptor.channel = channel } } diff --git a/internal/etw/fieldopt.go b/internal/etw/fieldopt.go index 5d5b425..630a321 100644 --- a/internal/etw/fieldopt.go +++ b/internal/etw/fieldopt.go @@ -7,7 +7,7 @@ import ( // FieldOpt defines the option function type that can be passed to // Provider.WriteEvent to add fields to the event. -type FieldOpt func(em *EventMetadata, ed *EventData) +type FieldOpt func(em *eventMetadata, ed *eventData) // WithFields returns the variadic arguments as a single slice. func WithFields(opts ...FieldOpt) []FieldOpt { @@ -16,46 +16,46 @@ func WithFields(opts ...FieldOpt) []FieldOpt { // BoolField adds a single bool field to the event. func BoolField(name string, value bool) FieldOpt { - return func(em *EventMetadata, ed *EventData) { - em.WriteField(name, InTypeUint8, OutTypeBoolean, 0) + return func(em *eventMetadata, ed *eventData) { + em.writeField(name, inTypeUint8, outTypeBoolean, 0) bool8 := uint8(0) if value { bool8 = uint8(1) } - ed.WriteUint8(bool8) + ed.writeUint8(bool8) } } // BoolArray adds an array of bool to the event. func BoolArray(name string, values []bool) FieldOpt { - return func(em *EventMetadata, ed *EventData) { - em.WriteArray(name, InTypeUint8, OutTypeBoolean, 0) - ed.WriteUint16(uint16(len(values))) + return func(em *eventMetadata, ed *eventData) { + em.writeArray(name, inTypeUint8, outTypeBoolean, 0) + ed.writeUint16(uint16(len(values))) for _, v := range values { bool8 := uint8(0) if v { bool8 = uint8(1) } - ed.WriteUint8(bool8) + ed.writeUint8(bool8) } } } // StringField adds a single string field to the event. func StringField(name string, value string) FieldOpt { - return func(em *EventMetadata, ed *EventData) { - em.WriteField(name, InTypeANSIString, OutTypeUTF8, 0) - ed.WriteString(value) + return func(em *eventMetadata, ed *eventData) { + em.writeField(name, inTypeANSIString, outTypeUTF8, 0) + ed.writeString(value) } } // StringArray adds an array of string to the event. func StringArray(name string, values []string) FieldOpt { - return func(em *EventMetadata, ed *EventData) { - em.WriteArray(name, InTypeANSIString, OutTypeUTF8, 0) - ed.WriteUint16(uint16(len(values))) + return func(em *eventMetadata, ed *eventData) { + em.writeArray(name, inTypeANSIString, outTypeUTF8, 0) + ed.writeUint16(uint16(len(values))) for _, v := range values { - ed.WriteString(v) + ed.writeString(v) } } } @@ -74,22 +74,22 @@ func IntField(name string, value int) FieldOpt { // IntArray adds an array of int to the event. func IntArray(name string, values []int) FieldOpt { - inType := InTypeNull - var writeItem func(*EventData, int) + inType := inTypeNull + var writeItem func(*eventData, int) switch unsafe.Sizeof(values[0]) { case 4: - inType = InTypeInt32 - writeItem = func(ed *EventData, item int) { ed.WriteInt32(int32(item)) } + inType = inTypeInt32 + writeItem = func(ed *eventData, item int) { ed.writeInt32(int32(item)) } case 8: - inType = InTypeInt64 - writeItem = func(ed *EventData, item int) { ed.WriteInt64(int64(item)) } + inType = inTypeInt64 + writeItem = func(ed *eventData, item int) { ed.writeInt64(int64(item)) } default: panic("Unsupported int size") } - return func(em *EventMetadata, ed *EventData) { - em.WriteArray(name, inType, OutTypeDefault, 0) - ed.WriteUint16(uint16(len(values))) + return func(em *eventMetadata, ed *eventData) { + em.writeArray(name, inType, outTypeDefault, 0) + ed.writeUint16(uint16(len(values))) for _, v := range values { writeItem(ed, v) } @@ -98,76 +98,76 @@ func IntArray(name string, values []int) FieldOpt { // Int8Field adds a single int8 field to the event. func Int8Field(name string, value int8) FieldOpt { - return func(em *EventMetadata, ed *EventData) { - em.WriteField(name, InTypeInt8, OutTypeDefault, 0) - ed.WriteInt8(value) + return func(em *eventMetadata, ed *eventData) { + em.writeField(name, inTypeInt8, outTypeDefault, 0) + ed.writeInt8(value) } } // Int8Array adds an array of int8 to the event. func Int8Array(name string, values []int8) FieldOpt { - return func(em *EventMetadata, ed *EventData) { - em.WriteArray(name, InTypeInt8, OutTypeDefault, 0) - ed.WriteUint16(uint16(len(values))) + return func(em *eventMetadata, ed *eventData) { + em.writeArray(name, inTypeInt8, outTypeDefault, 0) + ed.writeUint16(uint16(len(values))) for _, v := range values { - ed.WriteInt8(v) + ed.writeInt8(v) } } } // Int16Field adds a single int16 field to the event. func Int16Field(name string, value int16) FieldOpt { - return func(em *EventMetadata, ed *EventData) { - em.WriteField(name, InTypeInt16, OutTypeDefault, 0) - ed.WriteInt16(value) + return func(em *eventMetadata, ed *eventData) { + em.writeField(name, inTypeInt16, outTypeDefault, 0) + ed.writeInt16(value) } } // Int16Array adds an array of int16 to the event. func Int16Array(name string, values []int16) FieldOpt { - return func(em *EventMetadata, ed *EventData) { - em.WriteArray(name, InTypeInt16, OutTypeDefault, 0) - ed.WriteUint16(uint16(len(values))) + return func(em *eventMetadata, ed *eventData) { + em.writeArray(name, inTypeInt16, outTypeDefault, 0) + ed.writeUint16(uint16(len(values))) for _, v := range values { - ed.WriteInt16(v) + ed.writeInt16(v) } } } // Int32Field adds a single int32 field to the event. func Int32Field(name string, value int32) FieldOpt { - return func(em *EventMetadata, ed *EventData) { - em.WriteField(name, InTypeInt32, OutTypeDefault, 0) - ed.WriteInt32(value) + return func(em *eventMetadata, ed *eventData) { + em.writeField(name, inTypeInt32, outTypeDefault, 0) + ed.writeInt32(value) } } // Int32Array adds an array of int32 to the event. func Int32Array(name string, values []int32) FieldOpt { - return func(em *EventMetadata, ed *EventData) { - em.WriteArray(name, InTypeInt32, OutTypeDefault, 0) - ed.WriteUint16(uint16(len(values))) + return func(em *eventMetadata, ed *eventData) { + em.writeArray(name, inTypeInt32, outTypeDefault, 0) + ed.writeUint16(uint16(len(values))) for _, v := range values { - ed.WriteInt32(v) + ed.writeInt32(v) } } } // Int64Field adds a single int64 field to the event. func Int64Field(name string, value int64) FieldOpt { - return func(em *EventMetadata, ed *EventData) { - em.WriteField(name, InTypeInt64, OutTypeDefault, 0) - ed.WriteInt64(value) + return func(em *eventMetadata, ed *eventData) { + em.writeField(name, inTypeInt64, outTypeDefault, 0) + ed.writeInt64(value) } } // Int64Array adds an array of int64 to the event. func Int64Array(name string, values []int64) FieldOpt { - return func(em *EventMetadata, ed *EventData) { - em.WriteArray(name, InTypeInt64, OutTypeDefault, 0) - ed.WriteUint16(uint16(len(values))) + return func(em *eventMetadata, ed *eventData) { + em.writeArray(name, inTypeInt64, outTypeDefault, 0) + ed.writeUint16(uint16(len(values))) for _, v := range values { - ed.WriteInt64(v) + ed.writeInt64(v) } } } @@ -186,22 +186,22 @@ func UintField(name string, value uint) FieldOpt { // UintArray adds an array of uint to the event. func UintArray(name string, values []uint) FieldOpt { - inType := InTypeNull - var writeItem func(*EventData, uint) + inType := inTypeNull + var writeItem func(*eventData, uint) switch unsafe.Sizeof(values[0]) { case 4: - inType = InTypeUint32 - writeItem = func(ed *EventData, item uint) { ed.WriteUint32(uint32(item)) } + inType = inTypeUint32 + writeItem = func(ed *eventData, item uint) { ed.writeUint32(uint32(item)) } case 8: - inType = InTypeUint64 - writeItem = func(ed *EventData, item uint) { ed.WriteUint64(uint64(item)) } + inType = inTypeUint64 + writeItem = func(ed *eventData, item uint) { ed.writeUint64(uint64(item)) } default: panic("Unsupported uint size") } - return func(em *EventMetadata, ed *EventData) { - em.WriteArray(name, inType, OutTypeDefault, 0) - ed.WriteUint16(uint16(len(values))) + return func(em *eventMetadata, ed *eventData) { + em.writeArray(name, inType, outTypeDefault, 0) + ed.writeUint16(uint16(len(values))) for _, v := range values { writeItem(ed, v) } @@ -210,119 +210,119 @@ func UintArray(name string, values []uint) FieldOpt { // Uint8Field adds a single uint8 field to the event. func Uint8Field(name string, value uint8) FieldOpt { - return func(em *EventMetadata, ed *EventData) { - em.WriteField(name, InTypeUint8, OutTypeDefault, 0) - ed.WriteUint8(value) + return func(em *eventMetadata, ed *eventData) { + em.writeField(name, inTypeUint8, outTypeDefault, 0) + ed.writeUint8(value) } } // Uint8Array adds an array of uint8 to the event. func Uint8Array(name string, values []uint8) FieldOpt { - return func(em *EventMetadata, ed *EventData) { - em.WriteArray(name, InTypeUint8, OutTypeDefault, 0) - ed.WriteUint16(uint16(len(values))) + return func(em *eventMetadata, ed *eventData) { + em.writeArray(name, inTypeUint8, outTypeDefault, 0) + ed.writeUint16(uint16(len(values))) for _, v := range values { - ed.WriteUint8(v) + ed.writeUint8(v) } } } // Uint16Field adds a single uint16 field to the event. func Uint16Field(name string, value uint16) FieldOpt { - return func(em *EventMetadata, ed *EventData) { - em.WriteField(name, InTypeUint16, OutTypeDefault, 0) - ed.WriteUint16(value) + return func(em *eventMetadata, ed *eventData) { + em.writeField(name, inTypeUint16, outTypeDefault, 0) + ed.writeUint16(value) } } // Uint16Array adds an array of uint16 to the event. func Uint16Array(name string, values []uint16) FieldOpt { - return func(em *EventMetadata, ed *EventData) { - em.WriteArray(name, InTypeUint16, OutTypeDefault, 0) - ed.WriteUint16(uint16(len(values))) + return func(em *eventMetadata, ed *eventData) { + em.writeArray(name, inTypeUint16, outTypeDefault, 0) + ed.writeUint16(uint16(len(values))) for _, v := range values { - ed.WriteUint16(v) + ed.writeUint16(v) } } } // Uint32Field adds a single uint32 field to the event. func Uint32Field(name string, value uint32) FieldOpt { - return func(em *EventMetadata, ed *EventData) { - em.WriteField(name, InTypeUint32, OutTypeDefault, 0) - ed.WriteUint32(value) + return func(em *eventMetadata, ed *eventData) { + em.writeField(name, inTypeUint32, outTypeDefault, 0) + ed.writeUint32(value) } } // Uint32Array adds an array of uint32 to the event. func Uint32Array(name string, values []uint32) FieldOpt { - return func(em *EventMetadata, ed *EventData) { - em.WriteArray(name, InTypeUint32, OutTypeDefault, 0) - ed.WriteUint16(uint16(len(values))) + return func(em *eventMetadata, ed *eventData) { + em.writeArray(name, inTypeUint32, outTypeDefault, 0) + ed.writeUint16(uint16(len(values))) for _, v := range values { - ed.WriteUint32(v) + ed.writeUint32(v) } } } // Uint64Field adds a single uint64 field to the event. func Uint64Field(name string, value uint64) FieldOpt { - return func(em *EventMetadata, ed *EventData) { - em.WriteField(name, InTypeUint64, OutTypeDefault, 0) - ed.WriteUint64(value) + return func(em *eventMetadata, ed *eventData) { + em.writeField(name, inTypeUint64, outTypeDefault, 0) + ed.writeUint64(value) } } // Uint64Array adds an array of uint64 to the event. func Uint64Array(name string, values []uint64) FieldOpt { - return func(em *EventMetadata, ed *EventData) { - em.WriteArray(name, InTypeUint64, OutTypeDefault, 0) - ed.WriteUint16(uint16(len(values))) + return func(em *eventMetadata, ed *eventData) { + em.writeArray(name, inTypeUint64, outTypeDefault, 0) + ed.writeUint16(uint16(len(values))) for _, v := range values { - ed.WriteUint64(v) + ed.writeUint64(v) } } } // UintptrField adds a single uintptr field to the event. func UintptrField(name string, value uintptr) FieldOpt { - inType := InTypeNull - var writeItem func(*EventData, uintptr) + inType := inTypeNull + var writeItem func(*eventData, uintptr) switch unsafe.Sizeof(value) { case 4: - inType = InTypeHexInt32 - writeItem = func(ed *EventData, item uintptr) { ed.WriteUint32(uint32(item)) } + inType = inTypeHexInt32 + writeItem = func(ed *eventData, item uintptr) { ed.writeUint32(uint32(item)) } case 8: - inType = InTypeHexInt64 - writeItem = func(ed *EventData, item uintptr) { ed.WriteUint64(uint64(item)) } + inType = inTypeHexInt64 + writeItem = func(ed *eventData, item uintptr) { ed.writeUint64(uint64(item)) } default: panic("Unsupported uintptr size") } - return func(em *EventMetadata, ed *EventData) { - em.WriteField(name, inType, OutTypeDefault, 0) + return func(em *eventMetadata, ed *eventData) { + em.writeField(name, inType, outTypeDefault, 0) writeItem(ed, value) } } // UintptrArray adds an array of uintptr to the event. func UintptrArray(name string, values []uintptr) FieldOpt { - inType := InTypeNull - var writeItem func(*EventData, uintptr) + inType := inTypeNull + var writeItem func(*eventData, uintptr) switch unsafe.Sizeof(values[0]) { case 4: - inType = InTypeHexInt32 - writeItem = func(ed *EventData, item uintptr) { ed.WriteUint32(uint32(item)) } + inType = inTypeHexInt32 + writeItem = func(ed *eventData, item uintptr) { ed.writeUint32(uint32(item)) } case 8: - inType = InTypeHexInt64 - writeItem = func(ed *EventData, item uintptr) { ed.WriteUint64(uint64(item)) } + inType = inTypeHexInt64 + writeItem = func(ed *eventData, item uintptr) { ed.writeUint64(uint64(item)) } default: panic("Unsupported uintptr size") } - return func(em *EventMetadata, ed *EventData) { - em.WriteArray(name, inType, OutTypeDefault, 0) - ed.WriteUint16(uint16(len(values))) + return func(em *eventMetadata, ed *eventData) { + em.writeArray(name, inType, outTypeDefault, 0) + ed.writeUint16(uint16(len(values))) for _, v := range values { writeItem(ed, v) } @@ -331,38 +331,38 @@ func UintptrArray(name string, values []uintptr) FieldOpt { // Float32Field adds a single float32 field to the event. func Float32Field(name string, value float32) FieldOpt { - return func(em *EventMetadata, ed *EventData) { - em.WriteField(name, InTypeFloat, OutTypeDefault, 0) - ed.WriteUint32(math.Float32bits(value)) + return func(em *eventMetadata, ed *eventData) { + em.writeField(name, inTypeFloat, outTypeDefault, 0) + ed.writeUint32(math.Float32bits(value)) } } // Float32Array adds an array of float32 to the event. func Float32Array(name string, values []float32) FieldOpt { - return func(em *EventMetadata, ed *EventData) { - em.WriteArray(name, InTypeFloat, OutTypeDefault, 0) - ed.WriteUint16(uint16(len(values))) + return func(em *eventMetadata, ed *eventData) { + em.writeArray(name, inTypeFloat, outTypeDefault, 0) + ed.writeUint16(uint16(len(values))) for _, v := range values { - ed.WriteUint32(math.Float32bits(v)) + ed.writeUint32(math.Float32bits(v)) } } } // Float64Field adds a single float64 field to the event. func Float64Field(name string, value float64) FieldOpt { - return func(em *EventMetadata, ed *EventData) { - em.WriteField(name, InTypeDouble, OutTypeDefault, 0) - ed.WriteUint64(math.Float64bits(value)) + return func(em *eventMetadata, ed *eventData) { + em.writeField(name, inTypeDouble, outTypeDefault, 0) + ed.writeUint64(math.Float64bits(value)) } } // Float64Array adds an array of float64 to the event. func Float64Array(name string, values []float64) FieldOpt { - return func(em *EventMetadata, ed *EventData) { - em.WriteArray(name, InTypeDouble, OutTypeDefault, 0) - ed.WriteUint16(uint16(len(values))) + return func(em *eventMetadata, ed *eventData) { + em.writeArray(name, inTypeDouble, outTypeDefault, 0) + ed.writeUint16(uint16(len(values))) for _, v := range values { - ed.WriteUint64(math.Float64bits(v)) + ed.writeUint64(math.Float64bits(v)) } } } @@ -370,8 +370,8 @@ func Float64Array(name string, values []float64) FieldOpt { // Struct adds a nested struct to the event, the FieldOpts in the opts argument // are used to specify the fields of the struct. func Struct(name string, opts ...FieldOpt) FieldOpt { - return func(em *EventMetadata, ed *EventData) { - em.WriteStruct(name, uint8(len(opts)), 0) + return func(em *eventMetadata, ed *eventData) { + em.writeStruct(name, uint8(len(opts)), 0) for _, opt := range opts { opt(em, ed) } diff --git a/internal/etw/provider.go b/internal/etw/provider.go index 452c860..a81652f 100644 --- a/internal/etw/provider.go +++ b/internal/etw/provider.go @@ -219,9 +219,9 @@ func (provider *Provider) IsEnabledForLevelAndKeywords(level Level, keywords uin // constructed based on the EventOpt and FieldOpt values that are passed as // opts. func (provider *Provider) WriteEvent(name string, eventOpts []EventOpt, fieldOpts []FieldOpt) error { - options := eventOptions{descriptor: NewEventDescriptor()} - em := &EventMetadata{} - ed := &EventData{} + options := eventOptions{descriptor: newEventDescriptor()} + em := &eventMetadata{} + ed := &eventData{} // We need to evaluate the EventOpts first since they might change tags, and // we write out the tags before evaluating FieldOpts. @@ -229,11 +229,11 @@ func (provider *Provider) WriteEvent(name string, eventOpts []EventOpt, fieldOpt opt(&options) } - if !provider.IsEnabledForLevelAndKeywords(options.descriptor.Level, options.descriptor.Keyword) { + if !provider.IsEnabledForLevelAndKeywords(options.descriptor.level, options.descriptor.keyword) { return nil } - em.WriteEventHeader(name, options.tags) + em.writeEventHeader(name, options.tags) for _, opt := range fieldOpts { opt(em, ed) @@ -243,22 +243,22 @@ func (provider *Provider) WriteEvent(name string, eventOpts []EventOpt, fieldOpt // event metadata (e.g. for the name) so we don't need to do this check for // the metadata. dataBlobs := [][]byte{} - if len(ed.Bytes()) > 0 { - dataBlobs = [][]byte{ed.Bytes()} + if len(ed.bytes()) > 0 { + dataBlobs = [][]byte{ed.bytes()} } - return provider.WriteEventRaw(options.descriptor, nil, nil, [][]byte{em.Bytes()}, dataBlobs) + return provider.writeEventRaw(options.descriptor, nil, nil, [][]byte{em.bytes()}, dataBlobs) } -// WriteEventRaw writes a single ETW event from the provider. This function is +// writeEventRaw writes a single ETW event from the provider. This function is // less abstracted than WriteEvent, and presents a fairly direct interface to // the event writing functionality. It expects a series of event metadata and // event data blobs to be passed in, which must conform to the TraceLogging // schema. The functions on EventMetadata and EventData can help with creating // these blobs. The blobs of each type are effectively concatenated together by // the ETW infrastructure. -func (provider *Provider) WriteEventRaw( - descriptor *EventDescriptor, +func (provider *Provider) writeEventRaw( + descriptor *eventDescriptor, activityID *windows.GUID, relatedActivityID *windows.GUID, metadataBlobs [][]byte, diff --git a/internal/etw/sample/sample.go b/internal/etw/sample/sample.go index 7766eca..74acd81 100644 --- a/internal/etw/sample/sample.go +++ b/internal/etw/sample/sample.go @@ -36,7 +36,6 @@ func main() { fmt.Println("Press enter to log events") reader.ReadString('\n') - // Write using high-level API. if err := provider.WriteEvent( "TestEvent", etw.WithEventOpts( @@ -60,32 +59,4 @@ func main() { logrus.Error(err) return } - - // Write using low-level API. - descriptor := etw.NewEventDescriptor() - descriptor.Level = etw.LevelInfo - descriptor.Keyword = 0x140 - em := &etw.EventMetadata{} - ed := &etw.EventData{} - em.WriteEventHeader("TestEvent", 0) - em.WriteField("TestField", etw.InTypeANSIString, etw.OutTypeUTF8, 0) - ed.WriteString("Foo") - em.WriteField("TestField2", etw.InTypeANSIString, etw.OutTypeUTF8, 0) - ed.WriteString("Bar") - em.WriteStruct("TestStruct", 2, 0) - em.WriteField("Field1", etw.InTypeANSIString, etw.OutTypeUTF8, 0) - ed.WriteString("Value1") - em.WriteField("Field2", etw.InTypeANSIString, etw.OutTypeUTF8, 0) - ed.WriteString("Value2") - em.WriteArray("TestArray", etw.InTypeANSIString, etw.OutTypeDefault, 0) - ed.WriteUint16(5) - ed.WriteString("Item1") - ed.WriteString("Item2") - ed.WriteString("Item3") - ed.WriteString("Item4") - ed.WriteString("Item5") - if err := provider.WriteEventRaw(descriptor, nil, nil, [][]byte{em.Bytes()}, [][]byte{ed.Bytes()}); err != nil { - logrus.Error(err) - return - } } diff --git a/internal/etw/zsyscall_windows.go b/internal/etw/zsyscall_windows.go index 489a0f9..802cd69 100644 --- a/internal/etw/zsyscall_windows.go +++ b/internal/etw/zsyscall_windows.go @@ -61,7 +61,7 @@ func eventUnregister(providerHandle providerHandle) (win32err error) { return } -func eventWriteTransfer(providerHandle providerHandle, descriptor *EventDescriptor, activityID *windows.GUID, relatedActivityID *windows.GUID, dataDescriptorCount uint32, dataDescriptors *eventDataDescriptor) (win32err error) { +func eventWriteTransfer(providerHandle providerHandle, descriptor *eventDescriptor, activityID *windows.GUID, relatedActivityID *windows.GUID, dataDescriptorCount uint32, dataDescriptors *eventDataDescriptor) (win32err error) { r0, _, _ := syscall.Syscall6(procEventWriteTransfer.Addr(), 6, uintptr(providerHandle), uintptr(unsafe.Pointer(descriptor)), uintptr(unsafe.Pointer(activityID)), uintptr(unsafe.Pointer(relatedActivityID)), uintptr(dataDescriptorCount), uintptr(unsafe.Pointer(dataDescriptors))) if r0 != 0 { win32err = syscall.Errno(r0) From ce5a3739bc81a855417e39b5901818054aececae Mon Sep 17 00:00:00 2001 From: Kevin Parsons Date: Mon, 18 Mar 2019 23:45:39 -0700 Subject: [PATCH 2/2] Export etw package --- {internal => pkg}/etw/etw.go | 0 {internal => pkg}/etw/eventdata.go | 0 {internal => pkg}/etw/eventdatadescriptor.go | 0 {internal => pkg}/etw/eventdescriptor.go | 0 {internal => pkg}/etw/eventmetadata.go | 0 {internal => pkg}/etw/eventopt.go | 0 {internal => pkg}/etw/fieldopt.go | 0 {internal => pkg}/etw/provider.go | 0 {internal => pkg}/etw/providerglobal.go | 0 {internal => pkg}/etw/ptr64_32.go | 0 {internal => pkg}/etw/ptr64_64.go | 0 {internal => pkg}/etw/sample/sample.go | 0 {internal => pkg}/etw/zsyscall_windows.go | 0 pkg/etwlogrus/hook.go | 2 +- pkg/etwlogrus/hook_test.go | 2 +- 15 files changed, 2 insertions(+), 2 deletions(-) rename {internal => pkg}/etw/etw.go (100%) rename {internal => pkg}/etw/eventdata.go (100%) rename {internal => pkg}/etw/eventdatadescriptor.go (100%) rename {internal => pkg}/etw/eventdescriptor.go (100%) rename {internal => pkg}/etw/eventmetadata.go (100%) rename {internal => pkg}/etw/eventopt.go (100%) rename {internal => pkg}/etw/fieldopt.go (100%) rename {internal => pkg}/etw/provider.go (100%) rename {internal => pkg}/etw/providerglobal.go (100%) rename {internal => pkg}/etw/ptr64_32.go (100%) rename {internal => pkg}/etw/ptr64_64.go (100%) rename {internal => pkg}/etw/sample/sample.go (100%) rename {internal => pkg}/etw/zsyscall_windows.go (100%) diff --git a/internal/etw/etw.go b/pkg/etw/etw.go similarity index 100% rename from internal/etw/etw.go rename to pkg/etw/etw.go diff --git a/internal/etw/eventdata.go b/pkg/etw/eventdata.go similarity index 100% rename from internal/etw/eventdata.go rename to pkg/etw/eventdata.go diff --git a/internal/etw/eventdatadescriptor.go b/pkg/etw/eventdatadescriptor.go similarity index 100% rename from internal/etw/eventdatadescriptor.go rename to pkg/etw/eventdatadescriptor.go diff --git a/internal/etw/eventdescriptor.go b/pkg/etw/eventdescriptor.go similarity index 100% rename from internal/etw/eventdescriptor.go rename to pkg/etw/eventdescriptor.go diff --git a/internal/etw/eventmetadata.go b/pkg/etw/eventmetadata.go similarity index 100% rename from internal/etw/eventmetadata.go rename to pkg/etw/eventmetadata.go diff --git a/internal/etw/eventopt.go b/pkg/etw/eventopt.go similarity index 100% rename from internal/etw/eventopt.go rename to pkg/etw/eventopt.go diff --git a/internal/etw/fieldopt.go b/pkg/etw/fieldopt.go similarity index 100% rename from internal/etw/fieldopt.go rename to pkg/etw/fieldopt.go diff --git a/internal/etw/provider.go b/pkg/etw/provider.go similarity index 100% rename from internal/etw/provider.go rename to pkg/etw/provider.go diff --git a/internal/etw/providerglobal.go b/pkg/etw/providerglobal.go similarity index 100% rename from internal/etw/providerglobal.go rename to pkg/etw/providerglobal.go diff --git a/internal/etw/ptr64_32.go b/pkg/etw/ptr64_32.go similarity index 100% rename from internal/etw/ptr64_32.go rename to pkg/etw/ptr64_32.go diff --git a/internal/etw/ptr64_64.go b/pkg/etw/ptr64_64.go similarity index 100% rename from internal/etw/ptr64_64.go rename to pkg/etw/ptr64_64.go diff --git a/internal/etw/sample/sample.go b/pkg/etw/sample/sample.go similarity index 100% rename from internal/etw/sample/sample.go rename to pkg/etw/sample/sample.go diff --git a/internal/etw/zsyscall_windows.go b/pkg/etw/zsyscall_windows.go similarity index 100% rename from internal/etw/zsyscall_windows.go rename to pkg/etw/zsyscall_windows.go diff --git a/pkg/etwlogrus/hook.go b/pkg/etwlogrus/hook.go index fe0835b..0a067df 100644 --- a/pkg/etwlogrus/hook.go +++ b/pkg/etwlogrus/hook.go @@ -4,7 +4,7 @@ import ( "fmt" "reflect" - "github.com/Microsoft/go-winio/internal/etw" + "github.com/Microsoft/go-winio/pkg/etw" "github.com/sirupsen/logrus" ) diff --git a/pkg/etwlogrus/hook_test.go b/pkg/etwlogrus/hook_test.go index 3653cdc..26193d2 100644 --- a/pkg/etwlogrus/hook_test.go +++ b/pkg/etwlogrus/hook_test.go @@ -1,7 +1,7 @@ package etwlogrus import ( - "github.com/Microsoft/go-winio/internal/etw" + "github.com/Microsoft/go-winio/pkg/etw" "testing" )