1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.log4j.net;
19
20 import org.apache.log4j.AppenderSkeleton;
21 import org.apache.log4j.Layout;
22 import org.apache.log4j.helpers.SyslogQuietWriter;
23 import org.apache.log4j.helpers.SyslogWriter;
24 import org.apache.log4j.spi.LoggingEvent;
25
26 import java.text.SimpleDateFormat;
27 import java.util.Date;
28 import java.util.Locale;
29 import java.net.InetAddress;
30 import java.net.UnknownHostException;
31 import java.io.IOException;
32
33
34
35
36
37
38
39
40
41
42 public class SyslogAppender extends AppenderSkeleton {
43
44
45
46
47
48 final static public int LOG_KERN = 0;
49
50 final static public int LOG_USER = 1<<3;
51
52 final static public int LOG_MAIL = 2<<3;
53
54 final static public int LOG_DAEMON = 3<<3;
55
56 final static public int LOG_AUTH = 4<<3;
57
58 final static public int LOG_SYSLOG = 5<<3;
59
60
61 final static public int LOG_LPR = 6<<3;
62
63 final static public int LOG_NEWS = 7<<3;
64
65 final static public int LOG_UUCP = 8<<3;
66
67 final static public int LOG_CRON = 9<<3;
68
69 final static public int LOG_AUTHPRIV = 10<<3;
70
71 final static public int LOG_FTP = 11<<3;
72
73
74
75 final static public int LOG_LOCAL0 = 16<<3;
76
77 final static public int LOG_LOCAL1 = 17<<3;
78
79 final static public int LOG_LOCAL2 = 18<<3;
80
81 final static public int LOG_LOCAL3 = 19<<3;
82
83 final static public int LOG_LOCAL4 = 20<<3;
84
85 final static public int LOG_LOCAL5 = 21<<3;
86
87 final static public int LOG_LOCAL6 = 22<<3;
88
89 final static public int LOG_LOCAL7 = 23<<3;
90
91 protected static final int SYSLOG_HOST_OI = 0;
92 protected static final int FACILITY_OI = 1;
93
94 static final String TAB = " ";
95
96
97 int syslogFacility = LOG_USER;
98 String facilityStr;
99 boolean facilityPrinting = false;
100
101
102 SyslogQuietWriter sqw;
103 String syslogHost;
104
105
106
107
108
109
110 private boolean header = false;
111
112
113
114
115 private final SimpleDateFormat dateFormat = new SimpleDateFormat("MMM dd HH:mm:ss ", Locale.ENGLISH);
116
117
118
119
120 private String localHostname;
121
122
123
124
125 private boolean layoutHeaderChecked = false;
126
127 public
128 SyslogAppender() {
129 this.initSyslogFacilityStr();
130 }
131
132 public
133 SyslogAppender(Layout layout, int syslogFacility) {
134 this.layout = layout;
135 this.syslogFacility = syslogFacility;
136 this.initSyslogFacilityStr();
137 }
138
139 public
140 SyslogAppender(Layout layout, String syslogHost, int syslogFacility) {
141 this(layout, syslogFacility);
142 setSyslogHost(syslogHost);
143 }
144
145
146
147
148
149
150 synchronized
151 public
152 void close() {
153 closed = true;
154 if (sqw != null) {
155 try {
156 if (layoutHeaderChecked && layout != null && layout.getFooter() != null) {
157 sendLayoutMessage(layout.getFooter());
158 }
159 sqw.close();
160 sqw = null;
161 } catch(java.io.InterruptedIOException e) {
162 Thread.currentThread().interrupt();
163 sqw = null;
164 } catch(IOException e) {
165 sqw = null;
166 }
167 }
168 }
169
170 private
171 void initSyslogFacilityStr() {
172 facilityStr = getFacilityString(this.syslogFacility);
173
174 if (facilityStr == null) {
175 System.err.println("\"" + syslogFacility +
176 "\" is an unknown syslog facility. Defaulting to \"USER\".");
177 this.syslogFacility = LOG_USER;
178 facilityStr = "user:";
179 } else {
180 facilityStr += ":";
181 }
182 }
183
184
185
186
187
188 public
189 static
190 String getFacilityString(int syslogFacility) {
191 switch(syslogFacility) {
192 case LOG_KERN: return "kern";
193 case LOG_USER: return "user";
194 case LOG_MAIL: return "mail";
195 case LOG_DAEMON: return "daemon";
196 case LOG_AUTH: return "auth";
197 case LOG_SYSLOG: return "syslog";
198 case LOG_LPR: return "lpr";
199 case LOG_NEWS: return "news";
200 case LOG_UUCP: return "uucp";
201 case LOG_CRON: return "cron";
202 case LOG_AUTHPRIV: return "authpriv";
203 case LOG_FTP: return "ftp";
204 case LOG_LOCAL0: return "local0";
205 case LOG_LOCAL1: return "local1";
206 case LOG_LOCAL2: return "local2";
207 case LOG_LOCAL3: return "local3";
208 case LOG_LOCAL4: return "local4";
209 case LOG_LOCAL5: return "local5";
210 case LOG_LOCAL6: return "local6";
211 case LOG_LOCAL7: return "local7";
212 default: return null;
213 }
214 }
215
216
217
218
219
220
221
222
223
224
225
226
227 public
228 static
229 int getFacility(String facilityName) {
230 if(facilityName != null) {
231 facilityName = facilityName.trim();
232 }
233 if("KERN".equalsIgnoreCase(facilityName)) {
234 return LOG_KERN;
235 } else if("USER".equalsIgnoreCase(facilityName)) {
236 return LOG_USER;
237 } else if("MAIL".equalsIgnoreCase(facilityName)) {
238 return LOG_MAIL;
239 } else if("DAEMON".equalsIgnoreCase(facilityName)) {
240 return LOG_DAEMON;
241 } else if("AUTH".equalsIgnoreCase(facilityName)) {
242 return LOG_AUTH;
243 } else if("SYSLOG".equalsIgnoreCase(facilityName)) {
244 return LOG_SYSLOG;
245 } else if("LPR".equalsIgnoreCase(facilityName)) {
246 return LOG_LPR;
247 } else if("NEWS".equalsIgnoreCase(facilityName)) {
248 return LOG_NEWS;
249 } else if("UUCP".equalsIgnoreCase(facilityName)) {
250 return LOG_UUCP;
251 } else if("CRON".equalsIgnoreCase(facilityName)) {
252 return LOG_CRON;
253 } else if("AUTHPRIV".equalsIgnoreCase(facilityName)) {
254 return LOG_AUTHPRIV;
255 } else if("FTP".equalsIgnoreCase(facilityName)) {
256 return LOG_FTP;
257 } else if("LOCAL0".equalsIgnoreCase(facilityName)) {
258 return LOG_LOCAL0;
259 } else if("LOCAL1".equalsIgnoreCase(facilityName)) {
260 return LOG_LOCAL1;
261 } else if("LOCAL2".equalsIgnoreCase(facilityName)) {
262 return LOG_LOCAL2;
263 } else if("LOCAL3".equalsIgnoreCase(facilityName)) {
264 return LOG_LOCAL3;
265 } else if("LOCAL4".equalsIgnoreCase(facilityName)) {
266 return LOG_LOCAL4;
267 } else if("LOCAL5".equalsIgnoreCase(facilityName)) {
268 return LOG_LOCAL5;
269 } else if("LOCAL6".equalsIgnoreCase(facilityName)) {
270 return LOG_LOCAL6;
271 } else if("LOCAL7".equalsIgnoreCase(facilityName)) {
272 return LOG_LOCAL7;
273 } else {
274 return -1;
275 }
276 }
277
278
279 private void splitPacket(final String header, final String packet) {
280 int byteCount = packet.getBytes().length;
281
282
283
284
285
286 if (byteCount <= 1019) {
287 sqw.write(packet);
288 } else {
289 int split = header.length() + (packet.length() - header.length())/2;
290 splitPacket(header, packet.substring(0, split) + "...");
291 splitPacket(header, header + "..." + packet.substring(split));
292 }
293 }
294
295 public
296 void append(LoggingEvent event) {
297
298 if(!isAsSevereAsThreshold(event.getLevel()))
299 return;
300
301
302 if(sqw == null) {
303 errorHandler.error("No syslog host is set for SyslogAppedender named \""+
304 this.name+"\".");
305 return;
306 }
307
308 if (!layoutHeaderChecked) {
309 if (layout != null && layout.getHeader() != null) {
310 sendLayoutMessage(layout.getHeader());
311 }
312 layoutHeaderChecked = true;
313 }
314
315 String hdr = getPacketHeader(event.timeStamp);
316 String packet;
317 if (layout == null) {
318 packet = String.valueOf(event.getMessage());
319 } else {
320 packet = layout.format(event);
321 }
322 if(facilityPrinting || hdr.length() > 0) {
323 StringBuffer buf = new StringBuffer(hdr);
324 if(facilityPrinting) {
325 buf.append(facilityStr);
326 }
327 buf.append(packet);
328 packet = buf.toString();
329 }
330
331 sqw.setLevel(event.getLevel().getSyslogEquivalent());
332
333
334
335 if (packet.length() > 256) {
336 splitPacket(hdr, packet);
337 } else {
338 sqw.write(packet);
339 }
340
341 if (layout == null || layout.ignoresThrowable()) {
342 String[] s = event.getThrowableStrRep();
343 if (s != null) {
344 for(int i = 0; i < s.length; i++) {
345 if (s[i].startsWith("\t")) {
346 sqw.write(hdr+TAB+s[i].substring(1));
347 } else {
348 sqw.write(hdr+s[i]);
349 }
350 }
351 }
352 }
353 }
354
355
356
357
358
359 public
360 void activateOptions() {
361 if (header) {
362 getLocalHostname();
363 }
364 if (layout != null && layout.getHeader() != null) {
365 sendLayoutMessage(layout.getHeader());
366 }
367 layoutHeaderChecked = true;
368 }
369
370
371
372
373
374
375 public
376 boolean requiresLayout() {
377 return true;
378 }
379
380
381
382
383
384
385
386
387
388
389 public
390 void setSyslogHost(final String syslogHost) {
391 this.sqw = new SyslogQuietWriter(new SyslogWriter(syslogHost),
392 syslogFacility, errorHandler);
393
394 this.syslogHost = syslogHost;
395 }
396
397
398
399
400 public
401 String getSyslogHost() {
402 return syslogHost;
403 }
404
405
406
407
408
409
410
411
412
413
414 public
415 void setFacility(String facilityName) {
416 if(facilityName == null)
417 return;
418
419 syslogFacility = getFacility(facilityName);
420 if (syslogFacility == -1) {
421 System.err.println("["+facilityName +
422 "] is an unknown syslog facility. Defaulting to [USER].");
423 syslogFacility = LOG_USER;
424 }
425
426 this.initSyslogFacilityStr();
427
428
429 if(sqw != null) {
430 sqw.setSyslogFacility(this.syslogFacility);
431 }
432 }
433
434
435
436
437 public
438 String getFacility() {
439 return getFacilityString(syslogFacility);
440 }
441
442
443
444
445
446
447 public
448 void setFacilityPrinting(boolean on) {
449 facilityPrinting = on;
450 }
451
452
453
454
455 public
456 boolean getFacilityPrinting() {
457 return facilityPrinting;
458 }
459
460
461
462
463
464
465
466 public final boolean getHeader() {
467 return header;
468 }
469
470
471
472
473
474
475 public final void setHeader(final boolean val) {
476 header = val;
477 }
478
479
480
481
482
483
484 private String getLocalHostname() {
485 if (localHostname == null) {
486 try {
487 InetAddress addr = InetAddress.getLocalHost();
488 localHostname = addr.getHostName();
489 } catch (UnknownHostException uhe) {
490 localHostname = "UNKNOWN_HOST";
491 }
492 }
493 return localHostname;
494 }
495
496
497
498
499
500
501
502 private String getPacketHeader(final long timeStamp) {
503 if (header) {
504 StringBuffer buf = new StringBuffer(dateFormat.format(new Date(timeStamp)));
505
506 if (buf.charAt(4) == '0') {
507 buf.setCharAt(4, ' ');
508 }
509 buf.append(getLocalHostname());
510 buf.append(' ');
511 return buf.toString();
512 }
513 return "";
514 }
515
516
517
518
519
520 private void sendLayoutMessage(final String msg) {
521 if (sqw != null) {
522 String packet = msg;
523 String hdr = getPacketHeader(new Date().getTime());
524 if(facilityPrinting || hdr.length() > 0) {
525 StringBuffer buf = new StringBuffer(hdr);
526 if(facilityPrinting) {
527 buf.append(facilityStr);
528 }
529 buf.append(msg);
530 packet = buf.toString();
531 }
532 sqw.setLevel(6);
533 sqw.write(packet);
534 }
535 }
536 }