Skip to content

Instantly share code, notes, and snippets.

@reedlaw
Last active November 12, 2019 16:31
Show Gist options
  • Save reedlaw/61bb51a1c10326b9fb82162d09388b5c to your computer and use it in GitHub Desktop.
Save reedlaw/61bb51a1c10326b9fb82162d09388b5c to your computer and use it in GitHub Desktop.
Create custom Windows Event Source in Go
// +build windows
package main
import (
"errors"
"golang.org/x/sys/windows/registry"
"golang.org/x/sys/windows/svc/eventlog"
)
const eventLogKeyName = `SYSTEM\CurrentControlSet\Services\EventLog`
// InstallCustomLog creates a custom event log under Microsoft Event Viewer.
func InstallCustomLog(name string, src string, eventsSupported uint32) error {
k, err := createSubKey(registry.LOCAL_MACHINE, eventLogKeyName, name)
if err != nil {
return errors.New(name + " subkey could not be created")
}
defer k.Close()
err = k.SetDWordValue("TypesSupported", eventsSupported)
if err != nil {
return errors.New("TypesSupported could not be created")
}
lk, err := createSubKey(registry.LOCAL_MACHINE, eventLogKeyName + `\` + name, name)
if err != nil {
return errors.New(name + " " + name + " subkey could not be created")
}
defer lk.Close()
err = lk.SetExpandStringValue("EventMessageFile", "C:\\Windows\\Microsoft.NET\\Framework\\v4.0.30319\\EventLogMessages.dll")
if err != nil {
return errors.New("EventMessageFile")
}
sk, err := createSubKey(registry.LOCAL_MACHINE, eventLogKeyName + `\` + name, src)
if err != nil {
return err
}
defer sk.Close()
err = sk.SetExpandStringValue("EventMessageFile", "C:\\Windows\\Microsoft.NET\\Framework\\v4.0.30319\\EventLogMessages.dll")
if err != nil {
return err
}
if err != nil {
return err
}
return nil
}
// RemoveCustomLog deletes all registry elements installed by the correspondent InstallCustomLog.
func RemoveCustomLog(name string, src string) error {
appkey, err := registry.OpenKey(registry.LOCAL_MACHINE, eventLogKeyName + `\` + name, registry.SET_VALUE)
if err != nil {
return err
}
defer appkey.Close()
err = registry.DeleteKey(appkey, name)
if err != nil {
return err
}
err = registry.DeleteKey(appkey, src)
if err != nil {
return err
}
key, err := registry.OpenKey(registry.LOCAL_MACHINE, eventLogKeyName, registry.SET_VALUE)
if err != nil {
return err
}
defer key.Close()
return registry.DeleteKey(key, name)
}
func createSubKey(key registry.Key, path string, keyName string) (registry.Key, error) {
k, err := registry.OpenKey(key, path, registry.CREATE_SUB_KEY)
if err != nil {
return k, errors.New(path + " path could not be opened")
}
defer k.Close()
sk, alreadyExist, err := registry.CreateKey(key, path + `\` + keyName, registry.SET_VALUE)
if err != nil {
return sk, errors.New(keyName + " key could not be created")
}
if alreadyExist {
return sk, errors.New(path + `\` + keyName + " registry key already exists")
}
return sk, nil
}
@reedlaw
Copy link
Author

reedlaw commented Nov 12, 2019

Use like so:

import (
	"github.com/sirupsen/logrus"
	"github.com/freman/eventloghook"
)

// Sets up custom event log
func SetupEventLog(log *logrus.Logger) {
	const supports = eventlog.Error | eventlog.Warning | eventlog.Info
	svcName := "YourService"

	err := RemoveCustomLog(svcName + "Log", svcName + "Source")
	if err != nil {
		log.Infof("Remove failed: %s", err)
	}

	err = InstallCustomLog(svcName + "Log", svcName + "Source", supports)
	if err != nil {
		log.Infof("Install failed: %s", err)
	}

	l, err := eventlog.Open(svcName + "Log")
	if err != nil {
		log.Infof("Open failed: %s", err)
	}

	l.Info(1, "Setup log")
	log.Hooks.Add(eventloghook.NewHook(l))
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment