github.com/sujit-baniya/log@v1.0.73/eventlog.go (about) 1 //go:build windows 2 // +build windows 3 4 package log 5 6 import ( 7 "errors" 8 "sync" 9 "syscall" 10 "unsafe" 11 ) 12 13 // EventlogWriter is an Writer that writes logs to windows event log. 14 type EventlogWriter struct { 15 // Event Source, must not be empty 16 Source string 17 18 // Event ID, using `eid` key in log event if not empty 19 ID uintptr 20 21 // Event Host, optional 22 Host string 23 24 once sync.Once 25 register *syscall.LazyProc 26 deregister *syscall.LazyProc 27 report *syscall.LazyProc 28 handle uintptr 29 } 30 31 // Write implements io.Closer. 32 func (w *EventlogWriter) Close() (err error) { 33 var ret uintptr 34 ret, _, err = syscall.Syscall(w.deregister.Addr(), 1, w.handle, 0, 0) 35 if ret > 0 { 36 err = nil 37 } 38 return 39 } 40 41 // WriteEntry implements Writer. 42 func (w *EventlogWriter) WriteEntry(e *Entry) (n int, err error) { 43 w.once.Do(func() { 44 if w.ID == 0 { 45 err = errors.New("Specify eventlog default id") 46 return 47 } 48 49 if w.Source == "" { 50 err = errors.New("Specify eventlog source") 51 return 52 } 53 54 var s *uint16 55 if w.Host != "" { 56 s = syscall.StringToUTF16Ptr(w.Host) 57 } 58 59 advapi32 := syscall.NewLazyDLL("advapi32.dll") 60 w.register = advapi32.NewProc("RegisterEventSourceW") 61 w.deregister = advapi32.NewProc("DeregisterEventSource") 62 w.report = advapi32.NewProc("ReportEventW") 63 64 w.handle, _, err = syscall.Syscall(w.register.Addr(), 2, uintptr(unsafe.Pointer(s)), uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(w.Source))), 0) 65 if w.handle != 0 { 66 err = nil 67 } 68 }) 69 70 if err != nil { 71 return 72 } 73 74 const ( 75 EVENTLOG_SUCCESS = 0x0000 76 EVENTLOG_ERROR_TYPE = 0x0001 77 EVENTLOG_WARNING_TYPE = 0x0002 78 EVENTLOG_INFORMATION_TYPE = 0x0004 79 EVENTLOG_AUDIT_SUCCESS = 0x0008 80 EVENTLOG_AUDIT_FAILURE = 0x0010 81 ) 82 83 var etype uint16 84 switch e.Level { 85 case TraceLevel: 86 etype = EVENTLOG_INFORMATION_TYPE 87 case DebugLevel: 88 etype = EVENTLOG_INFORMATION_TYPE 89 case InfoLevel: 90 etype = EVENTLOG_INFORMATION_TYPE 91 case WarnLevel: 92 etype = EVENTLOG_WARNING_TYPE 93 case ErrorLevel: 94 etype = EVENTLOG_ERROR_TYPE 95 case FatalLevel: 96 etype = EVENTLOG_AUDIT_FAILURE 97 case PanicLevel: 98 etype = EVENTLOG_AUDIT_FAILURE 99 default: 100 etype = EVENTLOG_INFORMATION_TYPE 101 } 102 103 var ecat uintptr = 0 104 var eid = w.ID 105 var ss = []*uint16{syscall.StringToUTF16Ptr(b2s(e.buf))} 106 107 var ret uintptr 108 ret, _, err = syscall.Syscall9(w.report.Addr(), 9, w.handle, uintptr(etype), ecat, eid, 0, 1, 0, uintptr(unsafe.Pointer(&ss[0])), 0) 109 if ret > 0 { 110 err = nil 111 } 112 if err == nil { 113 n = len(e.buf) 114 } 115 116 return 117 } 118 119 var _ Writer = (*EventlogWriter)(nil)