go.mondoo.com/cnquery@v0.0.0-20231005093811-59568235f6ea/logger/eventlog/eventlog_windows.go (about)

     1  // Copyright (c) Mondoo, Inc.
     2  // SPDX-License-Identifier: BUSL-1.1
     3  
     4  // +build windows
     5  
     6  // Package eventlog provides a io.Writer to send the logs
     7  // to Windows event log.
     8  package eventlog
     9  
    10  import (
    11  	"bytes"
    12  	"encoding/json"
    13  	"io"
    14  
    15  	"github.com/rs/zerolog"
    16  	cbor "github.com/toravir/csd/libs"
    17  
    18  	"golang.org/x/sys/windows/svc/debug"
    19  	"golang.org/x/sys/windows/svc/eventlog"
    20  )
    21  
    22  // NewEventlogWriter returns a zerolog log destination
    23  // to be used as parameter to New() calls. Writing logs
    24  // to this writer will send the log messages to windows
    25  // event log running on this system.
    26  func NewEventlogWriter(svcName string) (io.WriteCloser, error) {
    27  	elog, err := eventlog.Open(svcName)
    28  	if err != nil {
    29  		return nil, err
    30  	}
    31  
    32  	return eventlogWriter{
    33  		elog: elog,
    34  	}, nil
    35  }
    36  
    37  type eventlogWriter struct {
    38  	elog debug.Log
    39  }
    40  
    41  func levelToJEventLevel(zLevel string) int {
    42  	lvl, _ := zerolog.ParseLevel(zLevel)
    43  
    44  	switch lvl {
    45  	case zerolog.TraceLevel:
    46  		return eventlog.Info
    47  	case zerolog.DebugLevel:
    48  		return eventlog.Info
    49  	case zerolog.InfoLevel:
    50  		return eventlog.Info
    51  	case zerolog.WarnLevel:
    52  		return eventlog.Warning
    53  	case zerolog.ErrorLevel:
    54  		return eventlog.Error
    55  	case zerolog.FatalLevel:
    56  		return eventlog.Error
    57  	case zerolog.PanicLevel:
    58  		return eventlog.Error
    59  	case zerolog.NoLevel:
    60  		return eventlog.Info
    61  	}
    62  	return eventlog.Info
    63  }
    64  
    65  func (w eventlogWriter) Close() error {
    66  	return w.elog.Close()
    67  }
    68  
    69  func (w eventlogWriter) Write(p []byte) (n int, err error) {
    70  	var event map[string]interface{}
    71  	p = cbor.DecodeIfBinaryToBytes(p)
    72  	d := json.NewDecoder(bytes.NewReader(p))
    73  	d.UseNumber()
    74  	err = d.Decode(&event)
    75  	jPrio := eventlog.Info
    76  	if err != nil {
    77  		return
    78  	}
    79  	if l, ok := event[zerolog.LevelFieldName].(string); ok {
    80  		jPrio = levelToJEventLevel(l)
    81  	}
    82  
    83  	switch jPrio {
    84  	case eventlog.Error:
    85  		w.elog.Error(1, string(p))
    86  	case eventlog.Warning:
    87  		w.elog.Warning(1, string(p))
    88  	default:
    89  		w.elog.Info(1, string(p))
    90  	}
    91  
    92  	return
    93  }