Left: | ||
Right: |
LEFT | RIGHT |
---|---|
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 // The syslog package provides a simple interface to | 5 // The syslog package provides a simple interface to |
6 // the System Log service. It can send messages to the | 6 // the system log service. It can send messages to the |
rsc
2009/11/29 22:57:57
s/System Log/system log/
nictuku
2009/12/07 18:43:51
Done.
| |
7 // syslog daemon using UNIX sockets, or UDP and TCP | 7 // syslog daemon using UNIX domain sockets, UDP, or |
rsc
2009/11/29 22:57:57
s/UNIX sockets/Unix domain sockets/
nictuku
2009/12/07 18:43:51
Done.
| |
8 // streams. | 8 // TCP connections. |
rsc
2009/11/29 22:57:57
s/streams/connections/
nictuku
2009/12/07 18:43:51
Done.
| |
9 package syslog | 9 package syslog |
10 | 10 |
11 import ( | 11 import ( |
12 "io"; | |
rsc
2009/11/29 22:57:57
Please sort
nictuku
2009/12/07 18:43:51
Done.
| |
13 "fmt"; | 12 "fmt"; |
13 "log"; | |
14 "net"; | 14 "net"; |
15 "os"; | 15 "os"; |
16 "log"; | |
17 "strings"; | |
18 "strconv"; | |
19 ) | 16 ) |
17 | |
18 type Priority int | |
20 | 19 |
21 const ( | 20 const ( |
22 // From /usr/include/sys/syslog.h. | 21 // From /usr/include/sys/syslog.h. |
rsc
2009/11/29 22:57:57
Add
// These are the same on Linux, BSD, and OS X
nictuku
2009/12/07 18:43:51
Done.
| |
23 » LOG_EMERG» = iota; | 22 » // These are the same on Linux, BSD, and OS X. |
23 » LOG_EMERG» Priority» = iota; | |
24 LOG_ALERT; | 24 LOG_ALERT; |
25 LOG_CRIT; | 25 LOG_CRIT; |
26 LOG_ERR; | 26 LOG_ERR; |
27 LOG_WARNING; | 27 LOG_WARNING; |
28 LOG_NOTICE; | 28 LOG_NOTICE; |
29 LOG_INFO; | 29 LOG_INFO; |
30 LOG_DEBUG; | 30 LOG_DEBUG; |
31 ) | 31 ) |
32 | 32 |
33 // Syslog contains a message to be sent to the server, as well as optional | 33 // A Writer is a connection to a syslog server. |
rsc
2009/11/29 22:57:57
I'm not sure it makes sense to expose all this mec
nictuku
2009/12/07 18:43:51
Done. Note that using []byte for prefix doesn't ac
| |
34 // routing settings. | 34 type Writer struct { |
35 type Syslog struct { | 35 » priority» Priority; |
36 » // Log priority. | 36 » prefix» » string; |
37 » priority» int; | 37 » conn» » net.Conn; |
38 » // Identifies which program is sending the message. | |
39 » ident» string; | |
40 » // Type of network address. Common values are "unixgram", "udp" and "tcp ". | |
41 » network»string; | |
42 » // Local address name, for example an IP address. Leaving blank is a saf e choice. | |
43 » laddr» string; | |
44 » // Remote address name. For UDP and TCP, "host:port". | |
45 » // For UNIX sockets, the path of the socket file. | |
46 » raddr» string; | |
47 } | 38 } |
48 | 39 |
49 func (s Syslog) formatMsg(message []byte) []byte { | 40 // New establishes a new connection to the system log daemon. |
50 » p := strconv.Itoa(s.priority); | 41 // Each write to the returned writer sends a log message with |
rsc
2009/11/29 22:57:57
This can be just %d below.
In terms of the interf
nictuku
2009/12/07 18:43:51
strings.Bytes doesn't do formatting, but I did a s
| |
51 » m := string(message); | 42 // the given priority and prefix. |
rsc
2009/11/29 22:57:57
The conversion here is unnecessary.
You can pass m
nictuku
2009/12/07 18:43:51
Done. I got rid of this function and merged it int
| |
52 » msg := fmt.Sprintf("<%s>%s: %s\n", p, s.ident, m); | 43 func New(priority Priority, prefix string) (w *Writer, err os.Error) { |
53 » b := strings.Bytes(msg); | 44 » return Dial("", "", priority, prefix) |
54 » return b; | |
55 } | 45 } |
56 | 46 |
57 // Write sends the message to the System Log. | 47 // Dial establishes a connection to a log daemon by connecting |
58 func (s Syslog) Write(message []byte) (n int, err os.Error) { | 48 // to address raddr on the network net. |
59 » if s.priority > LOG_DEBUG || s.priority < LOG_EMERG { | 49 // Each write to the returned writer sends a log message with |
60 » » return 0, InvalidArgument("invalid priority") | 50 // the given priority and prefix. |
51 func Dial(network, raddr string, priority Priority, prefix string) (w *Writer, e rr os.Error) { | |
52 » if prefix == "" { | |
53 » » prefix = os.Args[0] | |
61 } | 54 } |
62 » if s.network == "" { | 55 » var conn net.Conn; |
63 » » err = s.unixSyslog(message) | 56 » if network == "" { |
64 » } else if s.raddr == "" { | 57 » » conn, err = unixSyslog() |
65 » » return 0, InvalidArgument("network specified without raddr") | |
66 | |
67 } else { | 58 } else { |
68 » » err = s.send(message) | 59 » » conn, err = net.Dial(network, "", raddr) |
69 } | 60 } |
70 » if err != nil { | 61 » return &Writer{priority, prefix, conn}, err; |
71 » » return 0, err | |
72 » } | |
73 » return len(message), nil; | |
74 } | 62 } |
75 | 63 |
76 func (s Syslog) send(message []byte) (err os.Error) { | 64 func unixSyslog() (conn net.Conn, err os.Error) { |
77 » if s.ident == "" { | 65 » logTypes := []string{"unixgram", "unix"}; |
78 » » s.ident = os.Args[0] | 66 » logPaths := []string{"/dev/log", "/var/run/syslog"}; |
67 » var raddr string; | |
68 » for _, network := range logTypes { | |
69 » » for _, path := range logPaths { | |
70 » » » raddr = path; | |
71 » » » conn, err := net.Dial(network, "", raddr); | |
72 » » » if err != nil { | |
73 » » » » continue | |
74 » » » } else { | |
75 » » » » return conn, nil | |
76 » » » } | |
77 » » } | |
79 } | 78 } |
80 » conn, err := net.Dial(s.network, s.laddr, s.raddr); | 79 » return nil, os.ErrorString("Unix syslog delivery error"); |
81 » // TODO(yvesj): Re-use the connection. | 80 } |
rsc
2009/11/29 22:57:57
Yes please - the interface sketched above makes th
nictuku
2009/12/07 18:43:51
Done.
| |
82 » defer conn.Close(); | 81 |
83 » if err == nil { | 82 // Write sends a log message to the syslog daemon. |
84 » » b := s.formatMsg(message); | 83 func (w *Writer) Write(b []byte) (int, os.Error) { |
85 » » _, err = conn.Write(b); | 84 » if w.priority > LOG_DEBUG || w.priority < LOG_EMERG { |
85 » » return 0, os.EINVAL | |
86 } | 86 } |
87 return fmt.Fprintf(w.conn, "<%d>%s: %s\n", w.priority, w.prefix, b); | |
88 } | |
89 | |
90 func (w *Writer) writeString(p Priority, s string) (int, os.Error) { | |
91 return fmt.Fprintf(w.conn, "<%d>%s: %s\n", p, w.prefix, s) | |
92 } | |
93 | |
94 func (w *Writer) Close() os.Error { return w.conn.Close() } | |
95 | |
96 // Emerg logs a message using the LOG_EMERG priority. | |
97 func (w *Writer) Emerg(m string) (err os.Error) { | |
98 _, err = w.writeString(LOG_EMERG, m); | |
99 return err; | |
100 } | |
101 // Crit logs a message using the LOG_CRIT priority. | |
102 func (w *Writer) Crit(m string) (err os.Error) { | |
103 _, err = w.writeString(LOG_CRIT, m); | |
104 return err; | |
105 } | |
106 // ERR logs a message using the LOG_ERR priority. | |
107 func (w *Writer) Err(m string) (err os.Error) { | |
108 _, err = w.writeString(LOG_ERR, m); | |
87 return err; | 109 return err; |
88 } | 110 } |
89 | 111 |
90 func (s Syslog) unixSyslog(message []byte) (err os.Error) { | 112 // Warning logs a message using the LOG_WARNING priority. |
91 » logTypes := []string{"unixgram", "unix"}; | 113 func (w *Writer) Warning(m string) (err os.Error) { |
92 » logPaths := []string{"/dev/log", "/var/run/syslog"}; | 114 » _, err = w.writeString(LOG_WARNING, m); |
93 » // If successful, learn the configuration used. | |
94 » for _, network := range logTypes { | |
95 » » s.network = network; | |
96 » » for _, path := range logPaths { | |
97 » » » s.raddr = path; | |
98 » » » err = s.send(message); | |
99 » » » if err != nil { | |
100 » » » » continue | |
101 » » » } else { | |
102 » » » » return nil | |
103 » » » } | |
104 » » } | |
105 » } | |
106 » // Forget what was learned since it's broken. | |
107 » s.network = ""; | |
108 » s.raddr = ""; | |
109 » return os.ErrorString("Unix syslog delivery error"); | |
110 } | |
111 | |
112 | |
113 // Convenience functions that logs a message using the requested severity. | |
114 func (s Syslog) Emerg(message string) (err os.Error) { | |
115 » s.priority = LOG_EMERG; | |
116 » _, err = io.WriteString(s, message); | |
117 » return err; | |
118 } | |
119 func (s Syslog) Crit(message string) (err os.Error) { | |
120 » s.priority = LOG_CRIT; | |
121 » _, err = io.WriteString(s, message); | |
122 return err; | 115 return err; |
123 } | 116 } |
124 | 117 |
125 func (s Syslog) Err(message string) (err os.Error) { | 118 // Notice logs a message using the LOG_NOTICE priority. |
126 » s.priority = LOG_ERR; | 119 func (w *Writer) Notice(m string) (err os.Error) { |
127 » _, err = io.WriteString(s, message); | 120 » _, err = w.writeString(LOG_NOTICE, m); |
121 » return err; | |
122 } | |
123 // Info logs a message using the LOG_INFO priority. | |
124 func (w *Writer) Info(m string) (err os.Error) { | |
125 » _, err = w.writeString(LOG_INFO, m); | |
126 » return err; | |
127 } | |
128 // Debug logs a message using the LOG_DEBUG priority. | |
129 func (w *Writer) Debug(m string) (err os.Error) { | |
130 » _, err = w.writeString(LOG_DEBUG, m); | |
128 return err; | 131 return err; |
129 } | 132 } |
130 | 133 |
131 // DEPRECATED | 134 // NewLogger provides an object that implements the full log.Logger interface, |
132 // Error = Err | 135 // but sends messages to Syslog instead; flag is passed as is to Logger; |
133 | 136 // priority will be used for all messages sent using this interface. |
134 func (s Syslog) Warning(message string) (err os.Error) { | 137 // All messages are logged with priority p. |
135 » s.priority = LOG_WARNING; | 138 func NewLogger(p Priority, flag int) *log.Logger { |
136 » _, err = io.WriteString(s, message); | 139 » s, err := New(p, ""); |
137 » return err; | 140 » if err != nil { |
141 » » return nil | |
142 » } | |
143 » return log.New(s, nil, "", flag); | |
138 } | 144 } |
139 | |
140 // DEPRECATED | |
141 // Warn = Warning | |
142 | |
143 func (s Syslog) Notice(message string) (err os.Error) { | |
144 s.priority = LOG_NOTICE; | |
145 _, err = io.WriteString(s, message); | |
146 return err; | |
147 } | |
148 | |
149 func (s Syslog) Info(message string) (err os.Error) { | |
150 s.priority = LOG_INFO; | |
151 _, err = io.WriteString(s, message); | |
152 return err; | |
153 } | |
154 | |
155 func (s Syslog) Debug(message string) (err os.Error) { | |
156 s.priority = LOG_DEBUG; | |
157 _, err = io.WriteString(s, message); | |
158 return err; | |
159 } | |
160 | |
161 // New creates a new Syslog object. It sets a default priority of LOG_INFO for | |
162 // messages. Use one of the "Level" method levels to send messages using specifi c | |
163 // priorities. For example: | |
164 // | |
165 // s := syslog.New(); | |
166 // s.Err("My Error") | |
167 // s.Debug("Debug Message") | |
168 // | |
169 func New(ident string) *Syslog { return &Syslog{LOG_INFO, ident, "", "", ""} } | |
170 | |
171 // NewLn creates a new Syslog object. | |
172 // See that object documentation for details on the parameters; | |
rsc
2009/11/29 22:57:57
The object documentation is invisible because the
nictuku
2009/12/07 18:43:51
Deprecated this function in favor of Dial.
| |
173 func NewLn(ident string, priority int, net, laddr, raddr string) *Syslog { | |
174 return &Syslog{priority, ident, net, laddr, raddr} | |
175 } | |
176 | |
177 // NewLogger provides an object that implements the full log.Logger interface, | |
178 // but sends messages to Syslog instead; priority will be used for all messages | |
179 // sent using this interface; if you need more control, use the Syslog interface | |
180 // instead - see 'New' and 'NewLn'. | |
181 func NewLogger(priority int) *log.Logger { | |
rsc
2009/11/29 22:57:57
Maybe this should take two arguments
func NewLogg
nictuku
2009/12/07 18:43:51
Done.
| |
182 s := Syslog{priority, "", "", "", ""}; | |
183 return log.New(s, nil, "", 0); | |
184 } | |
185 | |
186 type InvalidArgument string | |
187 | |
188 func (e InvalidArgument) String() string { return "Invalid argument: " + string(e) } | |
LEFT | RIGHT |