vitess.io/vitess@v0.16.2/go/event/syslogger/syslogger.go (about) 1 /* 2 Copyright 2019 The Vitess Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 /* 18 Package syslogger uses the event package to listen for any event that 19 implements the Syslogger interface. The listener calls the Syslog method on the 20 event, which should return a severity and a message. 21 22 The tag for messages sent to syslog will be the program name (os.Args[0]), 23 and the facility number will be 1 (user-level). 24 25 For example, to declare that your event type MyEvent should be sent to syslog, 26 implement the Syslog() method to define how the message should be formatted and 27 which severity it should have (see package "log/syslog" for details). 28 29 import ( 30 "fmt" 31 "log/syslog" 32 "syslogger" 33 ) 34 35 type MyEvent struct { 36 field1, field2 string 37 } 38 39 func (ev *MyEvent) Syslog() (syslog.Priority, string) { 40 return syslog.LOG_INFO, fmt.Sprintf("event: %v, %v", ev.field1, ev.field2) 41 } 42 var _ syslogger.Syslogger = (*MyEvent)(nil) // compile-time interface check 43 44 The compile-time interface check is optional but recommended because usually 45 there is no other static conversion in these cases. See: 46 47 http://golang.org/doc/effective_go.html#blank_implements 48 */ 49 package syslogger 50 51 import ( 52 "fmt" 53 "log/syslog" 54 "os" 55 56 "vitess.io/vitess/go/event" 57 "vitess.io/vitess/go/vt/log" 58 ) 59 60 // Syslogger is the interface that events should implement if they want to be 61 // dispatched to this package. 62 type Syslogger interface { 63 // Syslog should return a severity (not a facility) and a message. 64 Syslog() (syslog.Priority, string) 65 } 66 67 // syslogWriter is an interface that wraps syslog.Writer so it can be faked. 68 type syslogWriter interface { 69 Alert(string) error 70 Crit(string) error 71 Debug(string) error 72 Emerg(string) error 73 Err(string) error 74 Info(string) error 75 Notice(string) error 76 Warning(string) error 77 } 78 79 // writer holds a persistent connection to the syslog daemon 80 var writer syslogWriter 81 82 func listener(ev Syslogger) { 83 // Ask the event to convert itself to a syslog message. 84 sev, msg := ev.Syslog() 85 86 // Call the corresponding Writer function. 87 var err error 88 switch sev { 89 case syslog.LOG_EMERG: 90 if writer != nil { 91 err = writer.Emerg(msg) 92 } else { 93 log.Errorf(msg) 94 } 95 case syslog.LOG_ALERT: 96 if writer != nil { 97 err = writer.Alert(msg) 98 } else { 99 log.Errorf(msg) 100 } 101 case syslog.LOG_CRIT: 102 if writer != nil { 103 err = writer.Crit(msg) 104 } else { 105 log.Errorf(msg) 106 } 107 case syslog.LOG_ERR: 108 if writer != nil { 109 err = writer.Err(msg) 110 } else { 111 log.Errorf(msg) 112 } 113 case syslog.LOG_WARNING: 114 if writer != nil { 115 err = writer.Warning(msg) 116 } else { 117 log.Warningf(msg) 118 } 119 case syslog.LOG_NOTICE: 120 if writer != nil { 121 err = writer.Notice(msg) 122 } else { 123 log.Infof(msg) 124 } 125 case syslog.LOG_INFO: 126 if writer != nil { 127 err = writer.Info(msg) 128 } else { 129 log.Infof(msg) 130 } 131 case syslog.LOG_DEBUG: 132 if writer != nil { 133 err = writer.Debug(msg) 134 } else { 135 log.Infof(msg) 136 } 137 default: 138 err = fmt.Errorf("invalid syslog severity: %v", sev) 139 } 140 if err != nil { 141 log.Errorf("can't write syslog event: %v", err) 142 } 143 } 144 145 func init() { 146 var err error 147 writer, err = syslog.New(syslog.LOG_INFO|syslog.LOG_USER, os.Args[0]) 148 if err != nil { 149 log.Errorf("can't connect to syslog") 150 writer = nil 151 } 152 153 event.AddListener(listener) 154 }