Source file src/pkg/log/syslog/syslog.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14 package syslog
15
16 import (
17 "errors"
18 "fmt"
19 "log"
20 "net"
21 "os"
22 "strings"
23 "sync"
24 "time"
25 )
26
27
28
29
30
31 type Priority int
32
33 const severityMask = 0x07
34 const facilityMask = 0xf8
35
36 const (
37
38
39
40
41 LOG_EMERG Priority = iota
42 LOG_ALERT
43 LOG_CRIT
44 LOG_ERR
45 LOG_WARNING
46 LOG_NOTICE
47 LOG_INFO
48 LOG_DEBUG
49 )
50
51 const (
52
53
54
55
56 LOG_KERN Priority = iota << 3
57 LOG_USER
58 LOG_MAIL
59 LOG_DAEMON
60 LOG_AUTH
61 LOG_SYSLOG
62 LOG_LPR
63 LOG_NEWS
64 LOG_UUCP
65 LOG_CRON
66 LOG_AUTHPRIV
67 LOG_FTP
68 _
69 _
70 _
71 _
72 LOG_LOCAL0
73 LOG_LOCAL1
74 LOG_LOCAL2
75 LOG_LOCAL3
76 LOG_LOCAL4
77 LOG_LOCAL5
78 LOG_LOCAL6
79 LOG_LOCAL7
80 )
81
82
83 type Writer struct {
84 priority Priority
85 tag string
86 hostname string
87 network string
88 raddr string
89
90 mu sync.Mutex
91 conn net.Conn
92 }
93
94
95
96
97 func New(priority Priority, tag string) (w *Writer, err error) {
98 return Dial("", "", priority, tag)
99 }
100
101
102
103
104
105 func Dial(network, raddr string, priority Priority, tag string) (*Writer, error) {
106 if priority < 0 || priority > LOG_LOCAL7|LOG_DEBUG {
107 return nil, errors.New("log/syslog: invalid priority")
108 }
109
110 if tag == "" {
111 tag = os.Args[0]
112 }
113 hostname, _ := os.Hostname()
114
115 w := &Writer{
116 priority: priority,
117 tag: tag,
118 hostname: hostname,
119 network: network,
120 raddr: raddr,
121 }
122
123 w.mu.Lock()
124 defer w.mu.Unlock()
125
126 err := w.connect()
127 if err != nil {
128 return nil, err
129 }
130 return w, err
131 }
132
133
134
135 func (w *Writer) connect() (err error) {
136 if w.conn != nil {
137
138 w.conn.Close()
139 w.conn = nil
140 }
141
142 if w.network == "" {
143 w.conn, err = unixSyslog()
144 if w.hostname == "" {
145 w.hostname = "localhost"
146 }
147 } else {
148 var c net.Conn
149 c, err = net.Dial(w.network, w.raddr)
150 if err == nil {
151 w.conn = c
152 if w.hostname == "" {
153 w.hostname = c.LocalAddr().String()
154 }
155 }
156 }
157 return
158 }
159
160
161 func (w *Writer) Write(b []byte) (int, error) {
162 return w.writeAndRetry(w.priority, string(b))
163 }
164
165
166 func (w *Writer) Close() error {
167 w.mu.Lock()
168 defer w.mu.Unlock()
169
170 if w.conn != nil {
171 err := w.conn.Close()
172 w.conn = nil
173 return err
174 }
175 return nil
176 }
177
178
179
180 func (w *Writer) Emerg(m string) (err error) {
181 _, err = w.writeAndRetry(LOG_EMERG, m)
182 return err
183 }
184
185
186
187 func (w *Writer) Alert(m string) (err error) {
188 _, err = w.writeAndRetry(LOG_ALERT, m)
189 return err
190 }
191
192
193
194 func (w *Writer) Crit(m string) (err error) {
195 _, err = w.writeAndRetry(LOG_CRIT, m)
196 return err
197 }
198
199
200
201 func (w *Writer) Err(m string) (err error) {
202 _, err = w.writeAndRetry(LOG_ERR, m)
203 return err
204 }
205
206
207
208 func (w *Writer) Warning(m string) (err error) {
209 _, err = w.writeAndRetry(LOG_WARNING, m)
210 return err
211 }
212
213
214
215 func (w *Writer) Notice(m string) (err error) {
216 _, err = w.writeAndRetry(LOG_NOTICE, m)
217 return err
218 }
219
220
221
222 func (w *Writer) Info(m string) (err error) {
223 _, err = w.writeAndRetry(LOG_INFO, m)
224 return err
225 }
226
227
228
229 func (w *Writer) Debug(m string) (err error) {
230 _, err = w.writeAndRetry(LOG_DEBUG, m)
231 return err
232 }
233
234 func (w *Writer) writeAndRetry(p Priority, s string) (int, error) {
235 pr := (w.priority & facilityMask) | (p & severityMask)
236
237 w.mu.Lock()
238 defer w.mu.Unlock()
239
240 if w.conn != nil {
241 if n, err := w.write(pr, s); err == nil {
242 return n, err
243 }
244 }
245 if err := w.connect(); err != nil {
246 return 0, err
247 }
248 return w.write(pr, s)
249 }
250
251
252
253 func (w *Writer) write(p Priority, msg string) (int, error) {
254
255 nl := ""
256 if !strings.HasSuffix(msg, "\n") {
257 nl = "\n"
258 }
259
260 timestamp := time.Now().Format(time.RFC3339)
261 fmt.Fprintf(w.conn, "<%d>%s %s %s[%d]: %s%s",
262 p, timestamp, w.hostname,
263 w.tag, os.Getpid(), msg, nl)
264 return len(msg), nil
265 }
266
267
268
269
270
271 func NewLogger(p Priority, logFlag int) (*log.Logger, error) {
272 s, err := New(p, "")
273 if err != nil {
274 return nil, err
275 }
276 return log.New(s, "", logFlag), nil
277 }
View as plain text