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:
parent
6ed1431348
commit
1bf5a19582
|
|
@ -12,6 +12,9 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func run(inputFilters, outputFilters, aggregatorFilters, processorFilters []string) {
|
func run(inputFilters, outputFilters, aggregatorFilters, processorFilters []string) {
|
||||||
|
// Register the eventlog logging target for windows.
|
||||||
|
logger.RegisterEventLogger(*fServiceName)
|
||||||
|
|
||||||
if runtime.GOOS == "windows" && windowsRunAsService() {
|
if runtime.GOOS == "windows" && windowsRunAsService() {
|
||||||
runAsWindowsService(
|
runAsWindowsService(
|
||||||
inputFilters,
|
inputFilters,
|
||||||
|
|
@ -96,12 +99,7 @@ func runAsWindowsService(inputFilters, outputFilters, aggregatorFilters, process
|
||||||
}
|
}
|
||||||
os.Exit(0)
|
os.Exit(0)
|
||||||
} else {
|
} else {
|
||||||
winlogger, err := s.Logger(nil)
|
logger.SetupLogging(logger.LogConfig{LogTarget: logger.LogTargetEventlog})
|
||||||
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})
|
|
||||||
}
|
|
||||||
err = s.Run()
|
err = s.Run()
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
|
|
@ -1,35 +1,41 @@
|
||||||
|
//+build windows
|
||||||
|
|
||||||
package logger
|
package logger
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"io"
|
"io"
|
||||||
|
"log"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/influxdata/wlog"
|
"github.com/influxdata/wlog"
|
||||||
"github.com/kardianos/service"
|
"golang.org/x/sys/windows/svc/eventlog"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
LogTargetEventlog = "eventlog"
|
LogTargetEventlog = "eventlog"
|
||||||
|
eidInfo = 1
|
||||||
|
eidWarning = 2
|
||||||
|
eidError = 3
|
||||||
)
|
)
|
||||||
|
|
||||||
type eventLogger struct {
|
type eventLogger struct {
|
||||||
logger service.Logger
|
logger *eventlog.Log
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *eventLogger) Write(b []byte) (n int, err error) {
|
func (t *eventLogger) Write(b []byte) (n int, err error) {
|
||||||
loc := prefixRegex.FindIndex(b)
|
loc := prefixRegex.FindIndex(b)
|
||||||
n = len(b)
|
n = len(b)
|
||||||
if loc == nil {
|
if loc == nil {
|
||||||
err = t.logger.Info(b)
|
err = t.logger.Info(1, string(b))
|
||||||
} else if n > 2 { //skip empty log messages
|
} else if n > 2 { //skip empty log messages
|
||||||
line := strings.Trim(string(b[loc[1]:]), " \t\r\n")
|
line := strings.Trim(string(b[loc[1]:]), " \t\r\n")
|
||||||
switch rune(b[loc[0]]) {
|
switch rune(b[loc[0]]) {
|
||||||
case 'I':
|
case 'I':
|
||||||
err = t.logger.Info(line)
|
err = t.logger.Info(eidInfo, line)
|
||||||
case 'W':
|
case 'W':
|
||||||
err = t.logger.Warning(line)
|
err = t.logger.Warning(eidWarning, line)
|
||||||
case 'E':
|
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 {
|
type eventLoggerCreator struct {
|
||||||
serviceLogger service.Logger
|
logger *eventlog.Log
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *eventLoggerCreator) CreateLogger(config LogConfig) (io.Writer, error) {
|
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) {
|
func RegisterEventLogger(name string) error {
|
||||||
registerLogger(LogTargetEventlog, &eventLoggerCreator{serviceLogger: serviceLogger})
|
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
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,9 +10,9 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/kardianos/service"
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
"golang.org/x/sys/windows/svc/eventlog"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Levels int
|
type Levels int
|
||||||
|
|
@ -30,7 +30,8 @@ type Event struct {
|
||||||
|
|
||||||
func getEventLog(t *testing.T, since time.Time) []Event {
|
func getEventLog(t *testing.T, since time.Time) []Event {
|
||||||
timeStr := since.UTC().Format(time.RFC3339)
|
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
|
var out bytes.Buffer
|
||||||
cmd.Stdout = &out
|
cmd.Stdout = &out
|
||||||
err := cmd.Run()
|
err := cmd.Run()
|
||||||
|
|
@ -91,10 +92,8 @@ func TestRestrictedEventLog(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func prepareLogger(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)
|
require.NoError(t, err)
|
||||||
svcLogger, err := svc.SystemLogger(nil)
|
require.NotNil(t, eventLog)
|
||||||
require.NoError(t, err)
|
registerLogger(LogTargetEventlog, &eventLoggerCreator{logger: eventLog})
|
||||||
require.NotNil(t, svcLogger)
|
|
||||||
registerLogger(LogTargetEventlog, &eventLoggerCreator{serviceLogger: svcLogger})
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue