Add Event Log support for Windows (#8616)

* Add event log support for windows when not running as a windows service.

* Add error message for initializing event logger.

* Add build windows flag.

* Only register event logger when running telegraf under windows.

* Update logger/event_logger.go

Co-authored-by: Steven Soroka <ssoroka@influxdata.com>

* Remove unnecessary 'fmt' import

* Remove unnecessary 'fmt' import

* Remove unnecessary error check

* use constants for eid levels.

Co-authored-by: Steven Soroka <ssoroka@influxdata.com>
This commit is contained in:
David Bennett 2021-01-19 11:03:19 -05:00 committed by GitHub
parent 6ed1431348
commit 1bf5a19582
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 33 additions and 23 deletions

View File

@ -12,6 +12,9 @@ import (
)
func run(inputFilters, outputFilters, aggregatorFilters, processorFilters []string) {
// Register the eventlog logging target for windows.
logger.RegisterEventLogger(*fServiceName)
if runtime.GOOS == "windows" && windowsRunAsService() {
runAsWindowsService(
inputFilters,
@ -96,12 +99,7 @@ func runAsWindowsService(inputFilters, outputFilters, aggregatorFilters, process
}
os.Exit(0)
} else {
winlogger, err := s.Logger(nil)
if err == nil {
//When in service mode, register eventlog target andd setup default logging to eventlog
logger.RegisterEventLogger(winlogger)
logger.SetupLogging(logger.LogConfig{LogTarget: logger.LogTargetEventlog})
}
logger.SetupLogging(logger.LogConfig{LogTarget: logger.LogTargetEventlog})
err = s.Run()
if err != nil {

View File

@ -1,35 +1,41 @@
//+build windows
package logger
import (
"io"
"log"
"strings"
"github.com/influxdata/wlog"
"github.com/kardianos/service"
"golang.org/x/sys/windows/svc/eventlog"
)
const (
LogTargetEventlog = "eventlog"
eidInfo = 1
eidWarning = 2
eidError = 3
)
type eventLogger struct {
logger service.Logger
logger *eventlog.Log
}
func (t *eventLogger) Write(b []byte) (n int, err error) {
loc := prefixRegex.FindIndex(b)
n = len(b)
if loc == nil {
err = t.logger.Info(b)
err = t.logger.Info(1, string(b))
} else if n > 2 { //skip empty log messages
line := strings.Trim(string(b[loc[1]:]), " \t\r\n")
switch rune(b[loc[0]]) {
case 'I':
err = t.logger.Info(line)
err = t.logger.Info(eidInfo, line)
case 'W':
err = t.logger.Warning(line)
err = t.logger.Warning(eidWarning, line)
case 'E':
err = t.logger.Error(line)
err = t.logger.Error(eidError, line)
}
}
@ -37,13 +43,20 @@ func (t *eventLogger) Write(b []byte) (n int, err error) {
}
type eventLoggerCreator struct {
serviceLogger service.Logger
logger *eventlog.Log
}
func (e *eventLoggerCreator) CreateLogger(config LogConfig) (io.Writer, error) {
return wlog.NewWriter(&eventLogger{logger: e.serviceLogger}), nil
return wlog.NewWriter(&eventLogger{logger: e.logger}), nil
}
func RegisterEventLogger(serviceLogger service.Logger) {
registerLogger(LogTargetEventlog, &eventLoggerCreator{serviceLogger: serviceLogger})
func RegisterEventLogger(name string) error {
eventLog, err := eventlog.Open(name)
if err != nil {
log.Printf("E! An error occurred while initializing an event logger. %s", err)
return err
}
registerLogger(LogTargetEventlog, &eventLoggerCreator{logger: eventLog})
return nil
}

View File

@ -10,9 +10,9 @@ import (
"testing"
"time"
"github.com/kardianos/service"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"golang.org/x/sys/windows/svc/eventlog"
)
type Levels int
@ -30,7 +30,8 @@ type Event struct {
func getEventLog(t *testing.T, since time.Time) []Event {
timeStr := since.UTC().Format(time.RFC3339)
cmd := exec.Command("wevtutil", "qe", "Application", "/rd:true", "/q:Event[System[TimeCreated[@SystemTime >= '"+timeStr+"'] and Provider[@Name='Telegraf']]]")
timeStr = timeStr[:19]
cmd := exec.Command("wevtutil", "qe", "Application", "/rd:true", "/q:Event[System[TimeCreated[@SystemTime >= '"+timeStr+"'] and Provider[@Name='telegraf']]]")
var out bytes.Buffer
cmd.Stdout = &out
err := cmd.Run()
@ -91,10 +92,8 @@ func TestRestrictedEventLog(t *testing.T) {
}
func prepareLogger(t *testing.T) {
svc, err := service.New(nil, &service.Config{Name: "Telegraf"})
eventLog, err := eventlog.Open("telegraf")
require.NoError(t, err)
svcLogger, err := svc.SystemLogger(nil)
require.NoError(t, err)
require.NotNil(t, svcLogger)
registerLogger(LogTargetEventlog, &eventLoggerCreator{serviceLogger: svcLogger})
require.NotNil(t, eventLog)
registerLogger(LogTargetEventlog, &eventLoggerCreator{logger: eventLog})
}