Skip to content

Commit

Permalink
Merge pull request #888 from andrewkroh/feature/winlogbeat-caching
Browse files Browse the repository at this point in the history
Winlogbeat: add caching of metadata handles
  • Loading branch information
ruflin committed Feb 1, 2016
2 parents 04cfaad + c0fc105 commit 002fa5d
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 11 deletions.
7 changes: 1 addition & 6 deletions CHANGELOG.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -70,13 +70,8 @@ https://github.com/elastic/beats/compare/v1.1.0...master[Check the HEAD diff]
- Add close_older configuration option to complete ignore_older https://github.com/elastic/filebeat/issues/181[181]
- Add experimental option to enable filebeat publisher pipeline to operate asynchonrously {pull}782[782]

*Packetbeat*

*Topbeat*

*Filebeat*

*Winlogbeat*
- Add caching of event metadata handles and the system render context for the wineventlog API {pull}888[888]

==== Deprecated

Expand Down
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 002fa5d

Please sign in to comment.