Documentation ¶
Overview ¶
Package etw allows you to receive Event Tracing for Windows (ETW) events.
etw allows you to process events from new TraceLogging providers as well as from classic (aka EventLog) providers, so you could actually listen to anything you can see in Event Viewer window.
For possible usage examples take a look at https://github.com/bi-zone/etw/tree/master/examples
Index ¶
Constants ¶
const ( TRACE_LEVEL_CRITICAL = TraceLevel(1) TRACE_LEVEL_ERROR = TraceLevel(2) TRACE_LEVEL_WARNING = TraceLevel(3) TRACE_LEVEL_INFORMATION = TraceLevel(4) TRACE_LEVEL_VERBOSE = TraceLevel(5) )
const ( // Include in the ExtendedEventInfo the security identifier (SID) of the user. EVENT_ENABLE_PROPERTY_SID = EnableProperty(0x001) // Include in the ExtendedEventInfo the terminal session identifier. EVENT_ENABLE_PROPERTY_TS_ID = EnableProperty(0x002) // Include in the ExtendedEventInfo a call stack trace for events written // using EventWrite. EVENT_ENABLE_PROPERTY_STACK_TRACE = EnableProperty(0x004) // Filters out all events that do not have a non-zero keyword specified. // By default events with 0 keywords are accepted. EVENT_ENABLE_PROPERTY_IGNORE_KEYWORD_0 = EnableProperty(0x010) // Filters out all events that are either marked as an InPrivate event or // come from a process that is marked as InPrivate. InPrivate implies that // the event or process contains some data that would be considered private // or personal. It is up to the process or event to designate itself as // InPrivate for this to work. EVENT_ENABLE_PROPERTY_EXCLUDE_INPRIVATE = EnableProperty(0x200) )
const KernelLoggerName = "NT Kernel Logger"
const KernelProviderProcess uint64 = C.EVENT_TRACE_FLAG_PROCESS
const KernelProviderTCPIP uint64 = C.EVENT_TRACE_FLAG_NETWORK_TCPIP
Variables ¶
var KernelLoggerGUID windows.GUID
Functions ¶
func KillSession ¶
KillSession forces the session with a given @name to stop. Don't having a session handle we can't shutdown it gracefully unsubscribing from all the providers first, so we just stop the session itself.
Use KillSession only to destroy session you've lost control over. If you have a session handle always prefer `.Close`.
Types ¶
type EnableProperty ¶
EnableProperty enables a property of a provider session is subscribing for.
For more info about available properties check original API reference: https://docs.microsoft.com/en-us/windows/win32/api/evntrace/ns-evntrace-enable_trace_parameters
type Event ¶
type Event struct { Header EventHeader // contains filtered or unexported fields }
Event is a single event record received from ETW provider. The only thing that is parsed implicitly is an EventHeader (which just translated from C structures mostly 1:1), all other data are parsed on-demand.
Events will be passed to the user EventCallback. It's invalid to use Event methods outside of an EventCallback.
func (*Event) EventProperties ¶
EventProperties returns a map that represents events-specific data provided by event producer. Returned data depends on the provider, event type and even provider and event versions.
The simplest (and the recommended) way to parse event data is to use TDH family of functions that render event data to the strings exactly as you can see it in the Event Viewer.
EventProperties returns a map that could be interpreted as "structure that fit inside a map". Map keys is a event data field names, map values is field values rendered to strings. So map values could be one of the following:
- `[]string` for arrays of any types;
- `map[string]interface{}` for fields that are structures;
- `string` for any other values.
Take a look at `TestParsing` for possible EventProperties values.
func (*Event) ExtendedInfo ¶
func (e *Event) ExtendedInfo() ExtendedEventInfo
ExtendedInfo extracts ExtendedEventInfo structure from native buffers of received event record.
If no ExtendedEventInfo is available inside an event record function returns the structure with all fields set to nil.
type EventCallback ¶
type EventCallback func(e *Event)
EventCallback is any function that could handle an ETW event. EventCallback is called synchronously and sequentially on every event received by Session one by one.
If EventCallback can't handle all ETW events produced, OS will handle a tricky file-based cache for you, however, it's recommended not to perform long-running tasks inside a callback.
N.B. Event pointer @e is valid ONLY inside a callback. You CAN'T copy a whole event, only EventHeader, EventProperties and ExtendedEventInfo separately.
type EventDescriptor ¶
type EventDescriptor struct { ID uint16 Version uint8 Channel uint8 Level uint8 OpCode uint8 Task uint16 Keyword uint64 }
EventDescriptor contains low-level metadata that defines received event. Most of fields could be used to refine events filtration.
For detailed information about fields values refer to EVENT_DESCRIPTOR docs: https://docs.microsoft.com/ru-ru/windows/win32/api/evntprov/ns-evntprov-event_descriptor
type EventHeader ¶
type EventHeader struct { EventDescriptor ThreadID uint32 ProcessID uint32 TimeStamp time.Time ProviderID windows.GUID ActivityID windows.GUID Flags uint16 KernelTime uint32 UserTime uint32 ProcessorTime uint64 }
EventHeader contains an information that is common for every ETW event record.
EventHeader fields is self-descriptive. If you need more info refer to the original struct docs: https://docs.microsoft.com/en-us/windows/win32/api/evntcons/ns-evntcons-event_header
func (EventHeader) HasCPUTime ¶
func (h EventHeader) HasCPUTime() bool
HasCPUTime returns true if the event has separate UserTime and KernelTime measurements. Otherwise the value of UserTime and KernelTime is meaningless and you should use ProcessorTime instead.
type EventInstanceInfo ¶
EventInstanceInfo defines the relationship between events if its provided.
type EventStackTrace ¶
EventStackTrace describes a call trace of the event occurred.
type ExistsError ¶
type ExistsError struct{ SessionName string }
ExistsError is returned by NewSession if the session name is already taken.
Having ExistsError you have an option to force kill the session:
var exists etw.ExistsError s, err = etw.NewSession(s.guid, etw.WithName(sessionName)) if errors.As(err, &exists) { err = etw.KillSession(exists.SessionName) }
func (ExistsError) Error ¶
func (e ExistsError) Error() string
type ExtendedEventInfo ¶
type ExtendedEventInfo struct { SessionID *uint32 ActivityID *windows.GUID UserSID *windows.SID InstanceInfo *EventInstanceInfo StackTrace *EventStackTrace }
ExtendedEventInfo contains additional information about received event. All ExtendedEventInfo fields are optional and are nils being not set by provider.
Presence of concrete fields is controlled by WithProperty option and an ability of event provider to set the required fields.
More info about fields is available at EVENT_HEADER_EXTENDED_DATA_ITEM.ExtType documentation: https://docs.microsoft.com/en-us/windows/win32/api/evntcons/ns-evntcons-event_header_extended_data_item
type Option ¶
type Option func(cfg *SessionOptions)
Option is any function that modifies SessionOptions. Options will be called on default config in NewSession. Subsequent options that modifies same fields will override each other.
func WithKernelEnableFlags ¶
func WithLevel ¶
func WithLevel(lvl TraceLevel) Option
WithLevel specifies a maximum level consumer is interested in. Higher levels imply that you get lower levels as well. For example, with TRACE_LEVEL_ERROR you'll get all events except ones with level critical.
func WithMatchKeywords ¶
WithMatchKeywords allows to specify keywords of receiving events. Each event has a set of keywords associated with it. That keywords are encoded as bit masks and matched with provided @anyKeyword and @allKeyword values.
A session will receive only those events whose keywords masks has ANY of @anyKeyword and ALL of @allKeyword bits sets.
For more info take a look a SessionOptions docs. To query keywords defined by specific provider identified by <GUID> try:
logman query providers <GUID>
func WithName ¶
WithName specifies a provided @name for the creating session. Further that session could be controlled from other processed by it's name, so it should be unique.
func WithProperty ¶
func WithProperty(p EnableProperty) Option
WithProperty enables additional provider feature toggled by @p. Subsequent WithProperty options will enable all provided options.
For more info about available properties check EnableProperty doc and original API reference: https://docs.microsoft.com/en-us/windows/win32/api/evntrace/ns-evntrace-enable_trace_parameters
type Session ¶
type Session struct {
// contains filtered or unexported fields
}
Session represents a Windows event tracing session that is ready to start events processing. Session subscribes to the given ETW provider only on `.Process` call, so having a Session without `.Process` called should not affect OS performance.
Session should be closed via `.Close` call to free obtained OS resources even if `.Process` has never been called.
func NewKernelSession ¶
func NewSession ¶
NewSession creates a Windows event tracing session instance. Session with no options provided is a usable session, but it could be a bit noisy. It's recommended to refine the session with level and match keywords options to get rid of unnecessary events.
You MUST call `.Close` on session after use to clear associated resources, otherwise it will leak in OS internals until system reboot.
func (*Session) Process ¶
func (s *Session) Process(cb EventCallback) error
Process starts processing of ETW events. Events will be passed to @cb synchronously and sequentially. Take a look to EventCallback documentation for more info about events processing.
N.B. Process blocks until `.Close` being called!
func (*Session) UpdateOptions ¶
UpdateOptions changes subscription parameters in runtime. The only option that can't be updated is session name. To change session name -- stop and recreate a session with new desired name.
type SessionOptions ¶
type SessionOptions struct { // Name specifies a name of ETW session being created. Further a session // could be controlled from other processed by it's name, so it should be // unique. Name string // Level represents provider-defined value that specifies the level of // detail included in the event. Higher levels imply that you get lower // levels as well. For example, with TRACE_LEVEL_ERROR you'll get all // events except ones with level critical. Check `EventDescriptor.Level` // values for current event verbosity level. Level TraceLevel // MatchAnyKeyword is a bitmask of keywords that determine the category of // events that you want the provider to write. The provider writes the // event if any of the event's keyword bits match any of the bits set in // this mask. // // If MatchAnyKeyword is not set the session will receive ALL possible // events (which is equivalent setting all 64 bits to 1). // // Passed as is to EnableTraceEx2. Refer to its remarks for more info: // https://docs.microsoft.com/en-us/windows/win32/api/evntrace/nf-evntrace-enabletraceex2#remarks MatchAnyKeyword uint64 // MatchAllKeyword is an optional bitmask that further restricts the // category of events that you want the provider to write. If the event's // keyword meets the MatchAnyKeyword condition, the provider will write the // event only if all of the bits in this mask exist in the event's keyword. // // This mask is not used if MatchAnyKeyword is zero. // // Passed as is to EnableTraceEx2. Refer to its remarks for more info: // https://docs.microsoft.com/en-us/windows/win32/api/evntrace/nf-evntrace-enabletraceex2#remarks MatchAllKeyword uint64 // EnableProperties defines a set of provider properties consumer wants to // enable. Properties adds fields to ExtendedEventInfo or asks provider to // sent more events. // // For more info about available properties check EnableProperty doc and // original API reference: // https://docs.microsoft.com/en-us/windows/win32/api/evntrace/ns-evntrace-enable_trace_parameters EnableProperties []EnableProperty KernelEnableFlags uint64 // contains filtered or unexported fields }
SessionOptions describes Session subscription options.
Most of options will be passed to EnableTraceEx2 and could be refined in its docs: https://docs.microsoft.com/en-us/windows/win32/api/evntrace/nf-evntrace-enabletraceex2
type TraceLevel ¶
TraceLevel represents provider-defined value that specifies the level of detail included in the event. Higher levels imply that you get lower levels as well.