diff --git a/cmd/windows_exporter/0_service.go b/cmd/windows_exporter/0_service.go
index d19756b22..37ac74087 100644
--- a/cmd/windows_exporter/0_service.go
+++ b/cmd/windows_exporter/0_service.go
@@ -126,7 +126,7 @@ func (s *windowsExporterService) Execute(_ []string, r <-chan svc.ChangeRequest,
// logToEventToLog logs a message to the Windows event log.
func logToEventToLog(eType uint16, msg string) error {
- eventLog, err := eventlog.Open("windows_exporter")
+ eventLog, err := eventlog.Open(serviceName)
if err != nil {
return fmt.Errorf("failed to open event log: %w", err)
}
@@ -134,15 +134,15 @@ func logToEventToLog(eType uint16, msg string) error {
_ = eventLog.Close()
}(eventLog)
- p, err := windows.UTF16PtrFromString(msg)
- if err != nil {
- return fmt.Errorf("error convert string to UTF-16: %w", err)
+ switch eType {
+ case windows.EVENTLOG_ERROR_TYPE:
+ err = eventLog.Error(102, msg)
+ case windows.EVENTLOG_WARNING_TYPE:
+ err = eventLog.Warning(101, msg)
+ case windows.EVENTLOG_INFORMATION_TYPE:
+ err = eventLog.Info(100, msg)
}
- zero := uint16(0)
- ss := []*uint16{p, &zero, &zero, &zero, &zero, &zero, &zero, &zero, &zero}
-
- err = windows.ReportEvent(eventLog.Handle, eType, 0, 3299, 0, 9, 0, &ss[0], nil)
if err != nil {
return fmt.Errorf("error report event: %w", err)
}
diff --git a/installer/files.wxs b/installer/files.wxs
index 1b4c019de..e011b6c66 100644
--- a/installer/files.wxs
+++ b/installer/files.wxs
@@ -44,6 +44,12 @@
+
+
diff --git a/internal/log/eventlog/eventlog.go b/internal/log/eventlog/eventlog.go
index 73e68864a..ba1c89f2a 100644
--- a/internal/log/eventlog/eventlog.go
+++ b/internal/log/eventlog/eventlog.go
@@ -17,53 +17,41 @@
package eventlog
import (
- "bytes"
- "fmt"
"io"
+ "regexp"
+ "strings"
- "golang.org/x/sys/windows"
-)
-
-const (
- // NeLogOemCode is a generic error log entry for OEMs to use to
- // elog errors from OEM value added services.
- // See: https://github.com/microsoft/win32metadata/blob/2f3c5282ce1024a712aeccd90d3aa50bf7a49e27/generation/WinSDK/RecompiledIdlHeaders/um/LMErrlog.h#L824-L845
- NeLogOemCode = uint32(3299)
+ "golang.org/x/sys/windows/svc/eventlog"
)
// Interface guard.
var _ io.Writer = (*Writer)(nil)
-//nolint:gochecknoglobals
-var EmptyStringUTF16 uint16
+var reStripTimeAndLevel = regexp.MustCompile(`^time=\S+ level=\S+ `)
type Writer struct {
- handle windows.Handle
+ handle *eventlog.Log
}
-// NewEventLogWriter returns a new Writer which writes to Windows EventLog.
-func NewEventLogWriter(handle windows.Handle) *Writer {
+// NewEventLogWriter returns a new Writer, which writes to Windows EventLog.
+func NewEventLogWriter(handle *eventlog.Log) *Writer {
return &Writer{handle: handle}
}
func (w *Writer) Write(p []byte) (int, error) {
- var eType uint16
+ var err error
+
+ msg := strings.TrimSpace(string(p))
+ eventLogMsg := reStripTimeAndLevel.ReplaceAllString(msg, "")
switch {
- case bytes.Contains(p, []byte(" level=error")) || bytes.Contains(p, []byte(`"level":"error"`)):
- eType = windows.EVENTLOG_ERROR_TYPE
- case bytes.Contains(p, []byte(" level=warn")) || bytes.Contains(p, []byte(`"level":"warn"`)):
- eType = windows.EVENTLOG_WARNING_TYPE
+ case strings.Contains(msg, " level=ERROR") || strings.Contains(msg, `"level":"error"`):
+ err = w.handle.Error(102, eventLogMsg)
+ case strings.Contains(msg, " level=WARN") || strings.Contains(msg, `"level":"warn"`):
+ err = w.handle.Warning(101, eventLogMsg)
default:
- eType = windows.EVENTLOG_INFORMATION_TYPE
+ err = w.handle.Info(100, eventLogMsg)
}
- msg, err := windows.UTF16PtrFromString(string(p))
- if err != nil {
- return 0, fmt.Errorf("error convert string to UTF-16: %w", err)
- }
-
- ss := []*uint16{msg, &EmptyStringUTF16, &EmptyStringUTF16, &EmptyStringUTF16, &EmptyStringUTF16, &EmptyStringUTF16, &EmptyStringUTF16, &EmptyStringUTF16, &EmptyStringUTF16}
-
- return len(p), windows.ReportEvent(w.handle, eType, 0, NeLogOemCode, 0, 9, 0, &ss[0], nil)
+ return len(p), err
}
diff --git a/internal/log/logger.go b/internal/log/logger.go
index c245783e2..23006aae9 100644
--- a/internal/log/logger.go
+++ b/internal/log/logger.go
@@ -24,7 +24,7 @@ import (
"github.com/prometheus-community/windows_exporter/internal/log/eventlog"
"github.com/prometheus/common/promslog"
- "golang.org/x/sys/windows"
+ wineventlog "golang.org/x/sys/windows/svc/eventlog"
)
// AllowedFile is a settable identifier for the output file that the logger can have.
@@ -51,12 +51,12 @@ func (f *AllowedFile) Set(s string) error {
case "stderr":
f.w = os.Stderr
case "eventlog":
- handle, err := windows.RegisterEventSource(nil, windows.StringToUTF16Ptr("windows_exporter"))
+ eventLog, err := wineventlog.Open("windows_exporter")
if err != nil {
return fmt.Errorf("failed to open event log: %w", err)
}
- f.w = eventlog.NewEventLogWriter(handle)
+ f.w = eventlog.NewEventLogWriter(eventLog)
default:
file, err := os.OpenFile(s, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0o200)
if err != nil {
diff --git a/internal/pdh/collector.go b/internal/pdh/collector.go
index 1aa689395..db8ab1490 100644
--- a/internal/pdh/collector.go
+++ b/internal/pdh/collector.go
@@ -172,6 +172,12 @@ func NewCollectorWithReflection(resultType CounterType, object string, instances
continue
}
+ if bufLen == 0 {
+ errs = append(errs, errors.New("GetCounterInfo: buffer length is zero"))
+
+ continue
+ }
+
buf := make([]byte, bufLen)
if ret := GetCounterInfo(counterHandle, 0, &bufLen, &buf[0]); ret != ErrorSuccess {
errs = append(errs, fmt.Errorf("GetCounterInfo: %w", NewPdhError(ret)))