1
2
3
4
5
6
7
8
9
10
11
12
13
14 package ch.qos.logback.core.net;
15
16 import java.io.IOException;
17 import java.io.OutputStream;
18 import java.net.SocketException;
19 import java.net.UnknownHostException;
20 import java.nio.charset.Charset;
21
22 import ch.qos.logback.core.AppenderBase;
23 import ch.qos.logback.core.CoreConstants;
24 import ch.qos.logback.core.Layout;
25
26
27
28
29
30
31
32
33 public abstract class SyslogAppenderBase<E> extends AppenderBase<E> {
34
35 final static String SYSLOG_LAYOUT_URL = CoreConstants.CODES_URL + "#syslog_layout";
36 final static int MAX_MESSAGE_SIZE_LIMIT = 65000;
37
38 Layout<E> layout;
39 String facilityStr;
40 String syslogHost;
41 protected String suffixPattern;
42 SyslogOutputStream sos;
43 int port = SyslogConstants.SYSLOG_PORT;
44 int maxMessageSize;
45 Charset charset;
46
47 public void start() {
48 int errorCount = 0;
49 if (facilityStr == null) {
50 addError("The Facility option is mandatory");
51 errorCount++;
52 }
53
54 if (charset == null) {
55
56
57
58 charset = Charset.defaultCharset();
59 }
60
61 try {
62 sos = createOutputStream();
63
64 final int systemDatagramSize = sos.getSendBufferSize();
65 if (maxMessageSize == 0) {
66 maxMessageSize = Math.min(systemDatagramSize, MAX_MESSAGE_SIZE_LIMIT);
67 addInfo("Defaulting maxMessageSize to [" + maxMessageSize + "]");
68 } else if (maxMessageSize > systemDatagramSize) {
69 addWarn("maxMessageSize of [" + maxMessageSize
70 + "] is larger than the system defined datagram size of [" + systemDatagramSize + "].");
71 addWarn("This may result in dropped logs.");
72 }
73 } catch (UnknownHostException e) {
74 addError("Could not create SyslogWriter", e);
75 errorCount++;
76 } catch (SocketException e) {
77 addWarn("Failed to bind to a random datagram socket. Will try to reconnect later.", e);
78 }
79
80 if (layout == null) {
81 layout = buildLayout();
82 }
83
84 if (errorCount == 0) {
85 super.start();
86 }
87 }
88
89 abstract public SyslogOutputStream createOutputStream() throws UnknownHostException, SocketException;
90
91 abstract public Layout<E> buildLayout();
92
93 abstract public int getSeverityForEvent(Object eventObject);
94
95 @Override
96 protected void append(E eventObject) {
97 if (!isStarted()) {
98 return;
99 }
100
101 try {
102 String msg = layout.doLayout(eventObject);
103 if (msg == null) {
104 return;
105 }
106 if (msg.length() > maxMessageSize) {
107 msg = msg.substring(0, maxMessageSize);
108 }
109 sos.write(msg.getBytes(charset));
110 sos.flush();
111 postProcess(eventObject, sos);
112 } catch (IOException ioe) {
113 addError("Failed to send diagram to " + syslogHost, ioe);
114 }
115 }
116
117 protected void postProcess(Object event, OutputStream sw) {
118
119 }
120
121
122
123
124
125
126 static public int facilityStringToint(String facilityStr) {
127 if ("KERN".equalsIgnoreCase(facilityStr)) {
128 return SyslogConstants.LOG_KERN;
129 } else if ("USER".equalsIgnoreCase(facilityStr)) {
130 return SyslogConstants.LOG_USER;
131 } else if ("MAIL".equalsIgnoreCase(facilityStr)) {
132 return SyslogConstants.LOG_MAIL;
133 } else if ("DAEMON".equalsIgnoreCase(facilityStr)) {
134 return SyslogConstants.LOG_DAEMON;
135 } else if ("AUTH".equalsIgnoreCase(facilityStr)) {
136 return SyslogConstants.LOG_AUTH;
137 } else if ("SYSLOG".equalsIgnoreCase(facilityStr)) {
138 return SyslogConstants.LOG_SYSLOG;
139 } else if ("LPR".equalsIgnoreCase(facilityStr)) {
140 return SyslogConstants.LOG_LPR;
141 } else if ("NEWS".equalsIgnoreCase(facilityStr)) {
142 return SyslogConstants.LOG_NEWS;
143 } else if ("UUCP".equalsIgnoreCase(facilityStr)) {
144 return SyslogConstants.LOG_UUCP;
145 } else if ("CRON".equalsIgnoreCase(facilityStr)) {
146 return SyslogConstants.LOG_CRON;
147 } else if ("AUTHPRIV".equalsIgnoreCase(facilityStr)) {
148 return SyslogConstants.LOG_AUTHPRIV;
149 } else if ("FTP".equalsIgnoreCase(facilityStr)) {
150 return SyslogConstants.LOG_FTP;
151 } else if ("NTP".equalsIgnoreCase(facilityStr)) {
152 return SyslogConstants.LOG_NTP;
153 } else if ("AUDIT".equalsIgnoreCase(facilityStr)) {
154 return SyslogConstants.LOG_AUDIT;
155 } else if ("ALERT".equalsIgnoreCase(facilityStr)) {
156 return SyslogConstants.LOG_ALERT;
157 } else if ("CLOCK".equalsIgnoreCase(facilityStr)) {
158 return SyslogConstants.LOG_CLOCK;
159 } else if ("LOCAL0".equalsIgnoreCase(facilityStr)) {
160 return SyslogConstants.LOG_LOCAL0;
161 } else if ("LOCAL1".equalsIgnoreCase(facilityStr)) {
162 return SyslogConstants.LOG_LOCAL1;
163 } else if ("LOCAL2".equalsIgnoreCase(facilityStr)) {
164 return SyslogConstants.LOG_LOCAL2;
165 } else if ("LOCAL3".equalsIgnoreCase(facilityStr)) {
166 return SyslogConstants.LOG_LOCAL3;
167 } else if ("LOCAL4".equalsIgnoreCase(facilityStr)) {
168 return SyslogConstants.LOG_LOCAL4;
169 } else if ("LOCAL5".equalsIgnoreCase(facilityStr)) {
170 return SyslogConstants.LOG_LOCAL5;
171 } else if ("LOCAL6".equalsIgnoreCase(facilityStr)) {
172 return SyslogConstants.LOG_LOCAL6;
173 } else if ("LOCAL7".equalsIgnoreCase(facilityStr)) {
174 return SyslogConstants.LOG_LOCAL7;
175 } else {
176 throw new IllegalArgumentException(facilityStr + " is not a valid syslog facility string");
177 }
178 }
179
180
181
182
183 public String getSyslogHost() {
184 return syslogHost;
185 }
186
187
188
189
190
191
192
193 public void setSyslogHost(String syslogHost) {
194 this.syslogHost = syslogHost;
195 }
196
197
198
199
200
201
202 public String getFacility() {
203 return facilityStr;
204 }
205
206
207
208
209
210
211
212
213
214
215
216 public void setFacility(String facilityStr) {
217 if (facilityStr != null) {
218 facilityStr = facilityStr.trim();
219 }
220 this.facilityStr = facilityStr;
221 }
222
223
224
225
226
227 public int getPort() {
228 return port;
229 }
230
231
232
233
234
235 public void setPort(int port) {
236 this.port = port;
237 }
238
239 public int getMaxMessageSize() {
240 return maxMessageSize;
241 }
242
243
244
245
246
247
248
249 public void setMaxMessageSize(int maxMessageSize) {
250 this.maxMessageSize = maxMessageSize;
251 }
252
253 public Layout<E> getLayout() {
254 return layout;
255 }
256
257 public void setLayout(Layout<E> layout) {
258 addWarn("The layout of a SyslogAppender cannot be set directly. See also " + SYSLOG_LAYOUT_URL);
259 }
260
261 @Override
262 public void stop() {
263 if (sos != null) {
264 sos.close();
265 }
266 super.stop();
267 }
268
269
270
271
272
273
274 public String getSuffixPattern() {
275 return suffixPattern;
276 }
277
278
279
280
281
282
283
284 public void setSuffixPattern(String suffixPattern) {
285 this.suffixPattern = suffixPattern;
286 }
287
288
289
290
291
292 public Charset getCharset() {
293 return charset;
294 }
295
296
297
298
299
300
301 public void setCharset(Charset charset) {
302 this.charset = charset;
303 }
304 }