Left: | ||
Right: |
OLD | NEW |
---|---|
1 // Copyright 2009 The Go Authors. All rights reserved. | 1 // Copyright 2009 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 // +build !windows,!plan9 | 5 // +build !windows,!plan9 |
6 | 6 |
7 // Package syslog provides a simple interface to the system log | 7 // Package syslog provides a simple interface to the system log |
8 // service. It can send messages to the syslog daemon using UNIX | 8 // service. It can send messages to the syslog daemon using UNIX |
9 // domain sockets, UDP, or TCP connections. | 9 // domain sockets, UDP, or TCP connections. |
10 package syslog | 10 package syslog |
11 | 11 |
12 import ( | 12 import ( |
13 "errors" | 13 "errors" |
14 "fmt" | 14 "fmt" |
15 "log" | 15 "log" |
16 "net" | 16 "net" |
17 "os" | 17 "os" |
18 "sync" | |
18 "time" | 19 "time" |
19 ) | 20 ) |
20 | 21 |
21 // The Priority is a combination of the syslog facility and | 22 // The Priority is a combination of the syslog facility and |
22 // severity. For example, LOG_ALERT | LOG_FTP sends an alert severity | 23 // severity. For example, LOG_ALERT | LOG_FTP sends an alert severity |
23 // message from the FTP facility. The default severity is LOG_EMERG; | 24 // message from the FTP facility. The default severity is LOG_EMERG; |
24 // the default facility is LOG_KERN. | 25 // the default facility is LOG_KERN. |
25 type Priority int | 26 type Priority int |
26 | 27 |
27 const severityMask = 0x07 | 28 const severityMask = 0x07 |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
71 LOG_LOCAL5 | 72 LOG_LOCAL5 |
72 LOG_LOCAL6 | 73 LOG_LOCAL6 |
73 LOG_LOCAL7 | 74 LOG_LOCAL7 |
74 ) | 75 ) |
75 | 76 |
76 // A Writer is a connection to a syslog server. | 77 // A Writer is a connection to a syslog server. |
77 type Writer struct { | 78 type Writer struct { |
78 priority Priority | 79 priority Priority |
79 tag string | 80 tag string |
80 hostname string | 81 hostname string |
81 » conn serverConn | 82 » network string |
83 » raddr string | |
84 | |
85 » mu sync.Mutex // guards conn | |
86 » conn serverConn | |
82 } | 87 } |
83 | 88 |
84 type serverConn interface { | 89 type serverConn interface { |
mikio
2012/12/16 06:54:17
I think this interface is unnecessary unless you w
jeff.allen
2012/12/18 15:18:03
Done.
| |
85 writeString(p Priority, hostname, tag, s string) (int, error) | 90 writeString(p Priority, hostname, tag, s string) (int, error) |
86 close() error | 91 close() error |
87 } | 92 } |
88 | 93 |
89 type netConn struct { | 94 type netConn struct { |
mikio
2012/12/16 06:54:17
ditto.
jeff.allen
2012/12/18 15:18:03
Done.
| |
90 conn net.Conn | 95 conn net.Conn |
91 } | 96 } |
92 | 97 |
93 // New establishes a new connection to the system log daemon. Each | 98 // New establishes a new connection to the system log daemon. Each |
94 // write to the returned writer sends a log message with the given | 99 // write to the returned writer sends a log message with the given |
95 // priority and prefix. | 100 // priority and prefix. |
96 func New(priority Priority, tag string) (w *Writer, err error) { | 101 func New(priority Priority, tag string) (w *Writer, err error) { |
97 return Dial("", "", priority, tag) | 102 return Dial("", "", priority, tag) |
98 } | 103 } |
99 | 104 |
100 // Dial establishes a connection to a log daemon by connecting to | 105 // Dial establishes a connection to a log daemon by connecting to |
101 // address raddr on the network net. Each write to the returned | 106 // address raddr on the network net. Each write to the returned |
102 // writer sends a log message with the given facility, severity and | 107 // writer sends a log message with the given facility, severity and |
103 // tag. | 108 // tag. |
104 func Dial(network, raddr string, priority Priority, tag string) (w *Writer, err error) { | 109 func Dial(network, raddr string, priority Priority, tag string) (*Writer, error) { |
105 if priority < 0 || priority > LOG_LOCAL7|LOG_DEBUG { | 110 if priority < 0 || priority > LOG_LOCAL7|LOG_DEBUG { |
106 return nil, errors.New("log/syslog: invalid priority") | 111 return nil, errors.New("log/syslog: invalid priority") |
107 } | 112 } |
108 | 113 |
109 if tag == "" { | 114 if tag == "" { |
110 tag = os.Args[0] | 115 tag = os.Args[0] |
111 } | 116 } |
112 | |
113 hostname, _ := os.Hostname() | 117 hostname, _ := os.Hostname() |
114 | 118 |
115 » var conn serverConn | 119 » w := &Writer{ |
116 » if network == "" { | 120 » » priority: priority, |
117 » » conn, err = unixSyslog() | 121 » » tag: tag, |
118 » » if hostname == "" { | 122 » » hostname: hostname, |
119 » » » hostname = "localhost" | 123 » » network: network, |
124 » » raddr: raddr, | |
125 » } | |
126 | |
127 » // w.mu not held, but w is still private to us at this point | |
128 » err := w.connect() | |
129 » if err != nil { | |
130 » » return nil, err | |
131 » } | |
132 » return w, err | |
133 } | |
134 | |
135 // (*Writer).connect makes a connection to the syslog server. | |
136 // It must be called with w.mu held. | |
137 func (w *Writer) connect() (err error) { | |
138 » if w.conn != nil { | |
139 » » // ignore err from close, it makes sense to continue anyway | |
140 » » w.conn.close() | |
141 » » w.conn = nil | |
142 » } | |
143 | |
144 » if w.network == "" { | |
145 » » w.conn, err = unixSyslog() | |
146 » » if w.hostname == "" { | |
147 » » » w.hostname = "localhost" | |
120 } | 148 } |
121 } else { | 149 } else { |
122 var c net.Conn | 150 var c net.Conn |
123 » » c, err = net.Dial(network, raddr) | 151 » » c, err = net.Dial(w.network, w.raddr) |
124 » » conn = netConn{c} | 152 » » if err == nil { |
125 » » if hostname == "" { | 153 » » » w.conn = netConn{c} |
126 » » » hostname = c.LocalAddr().String() | 154 » » » if w.hostname == "" { |
155 » » » » w.hostname = c.LocalAddr().String() | |
156 » » » } | |
127 } | 157 } |
128 } | 158 } |
129 » if err != nil { | 159 » return |
130 » » return nil, err | |
131 » } | |
132 | |
133 » return &Writer{priority: priority, tag: tag, hostname: hostname, conn: c onn}, nil | |
134 } | 160 } |
135 | 161 |
136 // Write sends a log message to the syslog daemon. | 162 // Write sends a log message to the syslog daemon. |
137 func (w *Writer) Write(b []byte) (int, error) { | 163 func (w *Writer) Write(b []byte) (int, error) { |
138 return w.writeString(w.priority, string(b)) | 164 return w.writeString(w.priority, string(b)) |
139 } | 165 } |
140 | 166 |
141 func (w *Writer) Close() error { return w.conn.close() } | 167 func (w *Writer) Close() error { |
mikio
2012/12/16 06:54:17
Close is exposed so it needs comments.
jeff.allen
2012/12/18 15:18:03
Done.
| |
168 » w.mu.Lock() | |
169 » defer w.mu.Unlock() | |
170 | |
171 » if w.conn != nil { | |
172 » » err := w.conn.close() | |
173 » » w.conn = nil | |
174 » » return err | |
175 » } | |
176 » return nil | |
177 } | |
142 | 178 |
143 // Emerg logs a message with severity LOG_EMERG, ignoring the severity | 179 // Emerg logs a message with severity LOG_EMERG, ignoring the severity |
144 // passed to New. | 180 // passed to New. |
145 func (w *Writer) Emerg(m string) (err error) { | 181 func (w *Writer) Emerg(m string) (err error) { |
146 _, err = w.writeString(LOG_EMERG, m) | 182 _, err = w.writeString(LOG_EMERG, m) |
147 return err | 183 return err |
148 } | 184 } |
149 | 185 |
150 // Alert logs a message with severity LOG_ALERT, ignoring the severity | 186 // Alert logs a message with severity LOG_ALERT, ignoring the severity |
151 // passed to New. | 187 // passed to New. |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
190 } | 226 } |
191 | 227 |
192 // Debug logs a message with severity LOG_DEBUG, ignoring the severity | 228 // Debug logs a message with severity LOG_DEBUG, ignoring the severity |
193 // passed to New. | 229 // passed to New. |
194 func (w *Writer) Debug(m string) (err error) { | 230 func (w *Writer) Debug(m string) (err error) { |
195 _, err = w.writeString(LOG_DEBUG, m) | 231 _, err = w.writeString(LOG_DEBUG, m) |
196 return err | 232 return err |
197 } | 233 } |
198 | 234 |
199 func (w *Writer) writeString(p Priority, s string) (int, error) { | 235 func (w *Writer) writeString(p Priority, s string) (int, error) { |
200 » return w.conn.writeString((w.priority&facilityMask)|(p&severityMask), | 236 » w.mu.Lock() |
237 » defer w.mu.Unlock() | |
238 | |
239 » if w.conn == nil { | |
mikio
2012/12/16 06:54:17
I'm not keen to manage a conn state with write-onl
jeff.allen
2012/12/18 15:18:03
I think the correct approach to this risk is to re
| |
240 » » err := w.connect() | |
241 » » if err != nil { | |
242 » » » return 0, err | |
243 » » } | |
244 » } | |
245 » n, err := w.conn.writeString((w.priority&facilityMask)|(p&severityMask), | |
201 w.hostname, w.tag, s) | 246 w.hostname, w.tag, s) |
247 if err != nil { | |
248 // try once to reconnect, to handle the case where | |
249 // the unix socket was closed and reopened by a restarting | |
250 // syslogd. | |
251 err = w.connect() | |
252 if err != nil { | |
253 return 0, err | |
254 } | |
255 n, err = w.conn.writeString((w.priority&facilityMask)|(p&severit yMask), | |
256 w.hostname, w.tag, s) | |
257 } | |
258 return n, err | |
202 } | 259 } |
203 | 260 |
204 // writeString: generates and writes a syslog formatted string. The | 261 // writeString: generates and writes a syslog formatted string. The |
205 // format is as follows: <PRI>1 TIMESTAMP HOSTNAME TAG[PID]: MSG | 262 // format is as follows: <PRI>1 TIMESTAMP HOSTNAME TAG[PID]: MSG |
206 func (n netConn) writeString(p Priority, hostname, tag, msg string) (int, error) { | 263 func (n netConn) writeString(p Priority, hostname, tag, msg string) (int, error) { |
207 nl := "" | 264 nl := "" |
208 if len(msg) == 0 || msg[len(msg)-1] != '\n' { | 265 if len(msg) == 0 || msg[len(msg)-1] != '\n' { |
209 nl = "\n" | 266 nl = "\n" |
210 } | 267 } |
211 timestamp := time.Now().Format(time.RFC3339) | 268 timestamp := time.Now().Format(time.RFC3339) |
(...skipping 12 matching lines...) Expand all Loading... | |
224 // the system log service with the specified priority. The logFlag | 281 // the system log service with the specified priority. The logFlag |
225 // argument is the flag set passed through to log.New to create | 282 // argument is the flag set passed through to log.New to create |
226 // the Logger. | 283 // the Logger. |
227 func NewLogger(p Priority, logFlag int) (*log.Logger, error) { | 284 func NewLogger(p Priority, logFlag int) (*log.Logger, error) { |
228 s, err := New(p, "") | 285 s, err := New(p, "") |
229 if err != nil { | 286 if err != nil { |
230 return nil, err | 287 return nil, err |
231 } | 288 } |
232 return log.New(s, "", logFlag), nil | 289 return log.New(s, "", logFlag), nil |
233 } | 290 } |
OLD | NEW |