Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove all C requirements #2

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 16 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,25 @@
# gowinlog
Go library for subscribing to the Windows Event Log.

Godocs
=======
[gowinlog v0](https://gopkg.in/scalingdata/gowinlog.v0))

Installation
=======

gowinlog uses cgo, so it needs gcc, and `evt.h` must be available. Installing [MinGW-w64](http://mingw-w64.yaxm.org/doku.php) should satisfy both requirements. Make sure the Go architecture and GCC architecture are the same.
gowinlog uses cgo, so it needs gcc. Installing [MinGW-w64](http://mingw-w64.yaxm.org/doku.php) should satisfy both requirements. Make sure the Go architecture and GCC architecture are the same.

Features
========

- Includes wrapper for wevtapi.dll, and a high level API
- Supports bookmarks for resuming consumption
- Filter events using XPath expressions

Usage
=======

In Go, create a watcher and subscribe to some log channels. Subscriptions can start at the beginning of the log, at the most recent event, or at a bookmark. Events and errors are coerced into Go structs and published on the `Event()` and `Error()` channels. Every event includes a `Bookmark` field which can be stored and used to resume processing at the same point.

``` Go
package main

Expand All @@ -25,15 +34,14 @@ func main() {
fmt.Printf("Couldn't create watcher: %v\n", err)
return
}
// Recieve any future messages
watcher.SubscribeFromNow("Application")
// Recieve any future messages on the Application channel
// "*" doesn't filter by any fields of the event
watcher.SubscribeFromNow("Application", "*")
for {
select {
case evt := <- watcher.Event():
// Print the event struct
fmt.Printf("Event: %v\n", evt)
// Print the updated bookmark for that channel
fmt.Printf("Bookmark XML: %v\n", evt.Bookmark)
case err := <- watcher.Error():
fmt.Printf("Error: %v\n\n", err)
}
Expand All @@ -44,4 +52,4 @@ func main() {
Low-level API
------

`event.go` contains wrappers around the C events API. `bookmark.go` has wrappers around the bookmark API.
`winevt.go` provides wrappers around the relevant functions in `wevtapi.dll`.
55 changes: 0 additions & 55 deletions bookmark.c

This file was deleted.

48 changes: 24 additions & 24 deletions bookmark.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,46 +2,46 @@

package winlog

/*
#cgo LDFLAGS: -l wevtapi
#include "bookmark.h"
*/
import "C"
import (
"unsafe"
"syscall"
)

/* Create a new, empty bookmark. Bookmark handles must be closed with CloseEventHandle. */
func CreateBookmark() (BookmarkHandle, error) {
bookmark := BookmarkHandle(C.CreateBookmark())
if bookmark == 0 {
return 0, GetLastError()
bookmark, err := EvtCreateBookmark(nil)
if err != nil {
return 0, err
}
return bookmark, nil
return BookmarkHandle(bookmark), nil
}

/* Create a bookmark from a XML-serialized bookmark. Bookmark handles must be closed with CloseEventHandle. */
func CreateBookmarkFromXml(xmlString string) (BookmarkHandle, error) {
cString := C.CString(xmlString)
bookmark := C.CreateBookmarkFromXML(cString)
C.free(unsafe.Pointer(cString))
wideXmlString, err := syscall.UTF16PtrFromString(xmlString)
if err != nil {
return 0, err
}
bookmark, err := EvtCreateBookmark(wideXmlString)
if bookmark == 0 {
return 0, GetLastError()
return 0, err
}
return BookmarkHandle(bookmark), nil
}

/* Update a bookmark to store the channel and ID of the given event */
func UpdateBookmark(bookmarkHandle BookmarkHandle, eventHandle EventHandle) error {
if C.UpdateBookmark(C.ULONGLONG(bookmarkHandle), C.ULONGLONG(eventHandle)) == 0 {
return GetLastError()
}
return nil
return EvtUpdateBookmark(syscall.Handle(bookmarkHandle), syscall.Handle(eventHandle))
}

/* Serialize the bookmark as XML */
func RenderBookmark(bookmarkHandle BookmarkHandle) (string, error) {
cString := C.RenderBookmark(C.ULONGLONG(bookmarkHandle))
if cString == nil {
return "", GetLastError()
var dwUsed uint32
var dwProps uint32
EvtRender(0, syscall.Handle(bookmarkHandle), EvtRenderBookmark, 0, nil, &dwUsed, &dwProps)
buf := make([]uint16, dwUsed)
err := EvtRender(0, syscall.Handle(bookmarkHandle), EvtRenderBookmark, uint32(len(buf)), &buf[0], &dwUsed, &dwProps)
if err != nil {
return "", err
}
bookmarkXml := C.GoString(cString)
C.free(unsafe.Pointer(cString))
return bookmarkXml, nil
return syscall.UTF16ToString(buf), nil
}
16 changes: 0 additions & 16 deletions bookmark.h

This file was deleted.

6 changes: 2 additions & 4 deletions bookmark_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ package winlog
import (
"encoding/xml"
. "testing"
"unsafe"
)

type bookmarkListXml struct {
Expand Down Expand Up @@ -85,9 +84,8 @@ func TestUpdateBookmark(t *T) {
if err != nil {
t.Fatal(err)
}
defer Free(unsafe.Pointer(renderedFields))
channel, _ := RenderStringField(renderedFields, EvtSystemChannel)
eventId, _ := RenderUIntField(renderedFields, EvtSystemEventRecordId)
channel, _ := renderedFields.String(EvtSystemChannel)
eventId, _ := renderedFields.Uint(EvtSystemEventRecordId)
bookmarkChannel := bookmarkStruct.Bookmarks[0].Channel
bookmarkId := bookmarkStruct.Bookmarks[0].RecordId

Expand Down
Loading