Skip to content

Commit

Permalink
Add caching of event metadata handles and the system render context f…
Browse files Browse the repository at this point in the history
…or wineventlog API
  • Loading branch information
andrewkroh committed Jan 29, 2016
1 parent ea19759 commit e4c46cd
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 5 deletions.
32 changes: 29 additions & 3 deletions winlogbeat/eventlog/wineventlog.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@ import (
"fmt"

"github.com/elastic/beats/libbeat/logp"
"github.com/elastic/beats/winlogbeat/sys/eventlogging"
sys "github.com/elastic/beats/winlogbeat/sys/wineventlog"
"golang.org/x/sys/windows"
)

const (
// defaultMaxNumRead is the maximum number of event Read will return.
defaultMaxNumRead = 50
defaultMaxNumRead = 100

// renderBufferSize is the size in bytes of the buffer used to render events.
renderBufferSize = 1 << 14
Expand All @@ -33,7 +34,9 @@ type winEventLog struct {
subscription sys.EvtHandle // Handle to the subscription.
maxRead int // Maximum number returned in one Read.

renderBuf []byte // Buffer used for rendering event.
renderBuf []byte // Buffer used for rendering event.
systemCtx sys.EvtHandle // System render context.
cache *messageFilesCache // Cached mapping of source name to event message file handles.

logPrefix string // String to prefix on log messages.
}
Expand Down Expand Up @@ -91,7 +94,7 @@ func (l *winEventLog) Read() ([]Record, error) {

var records []Record
for _, h := range handles {
e, err := sys.RenderEvent(h, 0, 0, l.renderBuf, nil)
e, err := sys.RenderEvent(h, l.systemCtx, 0, l.renderBuf, l.cache.get)
if err != nil {
logp.Err("%s Dropping event with rendering error. %v", l.logPrefix, err)
continue
Expand Down Expand Up @@ -138,11 +141,34 @@ func (l *winEventLog) Close() error {
// newWinEventLog creates and returns a new EventLog for reading event logs
// using the Windows Event Log.
func newWinEventLog(c Config) (EventLog, error) {
eventMetadataHandle := func(providerName, sourceName string) eventlogging.MessageFiles {
mf := eventlogging.MessageFiles{SourceName: sourceName}
h, err := sys.OpenPublisherMetadata(0, providerName, 0)
if err != nil {
mf.Err = err
return mf
}

mf.Handles = []eventlogging.FileHandle{eventlogging.FileHandle{Handle: uintptr(h)}}
return mf
}

freeHandle := func(handle uintptr) error {
return sys.Close(sys.EvtHandle(handle))
}

ctx, err := sys.CreateRenderContext(nil, sys.EvtRenderContextSystem)
if err != nil {
return nil, err
}

return &winEventLog{
channelName: c.Name,
remoteServer: c.RemoteAddress,
maxRead: defaultMaxNumRead,
renderBuf: make([]byte, renderBufferSize),
systemCtx: ctx,
cache: newMessageFilesCache(c.Name, eventMetadataHandle, freeHandle),
logPrefix: fmt.Sprintf("WinEventLog[%s]", c.Name),
}, nil
}
Expand Down
20 changes: 18 additions & 2 deletions winlogbeat/sys/wineventlog/wineventlog_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ func RenderEvent(
systemContext EvtHandle,
lang uint32,
renderBuf []byte,
pubHandleProvider func(string) uintptr,
pubHandleProvider func(string) eventlogging.MessageFiles,
) (Event, error) {
var err error

Expand Down Expand Up @@ -187,7 +187,12 @@ func RenderEvent(

var publisherHandle uintptr
if pubHandleProvider != nil {
publisherHandle = pubHandleProvider(e.ProviderName)
messageFiles := pubHandleProvider(e.ProviderName)
if messageFiles.Err == nil {
// There is only ever a single handle when using the Windows Event
// Log API.
publisherHandle = messageFiles.Handles[0].Handle
}
}

// Populate strings that must be looked up.
Expand Down Expand Up @@ -311,6 +316,17 @@ func CreateBookmark(channel string, recordID uint64) (EvtHandle, error) {
return h, nil
}

// Create a render context. Close must be called on returned EvtHandle when
// finished with the handle.
func CreateRenderContext(valuePaths []string, flag EvtRenderContextFlag) (EvtHandle, error) {
context, err := _EvtCreateRenderContext(0, nil, EvtRenderContextSystem)
if err != nil {
return 0, err
}

return context, nil
}

// OpenPublisherMetadata opens a handle to the publisher's metadata. Close must
// be called on returned EvtHandle when finished with the handle.
func OpenPublisherMetadata(
Expand Down

0 comments on commit e4c46cd

Please sign in to comment.