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 }