common/defaultlog_windows.go (52 lines of code) (raw):

// Copyright © Microsoft <wastore@microsoft.com> // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. package common import ( "os" "syscall" "unsafe" ) // forceLog should rarely be used. It forceable logs an entry to the // Windows Event Log (on Windows) or to the SysLog (on Linux) func forceLog(level LogLevel, msg string) { var el eventType switch level { case LogError, LogFatal, LogPanic: el = elError case LogWarning: el = elWarning case LogInfo: el = elInfo } // We are logging it, ensure trailing newline if len(msg) == 0 || msg[len(msg)-1] != '\n' { msg += "\n" // Ensure trailing newline } reportEvent(el, 0, msg) } type eventType int16 const ( elSuccess eventType = 0 elError eventType = 1 elWarning eventType = 2 elInfo eventType = 4 ) var reportEvent = func() func(eventType eventType, eventID int32, msg string) { advAPI32 := syscall.MustLoadDLL("advapi32.dll") // lower case to tie in with Go's sysdll registration registerEventSource := advAPI32.MustFindProc("RegisterEventSourceW") sourceName, _ := os.Executable() sourceNameUTF16, _ := syscall.UTF16PtrFromString(sourceName) handle, _, lastErr := registerEventSource.Call(uintptr(0), uintptr(unsafe.Pointer(sourceNameUTF16))) if lastErr == nil { // On error, logging is a no-op return func(eventType eventType, eventID int32, msg string) {} } reportEvent := advAPI32.MustFindProc("ReportEventW") return func(eventType eventType, eventID int32, msg string) { s, _ := syscall.UTF16PtrFromString(msg) _, _, _ = reportEvent.Call( uintptr(handle), // HANDLE hEventLog uintptr(eventType), // WORD wType uintptr(0), // WORD wCategory uintptr(eventID), // DWORD dwEventID uintptr(0), // PSID lpUserSid uintptr(1), // WORD wNumStrings uintptr(0), // DWORD dwDataSize uintptr(unsafe.Pointer(&s)), // LPCTSTR *lpStrings uintptr(0)) // LPVOID lpRawData } }()