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