Skip to content
Open
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
23 changes: 9 additions & 14 deletions logging/windows_etw_logger.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,6 @@ func RegisterETWLogger(rootLogger Logger, etlDir string, p ETWProvider) (io.Clos
if err := sess.Start(startCtx); err != nil {
rootLogger.Warnw("ETW session start failed; provider registered but file capture could not start",
"err", err, "session", p.SessionName, "outputPath", etlPath)
provider.Close()
return nopCloser{}, err
} else {
liveSession = sess
Expand All @@ -88,7 +87,7 @@ func RegisterETWLogger(rootLogger Logger, etlDir string, p ETWProvider) (io.Clos
// listening, near-free when not — no buffering goroutine needed.
type etwAppender struct {
provider *etw.Provider
session sessionController // nil if session start failed
session sessionController
}

// Write maps the zap entry to a level-tagged ETW event with structured fields.
Expand Down Expand Up @@ -142,20 +141,16 @@ func (a *etwAppender) Write(entry zapcore.Entry, fields []zapcore.Field) error {

func (a *etwAppender) Sync() error { return nil }

// Close stops the session before unregistering the provider so any kernel
// buffer contents are flushed to the .etl file before teardown.
// stop the session if it still exists when Close() is called.
// don't touch the provider to avoid a bug in the Close logic of winio
// the provider is killed by windows when the process dies
func (a *etwAppender) Close() error {
var sessErr error
if a.session != nil {
stopCtx, cancel := context.WithTimeout(context.Background(), etwLogmanTimeout)
defer cancel()
sessErr = a.session.Stop(stopCtx)
}
provErr := a.provider.Close()
if sessErr != nil {
return sessErr
if a.session == nil {
return nil
}
return provErr
stopCtx, cancel := context.WithTimeout(context.Background(), etwLogmanTimeout)
defer cancel()
return a.session.Stop(stopCtx)
}

func zapToETWLevel(l zapcore.Level) etw.Level {
Expand Down
5 changes: 3 additions & 2 deletions logging/windows_logging_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ func TestETWNulls(t *testing.T) {
closer, err := RegisterETWLogger(logger, etlDir, ServerETW)
test.That(t, closer, test.ShouldNotBeNil)
test.That(t, err, test.ShouldBeNil)
defer closer.Close()

logger.Info("message through registered ETW appender")
err = logger.Sync()
Expand Down Expand Up @@ -58,7 +59,7 @@ func TestETWAppenderLifecycle(t *testing.T) {

test.That(t, a.Close(), test.ShouldBeNil)

// Write after close: provider is unregistered, pkg/etw's WriteEvent checks
// provider.enabled and no-ops. Must not panic.
// Write after close: there's no active session, so the provider is disabled
// Must not panic.
logger.Info("after close")
}
Loading