View Javadoc

    1   /*
    2    * Licensed to the Apache Software Foundation (ASF) under one or more
    3    * contributor license agreements.  See the NOTICE file distributed with
    4    * this work for additional information regarding copyright ownership.
    5    * The ASF licenses this file to You under the Apache License, Version 2.0
    6    * (the "License"); you may not use this file except in compliance with
    7    * the License.  You may obtain a copy of the License at
    8    *
    9    *      http://www.apache.org/licenses/LICENSE-2.0
    10   *
    11   * Unless required by applicable law or agreed to in writing, software
    12   * distributed under the License is distributed on an "AS IS" BASIS,
    13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14   * See the License for the specific language governing permissions and
    15   * limitations under the License.
    16   */
    17
    18  package org.apache.log4j.helpers;
    19
    20
    21  import java.io.Writer;
    22  import java.net.DatagramSocket;
    23  import java.net.InetAddress;
    24  import java.net.DatagramPacket;
    25  import java.net.UnknownHostException;
    26  import java.net.SocketException;
    27  import java.io.IOException;
    28  import java.net.URL;
    29  import java.net.MalformedURLException;
    30
    31  /***
    32     SyslogWriter is a wrapper around the java.net.DatagramSocket class
    33     so that it behaves like a java.io.Writer.
    34
    35     @since 0.7.3
    36  */
    37  public class SyslogWriter extends Writer {
    38
    39    final int SYSLOG_PORT = 514;
    40    /***
    41     *  Host string from last constructed SyslogWriter.
    42     *  @deprecated
    43     */
    44    static String syslogHost;
    45
    46    private InetAddress address;
    47    private final int port;
    48    private DatagramSocket ds;
    49
    50    /***
    51     *  Constructs a new instance of SyslogWriter.
    52     *  @param syslogHost host name, may not be null.  A port
    53     *  may be specified by following the name or IPv4 literal address with
    54     *  a colon and a decimal port number.  To specify a port with an IPv6
    55     *  address, enclose the IPv6 address in square brackets before appending
    56     *  the colon and decimal port number.
    57     */
    58    public
    59    SyslogWriter(final String syslogHost) {
    60      SyslogWriter.syslogHost = syslogHost;
    61      if (syslogHost == null) {
    62          throw new NullPointerException("syslogHost");
    63      }
    64
    65      String host = syslogHost;
    66      int urlPort = -1;
    67
    68      //
    69      //  If not an unbracketed IPv6 address then
    70      //      parse as a URL
    71      //
    72      if (host.indexOf("[") != -1 || host.indexOf(':') == host.lastIndexOf(':')) {
    73          try {
    74              URL url = new URL("http://" + host);
    75              if (url.getHost() != null) {
    76                  host = url.getHost();
    77                  //   if host is a IPv6 literal, strip off the brackets
    78                  if(host.startsWith("[") && host.charAt(host.length() - 1) == ']') {
    79                      host = host.substring(1, host.length() - 1);
    80                  }
    81                  urlPort = url.getPort();
    82              }
    83          } catch(MalformedURLException e) {
    84        		LogLog.error("Malformed URL: will attempt to interpret as InetAddress.", e);
    85          }
    86      }
    87
    88      if (urlPort == -1) {
    89          urlPort = SYSLOG_PORT;
    90      }
    91      port = urlPort;
    92
    93      try {
    94        this.address = InetAddress.getByName(host);
    95      }
    96      catch (UnknownHostException e) {
    97        LogLog.error("Could not find " + host +
    98  			 ". All logging will FAIL.", e);
    99      }
    100
    101     try {
    102       this.ds = new DatagramSocket();
    103     }
    104     catch (SocketException e) {
    105       e.printStackTrace();
    106       LogLog.error("Could not instantiate DatagramSocket to " + host +
    107 			 ". All logging will FAIL.", e);
    108     }
    109
    110   }
    111
    112
    113   public
    114   void write(char[] buf, int off, int len) throws IOException {
    115     this.write(new String(buf, off, len));
    116   }
    117
    118   public
    119   void write(final String string) throws IOException {
    120
    121     if(this.ds != null && this.address != null) {
    122         byte[] bytes = string.getBytes();
    123         //
    124         //  syslog packets must be less than 1024 bytes
    125         //
    126         int bytesLength = bytes.length;
    127         if (bytesLength >= 1024) {
    128             bytesLength = 1024;
    129         }
    130         DatagramPacket packet = new DatagramPacket(bytes, bytesLength,
    131                                address, port);
    132         ds.send(packet);
    133     }
    134
    135   }
    136
    137   public
    138   void flush() {}
    139
    140   public void close() {
    141       if (ds != null) {
    142           ds.close();
    143       }
    144   }
    145 }