// 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, sourceName, 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), eventMetadata: c.EventMetadata, }, nil }
func (l *winEventLog) Open(recordNumber uint64) error { bookmark, err := sys.CreateBookmark(l.channelName, recordNumber) if err != nil { return err } defer sys.Close(bookmark) // Using a pull subscription to receive events. See: // https://msdn.microsoft.com/en-us/library/windows/desktop/aa385771(v=vs.85).aspx#pull signalEvent, err := windows.CreateEvent(nil, 0, 0, nil) if err != nil { return nil } subscriptionHandle, err := sys.Subscribe( 0, // null session (used for connecting to remote event logs) signalEvent, l.channelName, "", // Query - nil means all events bookmark, // Bookmark - for resuming from a specific event sys.EvtSubscribeStartAfterBookmark) if err != nil { return err } l.subscription = subscriptionHandle return nil }
func (l *winEventLog) Open(recordNumber uint64) error { bookmark, err := win.CreateBookmark(l.channelName, recordNumber) if err != nil { return err } defer win.Close(bookmark) // Using a pull subscription to receive events. See: // https://msdn.microsoft.com/en-us/library/windows/desktop/aa385771(v=vs.85).aspx#pull signalEvent, err := windows.CreateEvent(nil, 0, 0, nil) if err != nil { return nil } debugf("%s using subscription query=%s", l.logPrefix, l.query) subscriptionHandle, err := win.Subscribe( 0, // Session - nil for localhost signalEvent, "", // Channel - empty b/c channel is in the query l.query, // Query - nil means all events bookmark, // Bookmark - for resuming from a specific event win.EvtSubscribeStartAfterBookmark) if err != nil { return err } l.subscription = subscriptionHandle return nil }
func (l *winEventLog) Read() ([]Record, error) { handles, err := sys.EventHandles(l.subscription, l.maxRead) if err == sys.ERROR_NO_MORE_ITEMS { detailf("%s No more events", l.logPrefix) return nil, nil } if err != nil { logp.Warn("%s EventHandles returned error %v Errno: %d", l.logPrefix, err) return nil, err } defer func() { for _, h := range handles { sys.Close(h) } }() detailf("%s EventHandles returned %d handles", l.logPrefix, len(handles)) var records []Record for _, h := range handles { 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 } r := Record{ API: winEventLogAPIName, EventLogName: e.Channel, SourceName: e.ProviderName, ComputerName: e.Computer, RecordNumber: e.RecordID, EventID: uint32(e.EventID), Level: e.Level, Category: e.Task, Message: e.Message, MessageErr: e.MessageErr, EventMetadata: l.eventMetadata, } if e.TimeCreated != nil { r.TimeGenerated = *e.TimeCreated } if e.UserSID != nil { r.User = &User{ Identifier: e.UserSID.Identifier, Name: e.UserSID.Name, Domain: e.UserSID.Domain, Type: e.UserSID.Type.String(), } } records = append(records, r) } debugf("%s Read() is returning %d records", l.logPrefix, len(records)) return records, nil }
func (l *winEventLog) Read() ([]Record, error) { handles, err := win.EventHandles(l.subscription, l.maxRead) if err == win.ERROR_NO_MORE_ITEMS { detailf("%s No more events", l.logPrefix) return nil, nil } if err != nil { logp.Warn("%s EventHandles returned error %v", l.logPrefix, err) return nil, err } defer func() { for _, h := range handles { win.Close(h) } }() detailf("%s EventHandles returned %d handles", l.logPrefix, len(handles)) var records []Record for _, h := range handles { x, err := l.render(h) if bufErr, ok := err.(sys.InsufficientBufferError); ok { detailf("%s Increasing render buffer size to %d", l.logPrefix, bufErr.RequiredSize) l.renderBuf = make([]byte, bufErr.RequiredSize) x, err = l.render(h) } if err != nil && x == "" { logp.Err("%s Dropping event with rendering error. %v", l.logPrefix, err) reportDrop(err) continue } r, err := l.buildRecordFromXML(x, err) if err != nil { logp.Err("%s Dropping event. %v", l.logPrefix, err) reportDrop("unmarshal") continue } records = append(records, r) } debugf("%s Read() is returning %d records", l.logPrefix, len(records)) return records, nil }
// newWinEventLog creates and returns a new EventLog for reading event logs // using the Windows Event Log. func newWinEventLog(options map[string]interface{}) (EventLog, error) { var c winEventLogConfig if err := readConfig(options, &c, winEventLogConfigKeys); err != nil { return nil, err } query, err := win.Query{ Log: c.Name, IgnoreOlder: c.SimpleQuery.IgnoreOlder, Level: c.SimpleQuery.Level, EventID: c.SimpleQuery.EventID, Provider: c.SimpleQuery.Provider, }.Build() if err != nil { return nil, err } eventMetadataHandle := func(providerName, sourceName string) sys.MessageFiles { mf := sys.MessageFiles{SourceName: sourceName} h, err := win.OpenPublisherMetadata(0, sourceName, 0) if err != nil { mf.Err = err return mf } mf.Handles = []sys.FileHandle{sys.FileHandle{Handle: uintptr(h)}} return mf } freeHandle := func(handle uintptr) error { return win.Close(win.EvtHandle(handle)) } return &winEventLog{ config: c, query: query, channelName: c.Name, maxRead: defaultMaxNumRead, renderBuf: make([]byte, renderBufferSize), cache: newMessageFilesCache(c.Name, eventMetadataHandle, freeHandle), logPrefix: fmt.Sprintf("WinEventLog[%s]", c.Name), eventMetadata: c.EventMetadata, }, nil }
func (l *winEventLog) Read() ([]Record, error) { handles, _, err := l.eventHandles(l.maxRead) if err != nil || len(handles) == 0 { return nil, err } defer func() { for _, h := range handles { win.Close(h) } }() detailf("%s EventHandles returned %d handles", l.logPrefix, len(handles)) var records []Record for _, h := range handles { l.outputBuf.Reset() err := l.render(h, l.outputBuf) if bufErr, ok := err.(sys.InsufficientBufferError); ok { detailf("%s Increasing render buffer size to %d", l.logPrefix, bufErr.RequiredSize) l.renderBuf = make([]byte, bufErr.RequiredSize) l.outputBuf.Reset() err = l.render(h, l.outputBuf) } if err != nil && l.outputBuf.Len() == 0 { logp.Err("%s Dropping event with rendering error. %v", l.logPrefix, err) incrementMetric(dropReasons, err) continue } r, err := l.buildRecordFromXML(l.outputBuf.Bytes(), err) if err != nil { logp.Err("%s Dropping event. %v", l.logPrefix, err) incrementMetric(dropReasons, err) continue } records = append(records, r) l.lastRead = r.RecordID } debugf("%s Read() is returning %d records", l.logPrefix, len(records)) return records, nil }
func (l *winEventLog) Close() error { debugf("%s Closing handle", l.logPrefix) return sys.Close(l.subscription) }
// newWinEventLog creates and returns a new EventLog for reading event logs // using the Windows Event Log. func newWinEventLog(options map[string]interface{}) (EventLog, error) { c := defaultWinEventLogConfig if err := readConfig(options, &c, winEventLogConfigKeys); err != nil { return nil, err } query, err := win.Query{ Log: c.Name, IgnoreOlder: c.SimpleQuery.IgnoreOlder, Level: c.SimpleQuery.Level, EventID: c.SimpleQuery.EventID, Provider: c.SimpleQuery.Provider, }.Build() if err != nil { return nil, err } eventMetadataHandle := func(providerName, sourceName string) sys.MessageFiles { mf := sys.MessageFiles{SourceName: sourceName} h, err := win.OpenPublisherMetadata(0, sourceName, 0) if err != nil { mf.Err = err return mf } mf.Handles = []sys.FileHandle{{Handle: uintptr(h)}} return mf } freeHandle := func(handle uintptr) error { return win.Close(win.EvtHandle(handle)) } l := &winEventLog{ config: c, query: query, channelName: c.Name, maxRead: c.BatchReadSize, renderBuf: make([]byte, renderBufferSize), cache: newMessageFilesCache(c.Name, eventMetadataHandle, freeHandle), logPrefix: fmt.Sprintf("WinEventLog[%s]", c.Name), eventMetadata: c.EventMetadata, } // Forwarded events should be rendered using RenderEventXML. It is more // efficient and does not attempt to use local message files for rendering // the event's message. switch { case c.Forwarded == nil && c.Name == "ForwardedEvents", c.Forwarded != nil && *c.Forwarded == true: l.render = func(event win.EvtHandle) (string, error) { return win.RenderEventXML(event, l.renderBuf) } default: l.render = func(event win.EvtHandle) (string, error) { return win.RenderEvent(event, 0, l.renderBuf, l.cache.get) } } return l, nil }
func (l *eventLog) Close() error { return sys.Close(l.subscription) }