github.com/nats-io/nats-server/v2@v2.11.0-preview.2/logger/syslog.go (about) 1 // Copyright 2012-2019 The NATS Authors 2 // Licensed under the Apache License, Version 2.0 (the "License"); 3 // you may not use this file except in compliance with the License. 4 // You may obtain a copy of the License at 5 // 6 // http://www.apache.org/licenses/LICENSE-2.0 7 // 8 // Unless required by applicable law or agreed to in writing, software 9 // distributed under the License is distributed on an "AS IS" BASIS, 10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 //go:build !windows 15 // +build !windows 16 17 package logger 18 19 import ( 20 "fmt" 21 "log" 22 "log/syslog" 23 "net/url" 24 "os" 25 "strings" 26 ) 27 28 // SysLogger provides a system logger facility 29 type SysLogger struct { 30 writer *syslog.Writer 31 debug bool 32 trace bool 33 } 34 35 // SetSyslogName sets the name to use for the syslog. 36 // Currently used only on Windows. 37 func SetSyslogName(name string) {} 38 39 // GetSysLoggerTag generates the tag name for use in syslog statements. If 40 // the executable is linked, the name of the link will be used as the tag, 41 // otherwise, the name of the executable is used. "nats-server" is the default 42 // for the NATS server. 43 func GetSysLoggerTag() string { 44 procName := os.Args[0] 45 if strings.ContainsRune(procName, os.PathSeparator) { 46 parts := strings.FieldsFunc(procName, func(c rune) bool { 47 return c == os.PathSeparator 48 }) 49 procName = parts[len(parts)-1] 50 } 51 return procName 52 } 53 54 // NewSysLogger creates a new system logger 55 func NewSysLogger(debug, trace bool) *SysLogger { 56 w, err := syslog.New(syslog.LOG_DAEMON|syslog.LOG_NOTICE, GetSysLoggerTag()) 57 if err != nil { 58 log.Fatalf("error connecting to syslog: %q", err.Error()) 59 } 60 61 return &SysLogger{ 62 writer: w, 63 debug: debug, 64 trace: trace, 65 } 66 } 67 68 // NewRemoteSysLogger creates a new remote system logger 69 func NewRemoteSysLogger(fqn string, debug, trace bool) *SysLogger { 70 network, addr := getNetworkAndAddr(fqn) 71 w, err := syslog.Dial(network, addr, syslog.LOG_DEBUG, GetSysLoggerTag()) 72 if err != nil { 73 log.Fatalf("error connecting to syslog: %q", err.Error()) 74 } 75 76 return &SysLogger{ 77 writer: w, 78 debug: debug, 79 trace: trace, 80 } 81 } 82 83 func getNetworkAndAddr(fqn string) (network, addr string) { 84 u, err := url.Parse(fqn) 85 if err != nil { 86 log.Fatal(err) 87 } 88 89 network = u.Scheme 90 if network == "udp" || network == "tcp" { 91 addr = u.Host 92 } else if network == "unix" { 93 addr = u.Path 94 } else { 95 log.Fatalf("error invalid network type: %q", u.Scheme) 96 } 97 98 return 99 } 100 101 // Noticef logs a notice statement 102 func (l *SysLogger) Noticef(format string, v ...any) { 103 l.writer.Notice(fmt.Sprintf(format, v...)) 104 } 105 106 // Warnf logs a warning statement 107 func (l *SysLogger) Warnf(format string, v ...any) { 108 l.writer.Warning(fmt.Sprintf(format, v...)) 109 } 110 111 // Fatalf logs a fatal error 112 func (l *SysLogger) Fatalf(format string, v ...any) { 113 l.writer.Crit(fmt.Sprintf(format, v...)) 114 } 115 116 // Errorf logs an error statement 117 func (l *SysLogger) Errorf(format string, v ...any) { 118 l.writer.Err(fmt.Sprintf(format, v...)) 119 } 120 121 // Debugf logs a debug statement 122 func (l *SysLogger) Debugf(format string, v ...any) { 123 if l.debug { 124 l.writer.Debug(fmt.Sprintf(format, v...)) 125 } 126 } 127 128 // Tracef logs a trace statement 129 func (l *SysLogger) Tracef(format string, v ...any) { 130 if l.trace { 131 l.writer.Notice(fmt.Sprintf(format, v...)) 132 } 133 }