FileDocCategorySizeDatePackage
SyslogAppender.javaAPI DocApache log4j 1.2.1515981Sat Aug 25 00:09:40 BST 2007org.apache.log4j.net

SyslogAppender

public class SyslogAppender extends AppenderSkeleton
Use SyslogAppender to send log messages to a remote syslog daemon.
author
Ceki Gülcü
author
Anders Kristensen

Fields Summary
public static final int
LOG_KERN
Kernel messages
public static final int
LOG_USER
Random user-level messages
public static final int
LOG_MAIL
Mail system
public static final int
LOG_DAEMON
System daemons
public static final int
LOG_AUTH
security/authorization messages
public static final int
LOG_SYSLOG
messages generated internally by syslogd
public static final int
LOG_LPR
line printer subsystem
public static final int
LOG_NEWS
network news subsystem
public static final int
LOG_UUCP
UUCP subsystem
public static final int
LOG_CRON
clock daemon
public static final int
LOG_AUTHPRIV
security/authorization messages (private)
public static final int
LOG_FTP
ftp daemon
public static final int
LOG_LOCAL0
reserved for local use
public static final int
LOG_LOCAL1
reserved for local use
public static final int
LOG_LOCAL2
reserved for local use
public static final int
LOG_LOCAL3
reserved for local use
public static final int
LOG_LOCAL4
reserved for local use
public static final int
LOG_LOCAL5
reserved for local use
public static final int
LOG_LOCAL6
reserved for local use
public static final int
LOG_LOCAL7
reserved for local use
protected static final int
SYSLOG_HOST_OI
protected static final int
FACILITY_OI
static final String
TAB
int
syslogFacility
String
facilityStr
boolean
facilityPrinting
SyslogQuietWriter
sqw
String
syslogHost
private boolean
header
If true, the appender will generate the HEADER (timestamp and host name) part of the syslog packet.
private final SimpleDateFormat
dateFormat
Date format used if header = true.
private String
localHostname
Host name used to identify messages from this appender.
private boolean
layoutHeaderChecked
Set to true after the header of the layout has been sent or if it has none.
Constructors Summary
public SyslogAppender()


  
   
    this.initSyslogFacilityStr();
  
public SyslogAppender(Layout layout, int syslogFacility)

    this.layout = layout;
    this.syslogFacility = syslogFacility;
    this.initSyslogFacilityStr();
  
public SyslogAppender(Layout layout, String syslogHost, int syslogFacility)

    this(layout, syslogFacility);
    setSyslogHost(syslogHost);
  
Methods Summary
public voidactivateOptions()
This method returns immediately as options are activated when they are set.

      if (header) {
        getLocalHostname();
      }
      if (layout != null && layout.getHeader() != null) {
          sendLayoutMessage(layout.getHeader());
      }
      layoutHeaderChecked = true;
  
public voidappend(org.apache.log4j.spi.LoggingEvent event)


    if(!isAsSevereAsThreshold(event.getLevel()))
      return;

    // We must not attempt to append if sqw is null.
    if(sqw == null) {
      errorHandler.error("No syslog host is set for SyslogAppedender named \""+
			this.name+"\".");
      return;
    }

    if (!layoutHeaderChecked) {
        if (layout != null && layout.getHeader() != null) {
            sendLayoutMessage(layout.getHeader());
        }
        layoutHeaderChecked = true;
    }

    String hdr = getPacketHeader(event.timeStamp);
    String packet = layout.format(event);
    if(facilityPrinting || hdr.length() > 0) {
        StringBuffer buf = new StringBuffer(hdr);
        if(facilityPrinting) {
            buf.append(facilityStr);
        }
        buf.append(packet);
        packet = buf.toString();
    }

    sqw.setLevel(event.getLevel().getSyslogEquivalent());
    //
    //   if message has a remote likelihood of exceeding 1024 bytes
    //      when encoded, consider splitting message into multiple packets
    if (packet.length() > 256) {
        splitPacket(hdr, packet);
    } else {
        sqw.write(packet);
    }

    if (layout.ignoresThrowable()) {
      String[] s = event.getThrowableStrRep();
      if (s != null) {
        for(int i = 0; i < s.length; i++) {
            if (s[i].startsWith("\t")) {
               sqw.write(hdr+TAB+s[i].substring(1));
            } else {
               sqw.write(hdr+s[i]);
            }
        }
      }
    }
  
public synchronized voidclose()
Release any resources held by this SyslogAppender.

since
0.8.4

    closed = true;
    if (sqw != null) {
        try {
            if (layoutHeaderChecked && layout != null && layout.getFooter() != null) {
                sendLayoutMessage(layout.getFooter());
            }
            sqw.close();
            sqw = null;
        } catch(java.io.IOException ex) {
            sqw = null;
        }
    }
  
public java.lang.StringgetFacility()
Returns the value of the Facility option.

    return getFacilityString(syslogFacility);
  
public static intgetFacility(java.lang.String facilityName)
Returns the integer value corresponding to the named syslog facility, or -1 if it couldn't be recognized.

param
facilityName one of the strings KERN, USER, MAIL, DAEMON, AUTH, SYSLOG, LPR, NEWS, UUCP, CRON, AUTHPRIV, FTP, LOCAL0, LOCAL1, LOCAL2, LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7. The matching is case-insensitive.
since
1.1

    if(facilityName != null) {
      facilityName = facilityName.trim();
    }
    if("KERN".equalsIgnoreCase(facilityName)) {
      return LOG_KERN;
    } else if("USER".equalsIgnoreCase(facilityName)) {
      return LOG_USER;
    } else if("MAIL".equalsIgnoreCase(facilityName)) {
      return LOG_MAIL;
    } else if("DAEMON".equalsIgnoreCase(facilityName)) {
      return LOG_DAEMON;
    } else if("AUTH".equalsIgnoreCase(facilityName)) {
      return LOG_AUTH;
    } else if("SYSLOG".equalsIgnoreCase(facilityName)) {
      return LOG_SYSLOG;
    } else if("LPR".equalsIgnoreCase(facilityName)) {
      return LOG_LPR;
    } else if("NEWS".equalsIgnoreCase(facilityName)) {
      return LOG_NEWS;
    } else if("UUCP".equalsIgnoreCase(facilityName)) {
      return LOG_UUCP;
    } else if("CRON".equalsIgnoreCase(facilityName)) {
      return LOG_CRON;
    } else if("AUTHPRIV".equalsIgnoreCase(facilityName)) {
      return LOG_AUTHPRIV;
    } else if("FTP".equalsIgnoreCase(facilityName)) {
      return LOG_FTP;
    } else if("LOCAL0".equalsIgnoreCase(facilityName)) {
      return LOG_LOCAL0;
    } else if("LOCAL1".equalsIgnoreCase(facilityName)) {
      return LOG_LOCAL1;
    } else if("LOCAL2".equalsIgnoreCase(facilityName)) {
      return LOG_LOCAL2;
    } else if("LOCAL3".equalsIgnoreCase(facilityName)) {
      return LOG_LOCAL3;
    } else if("LOCAL4".equalsIgnoreCase(facilityName)) {
      return LOG_LOCAL4;
    } else if("LOCAL5".equalsIgnoreCase(facilityName)) {
      return LOG_LOCAL5;
    } else if("LOCAL6".equalsIgnoreCase(facilityName)) {
      return LOG_LOCAL6;
    } else if("LOCAL7".equalsIgnoreCase(facilityName)) {
      return LOG_LOCAL7;
    } else {
      return -1;
    }
  
public booleangetFacilityPrinting()
Returns the value of the FacilityPrinting option.

    return facilityPrinting;
  
public static java.lang.StringgetFacilityString(int syslogFacility)
Returns the specified syslog facility as a lower-case String, e.g. "kern", "user", etc.

    switch(syslogFacility) {
    case LOG_KERN:      return "kern";
    case LOG_USER:      return "user";
    case LOG_MAIL:      return "mail";
    case LOG_DAEMON:    return "daemon";
    case LOG_AUTH:      return "auth";
    case LOG_SYSLOG:    return "syslog";
    case LOG_LPR:       return "lpr";
    case LOG_NEWS:      return "news";
    case LOG_UUCP:      return "uucp";
    case LOG_CRON:      return "cron";
    case LOG_AUTHPRIV:  return "authpriv";
    case LOG_FTP:       return "ftp";
    case LOG_LOCAL0:    return "local0";
    case LOG_LOCAL1:    return "local1";
    case LOG_LOCAL2:    return "local2";
    case LOG_LOCAL3:    return "local3";
    case LOG_LOCAL4:    return "local4";
    case LOG_LOCAL5:    return "local5";
    case LOG_LOCAL6:    return "local6";
    case LOG_LOCAL7:    return "local7";
    default:            return null;
    }
  
public final booleangetHeader()
If true, the appender will generate the HEADER part (that is, timestamp and host name) of the syslog packet. Default value is false for compatibility with existing behavior, however should be true unless there is a specific justification.

since
1.2.15

      return header;
  
private java.lang.StringgetLocalHostname()
Get the host name used to identify this appender.

return
local host name
since
1.2.15

      if (localHostname == null) {
          try {
            InetAddress addr = InetAddress.getLocalHost();
            localHostname = addr.getHostName();
          } catch (UnknownHostException uhe) {
            localHostname = "UNKNOWN_HOST";
          }
      }
      return localHostname;
  
private java.lang.StringgetPacketHeader(long timeStamp)
Gets HEADER portion of packet.

param
timeStamp number of milliseconds after the standard base time.
return
HEADER portion of packet, will be zero-length string if header is false.
since
1.2.15

      if (header) {
        StringBuffer buf = new StringBuffer(dateFormat.format(new Date(timeStamp)));
        //  RFC 3164 says leading space, not leading zero on days 1-9
        if (buf.charAt(4) == '0") {
          buf.setCharAt(4, ' ");
        }
        buf.append(getLocalHostname());
        buf.append(' ");
        return buf.toString();
      }
      return "";
  
public java.lang.StringgetSyslogHost()
Returns the value of the SyslogHost option.

    return syslogHost;
  
private voidinitSyslogFacilityStr()

    facilityStr = getFacilityString(this.syslogFacility);

    if (facilityStr == null) {
      System.err.println("\"" + syslogFacility +
                  "\" is an unknown syslog facility. Defaulting to \"USER\".");
      this.syslogFacility = LOG_USER;
      facilityStr = "user:";
    } else {
      facilityStr += ":";
    }
  
public booleanrequiresLayout()
The SyslogAppender requires a layout. Hence, this method returns true.

since
0.8.4

    return true;
  
private voidsendLayoutMessage(java.lang.String msg)
Set header or footer of layout.

param
msg message body, may not be null.

      if (sqw != null) {
          String packet = msg;
          String hdr = getPacketHeader(new Date().getTime());
          if(facilityPrinting || hdr.length() > 0) {
              StringBuffer buf = new StringBuffer(hdr);
              if(facilityPrinting) {
                  buf.append(facilityStr);
              }
              buf.append(msg);
              packet = buf.toString();
          }
          sqw.setLevel(6);
          sqw.write(packet);
      }
  
public voidsetFacility(java.lang.String facilityName)
Set the syslog facility. This is the Facility option.

The facilityName parameter must be one of the strings KERN, USER, MAIL, DAEMON, AUTH, SYSLOG, LPR, NEWS, UUCP, CRON, AUTHPRIV, FTP, LOCAL0, LOCAL1, LOCAL2, LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7. Case is unimportant.

since
0.8.1

    if(facilityName == null)
      return;

    syslogFacility = getFacility(facilityName);
    if (syslogFacility == -1) {
      System.err.println("["+facilityName +
                  "] is an unknown syslog facility. Defaulting to [USER].");
      syslogFacility = LOG_USER;
    }

    this.initSyslogFacilityStr();

    // If there is already a sqw, make it use the new facility.
    if(sqw != null) {
      sqw.setSyslogFacility(this.syslogFacility);
    }
  
public voidsetFacilityPrinting(boolean on)
If the FacilityPrinting option is set to true, the printed message will include the facility name of the application. It is false by default.

    facilityPrinting = on;
  
public final voidsetHeader(boolean val)
Returns whether the appender produces the HEADER part (that is, timestamp and host name) of the syslog packet.

since
1.2.15

      header = val;
  
public voidsetSyslogHost(java.lang.String syslogHost)
The SyslogHost option is the name of the the syslog host where log output should go. A non-default port can be specified by appending a colon and port number to a host name, an IPv4 address or an IPv6 address enclosed in square brackets. WARNING If the SyslogHost is not set, then this appender will fail.

    this.sqw = new SyslogQuietWriter(new SyslogWriter(syslogHost),
				     syslogFacility, errorHandler);
    //this.stp = new SyslogTracerPrintWriter(sqw);
    this.syslogHost = syslogHost;
  
private voidsplitPacket(java.lang.String header, java.lang.String packet)

      int byteCount = packet.getBytes().length;
      //
      //   if packet is less than RFC 3164 limit
      //      of 1024 bytes, then write it
      //      (must allow for up 5to 5 characters in the PRI section
      //          added by SyslogQuietWriter)
      if (byteCount <= 1019) {
          sqw.write(packet);
      } else {
          int split = header.length() + (packet.length() - header.length())/2;
          splitPacket(header, packet.substring(0, split) + "...");
          splitPacket(header, header + "..." + packet.substring(split));
      }