| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package org.apache.log4j.net; |
| |
| import junit.framework.TestCase; |
| |
| import org.apache.log4j.AsyncAppender; |
| import org.apache.log4j.Layout; |
| import org.apache.log4j.Level; |
| import org.apache.log4j.LogManager; |
| import org.apache.log4j.Logger; |
| import org.apache.log4j.PatternLayout; |
| import org.apache.log4j.VectorErrorHandler; |
| import org.apache.log4j.HTMLLayout; |
| |
| import java.util.StringTokenizer; |
| import java.net.DatagramSocket; |
| import java.net.DatagramPacket; |
| import java.text.SimpleDateFormat; |
| import java.util.Locale; |
| import java.util.Date; |
| import java.util.Calendar; |
| |
| |
| /** |
| * Tests for SyslogAppender |
| * |
| * |
| * */ |
| public class SyslogAppenderTest extends TestCase { |
| /** |
| * Create new instance of SyslogAppenderTest. |
| * @param testName test name |
| */ |
| public SyslogAppenderTest(final String testName) { |
| super(testName); |
| } |
| |
| /** |
| * Resets configuration after every test. |
| */ |
| public void tearDown() { |
| LogManager.resetConfiguration(); |
| } |
| |
| /** |
| * Test default constructor. |
| */ |
| public void testDefaultConstructor() { |
| SyslogAppender appender = new SyslogAppender(); |
| assertEquals("user", appender.getFacility()); |
| assertEquals(false, appender.getFacilityPrinting()); |
| assertNull(appender.getLayout()); |
| assertNull(appender.getSyslogHost()); |
| assertNull(appender.getTag()); |
| assertTrue(appender.requiresLayout()); |
| } |
| |
| /** |
| * Test two parameter constructor. |
| */ |
| public void testTwoParamConstructor() { |
| Layout layout = new PatternLayout(); |
| SyslogAppender appender = new SyslogAppender(layout, 24); |
| assertEquals("daemon", appender.getFacility()); |
| assertEquals(false, appender.getFacilityPrinting()); |
| assertEquals(layout, appender.getLayout()); |
| assertNull(appender.getSyslogHost()); |
| assertNull(appender.getTag()); |
| assertTrue(appender.requiresLayout()); |
| } |
| |
| /** |
| * Test two parameter constructor with unexpected facility. |
| */ |
| public void testTwoParamConstructorBadFacility() { |
| Layout layout = new PatternLayout(); |
| SyslogAppender appender = new SyslogAppender(layout, 25); |
| assertEquals("user", appender.getFacility()); |
| assertEquals(false, appender.getFacilityPrinting()); |
| assertEquals(layout, appender.getLayout()); |
| assertNull(appender.getSyslogHost()); |
| assertNull(appender.getTag()); |
| assertTrue(appender.requiresLayout()); |
| } |
| |
| /** |
| * Test three parameter constructor. |
| */ |
| public void testThreeParamConstructor() { |
| Layout layout = new PatternLayout(); |
| SyslogAppender appender = |
| new SyslogAppender(layout, "syslog.example.org", 24); |
| assertEquals("daemon", appender.getFacility()); |
| assertEquals(false, appender.getFacilityPrinting()); |
| assertEquals(layout, appender.getLayout()); |
| assertEquals("syslog.example.org", appender.getSyslogHost()); |
| assertNull(appender.getTag()); |
| assertTrue(appender.requiresLayout()); |
| } |
| |
| /** |
| * Test getFacilityString for expected facility codes. |
| */ |
| public void testGetFacilityString() { |
| String expected = |
| "kern user mail daemon auth syslog lpr news " |
| + "uucp cron authpriv ftp local0 local1 local2 local3 " |
| + "local4 local5 local6 local7 "; |
| StringBuffer actual = new StringBuffer(); |
| |
| for (int i = 0; i <= 11; i++) { |
| actual.append(SyslogAppender.getFacilityString(i << 3)); |
| actual.append(' '); |
| } |
| |
| for (int i = 16; i <= 23; i++) { |
| actual.append(SyslogAppender.getFacilityString(i << 3)); |
| actual.append(' '); |
| } |
| |
| assertEquals(expected, actual.toString()); |
| } |
| |
| /** |
| * Test getFacilityString for some unexpected facility codes. |
| */ |
| public void testGetFacilityStringUnexpected() { |
| assertNull(SyslogAppender.getFacilityString(1)); |
| assertNull(SyslogAppender.getFacilityString(12 << 3)); |
| } |
| |
| /** |
| * Test getFacility with a bogus facility name. |
| */ |
| public void testGetFacilityBogus() { |
| assertEquals(-1, SyslogAppender.getFacility("bogus")); |
| } |
| |
| /** |
| * Test getFacility with a null facility name. |
| */ |
| public void testGetFacilityNull() { |
| assertEquals(-1, SyslogAppender.getFacility(null)); |
| } |
| |
| /** |
| * Test getFacility for expected system facility names. |
| */ |
| public void testGetFacilitySystemNames() { |
| String[] names = |
| new String[] { |
| "kErn", "usEr", "MaIL", "daemOn", "auTh", "syslOg", "lPr", "newS", |
| "Uucp", "croN", "authprIv", "ftP" |
| }; |
| |
| for (int i = 0; i <= 11; i++) { |
| assertEquals(i << 3, SyslogAppender.getFacility(names[i])); |
| } |
| } |
| |
| /** |
| * Test getFacility for expected system facility names. |
| */ |
| public void testGetFacilityLocalNames() { |
| String[] names = |
| new String[] { |
| "lOcal0", "LOCAL1", "loCal2", "locAl3", "locaL4", "local5", "LOCal6", |
| "loCAL7" |
| }; |
| |
| for (int i = 0; i <= 7; i++) { |
| assertEquals((16 + i) << 3, SyslogAppender.getFacility(names[i])); |
| } |
| } |
| |
| /** |
| * Test setFacilityPrinting. |
| */ |
| public void testSetFacilityPrinting() { |
| SyslogAppender appender = new SyslogAppender(); |
| assertFalse(appender.getFacilityPrinting()); |
| appender.setFacilityPrinting(true); |
| assertTrue(appender.getFacilityPrinting()); |
| appender.setFacilityPrinting(false); |
| assertFalse(appender.getFacilityPrinting()); |
| } |
| |
| /** |
| * Test of SyslogAppender constants. |
| */ |
| public void testConstants() { |
| assertEquals(0 << 3, SyslogAppender.LOG_KERN); |
| assertEquals(1 << 3, SyslogAppender.LOG_USER); |
| assertEquals(2 << 3, SyslogAppender.LOG_MAIL); |
| assertEquals(3 << 3, SyslogAppender.LOG_DAEMON); |
| assertEquals(4 << 3, SyslogAppender.LOG_AUTH); |
| assertEquals(5 << 3, SyslogAppender.LOG_SYSLOG); |
| assertEquals(6 << 3, SyslogAppender.LOG_LPR); |
| assertEquals(7 << 3, SyslogAppender.LOG_NEWS); |
| assertEquals(8 << 3, SyslogAppender.LOG_UUCP); |
| assertEquals(9 << 3, SyslogAppender.LOG_CRON); |
| assertEquals(10 << 3, SyslogAppender.LOG_AUTHPRIV); |
| assertEquals(11 << 3, SyslogAppender.LOG_FTP); |
| assertEquals(16 << 3, SyslogAppender.LOG_LOCAL0); |
| assertEquals(17 << 3, SyslogAppender.LOG_LOCAL1); |
| assertEquals(18 << 3, SyslogAppender.LOG_LOCAL2); |
| assertEquals(19 << 3, SyslogAppender.LOG_LOCAL3); |
| assertEquals(20 << 3, SyslogAppender.LOG_LOCAL4); |
| assertEquals(21 << 3, SyslogAppender.LOG_LOCAL5); |
| assertEquals(22 << 3, SyslogAppender.LOG_LOCAL6); |
| assertEquals(23 << 3, SyslogAppender.LOG_LOCAL7); |
| } |
| |
| /** |
| * Test setFacility with null. |
| * Should have no effect. |
| */ |
| public void testSetFacilityKern() { |
| SyslogAppender appender = new SyslogAppender(); |
| appender.setFacility("kern"); |
| appender.setFacility(null); |
| assertEquals("kern", appender.getFacility()); |
| } |
| |
| /** |
| * Test setFacility with null. |
| * Should have no effect. |
| */ |
| public void testSetFacilityNull() { |
| SyslogAppender appender = new SyslogAppender(); |
| appender.setFacility("kern"); |
| appender.setFacility(null); |
| assertEquals("kern", appender.getFacility()); |
| } |
| |
| /** |
| * Test setFacility with bogus value. |
| * Should reset to user. |
| */ |
| public void testSetFacilityBogus() { |
| SyslogAppender appender = new SyslogAppender(); |
| appender.setFacility("kern"); |
| appender.setFacility("bogus"); |
| assertEquals("user", appender.getFacility()); |
| } |
| |
| /** |
| * Tests calling setFacility after appender has been activated. |
| */ |
| public void testSetFacilityAfterActivation() { |
| SyslogAppender appender = new SyslogAppender(); |
| appender.setName("foo"); |
| appender.setThreshold(Level.INFO); |
| appender.setSyslogHost("localhost"); |
| appender.setFacility("user"); |
| appender.setLayout(new PatternLayout("%m%n")); |
| |
| VectorErrorHandler errorHandler = new VectorErrorHandler(); |
| appender.setErrorHandler(errorHandler); |
| appender.activateOptions(); |
| appender.setFacility("kern"); |
| assertEquals("kern", appender.getFacility()); |
| } |
| |
| /** |
| * Tests that append method drops messages below threshold. |
| * Can't reach isSevereAsThreshold call in SyslogAppender.append |
| * since it is checked in AppenderSkeleton.doAppend. |
| */ |
| public void testAppendBelowThreshold() { |
| SyslogAppender appender = new SyslogAppender(); |
| appender.setThreshold(Level.ERROR); |
| appender.activateOptions(); |
| |
| Logger logger = Logger.getRootLogger(); |
| logger.addAppender(appender); |
| logger.info( |
| "Should not be logged by SyslogAppenderTest.testAppendBelowThreshold."); |
| } |
| |
| /** |
| * Tests that append method drops messages below threshold. |
| */ |
| public void testAppendNoHost() { |
| SyslogAppender appender = new SyslogAppender(); |
| appender.setName("foo"); |
| appender.setThreshold(Level.INFO); |
| |
| VectorErrorHandler errorHandler = new VectorErrorHandler(); |
| appender.setErrorHandler(errorHandler); |
| appender.setLayout(new PatternLayout("%m%n")); |
| appender.activateOptions(); |
| |
| Logger logger = Logger.getRootLogger(); |
| logger.addAppender(appender); |
| logger.info( |
| "Should not be logged by SyslogAppenderTest.testAppendNoHost."); |
| assertEquals(1, errorHandler.size()); |
| |
| // |
| // Appender is misspelled in implementation |
| // |
| assertEquals( |
| "No syslog host is set for SyslogAppedender named \"foo\".", |
| errorHandler.getMessage(0)); |
| } |
| |
| /** |
| * Tests append method under normal conditions. |
| */ |
| public void testAppend() { |
| SyslogAppender appender = new SyslogAppender(); |
| appender.setName("foo"); |
| appender.setThreshold(Level.INFO); |
| appender.setSyslogHost("localhost"); |
| appender.setFacility("user"); |
| appender.setLayout(new PatternLayout("%m%n")); |
| |
| VectorErrorHandler errorHandler = new VectorErrorHandler(); |
| appender.setErrorHandler(errorHandler); |
| appender.activateOptions(); |
| |
| // |
| // wrap SyslogAppender with an Async since appender may |
| // hang if syslogd is not accepting network messages |
| // |
| AsyncAppender asyncAppender = new AsyncAppender(); |
| asyncAppender.addAppender(appender); |
| asyncAppender.activateOptions(); |
| |
| Logger logger = Logger.getRootLogger(); |
| logger.addAppender(asyncAppender); |
| |
| Exception e = |
| new Exception("Expected exception from SyslogAppenderTest.testAppend"); |
| logger.info( |
| "Expected message from log4j unit test SyslogAppenderTest.testAppend.", e); |
| assertEquals(0, errorHandler.size()); |
| } |
| |
| /** |
| * Tests SyslogAppender with IPv6 address. |
| */ |
| public void testIPv6() { |
| SyslogAppender appender = new SyslogAppender(); |
| appender.setSyslogHost("::1"); |
| } |
| |
| /** |
| * Tests SyslogAppender with IPv6 address enclosed in square brackets. |
| */ |
| public void testIPv6InBrackets() { |
| SyslogAppender appender = new SyslogAppender(); |
| appender.setSyslogHost("[::1]"); |
| } |
| |
| /** |
| * Tests SyslogAppender with IPv6 address enclosed in square brackets |
| * followed by port specification. |
| */ |
| public void testIPv6AndPort() { |
| SyslogAppender appender = new SyslogAppender(); |
| appender.setSyslogHost("[::1]:1514"); |
| } |
| |
| /** |
| * Tests SyslogAppender with host name enclosed in square brackets |
| * followed by port specification. |
| */ |
| public void testHostNameAndPort() { |
| SyslogAppender appender = new SyslogAppender(); |
| appender.setSyslogHost("localhost:1514"); |
| } |
| |
| |
| /** |
| * Tests SyslogAppender with IPv4 address followed by port specification. |
| */ |
| public void testIPv4AndPort() { |
| SyslogAppender appender = new SyslogAppender(); |
| appender.setSyslogHost("127.0.0.1:1514"); |
| } |
| |
| /** |
| * Tests SyslogAppender with setTag. |
| */ |
| public void testTag() { |
| SyslogAppender appender = new SyslogAppender(); |
| appender.setTag("testtag"); |
| assertEquals("testtag", appender.getTag()); |
| } |
| |
| /** |
| * Tests SyslogAppender with null tag. |
| */ |
| public void testNullTag() { |
| SyslogAppender appender = new SyslogAppender(); |
| appender.setTag(null); |
| assertNull(appender.getTag()); |
| } |
| |
| /** |
| * Tests SyslogAppender with long tag. |
| */ |
| public void testLongTag() { |
| SyslogAppender appender = new SyslogAppender(); |
| appender.setTag("testtagtesttagtesttagtesttagtesttag"); |
| assertEquals(appender.getTag(), "testtagtesttagtesttagtesttagtest"); |
| } |
| |
| /** |
| * Tests SyslogAppender with non alnum tag. |
| */ |
| public void testNonAlnumTag() { |
| SyslogAppender appender = new SyslogAppender(); |
| try{ |
| appender.setTag("testtag testtag"); |
| fail("SyslogAppender.setTag() should have thrown an exception."); |
| } catch (IllegalArgumentException e) { |
| // Correct behavior, ignore and let the test pass. |
| } |
| } |
| |
| private static String[] log(final boolean header, |
| final String tag, |
| final String msg, |
| final Exception ex, |
| final int packets) throws Exception { |
| DatagramSocket ds = new DatagramSocket(); |
| ds.setSoTimeout(2000); |
| |
| SyslogAppender appender = new SyslogAppender(); |
| appender.setSyslogHost("localhost:" + ds.getLocalPort()); |
| appender.setName("name"); |
| appender.setHeader(header); |
| appender.setTag(tag); |
| PatternLayout pl = new PatternLayout("%m"); |
| appender.setLayout(pl); |
| appender.activateOptions(); |
| |
| Logger l = Logger.getRootLogger(); |
| l.addAppender(appender); |
| if (ex == null) { |
| l.info(msg); |
| } else { |
| l.error(msg, ex); |
| } |
| appender.close(); |
| String[] retval = new String[packets]; |
| byte[] buf = new byte[1000]; |
| for(int i = 0; i < packets; i++) { |
| DatagramPacket p = new DatagramPacket(buf, 0, buf.length); |
| ds.receive(p); |
| retval[i] = new String(p.getData(), 0, p.getLength()); |
| } |
| ds.close(); |
| return retval; |
| } |
| |
| public void testActualLogging() throws Exception { |
| String s = log(false, null, "greetings", null, 1)[0]; |
| StringTokenizer st = new StringTokenizer(s, "<>() "); |
| assertEquals("14", st.nextToken()); |
| assertEquals("greetings", st.nextToken()); |
| } |
| |
| /** |
| * Exception with printStackTrace that breaks earlier SyslogAppender. |
| */ |
| private static class MishandledException extends Exception { |
| private static final long serialVersionUID = 1L; |
| /* |
| * Create new instance. |
| */ |
| public MishandledException() { |
| } |
| |
| /** |
| * Print stack trace. |
| * @param w print writer, may not be null. |
| */ |
| public void printStackTrace(final java.io.PrintWriter w) { |
| w.println("Mishandled stack trace follows:"); |
| w.println(""); |
| w.println("No tab here"); |
| w.println("\ttab here"); |
| w.println("\t"); |
| } |
| } |
| |
| /** |
| * Tests fix for bug 40502. |
| * @throws Exception on IOException. |
| */ |
| public void testBadTabbing() throws Exception { |
| String[] s = log(false, null, "greetings", new MishandledException(), 6); |
| StringTokenizer st = new StringTokenizer(s[0], "<>() "); |
| assertEquals("11", st.nextToken()); |
| assertEquals("greetings", st.nextToken()); |
| assertEquals("<11>Mishandled stack trace follows:", s[1]); |
| assertEquals("<11>", s[2]); |
| assertEquals("<11>No tab here", s[3]); |
| assertEquals("<11>" + SyslogAppender.TAB + "tab here", s[4]); |
| assertEquals("<11>" + SyslogAppender.TAB, s[5]); |
| } |
| |
| /** |
| * Tests presence of timestamp if header = true. |
| * |
| * @throws Exception if IOException. |
| */ |
| public void testHeaderLogging() throws Exception { |
| Date preDate = new Date(); |
| String s = log(true, null, "greetings", null, 1)[0]; |
| Date postDate = new Date(); |
| assertEquals("<14>", s.substring(0, 4)); |
| |
| String syslogDateStr = s.substring(4, 20); |
| SimpleDateFormat fmt = new SimpleDateFormat("MMM dd HH:mm:ss ", Locale.ENGLISH); |
| Date syslogDate = fmt.parse(syslogDateStr); |
| Calendar cal = Calendar.getInstance(Locale.ENGLISH); |
| cal.setTime(syslogDate); |
| int syslogMonth = cal.get(Calendar.MONTH); |
| int syslogDay = cal.get(Calendar.DATE); |
| if (syslogDay < 10) { |
| assertEquals(' ', syslogDateStr.charAt(4)); |
| } |
| cal.setTime(preDate); |
| int preMonth = cal.get(Calendar.MONTH); |
| cal.set(Calendar.MILLISECOND, 0); |
| preDate = cal.getTime(); |
| int syslogYear; |
| if (preMonth == syslogMonth) { |
| syslogYear = cal.get(Calendar.YEAR); |
| } else { |
| cal.setTime(postDate); |
| syslogYear = cal.get(Calendar.YEAR); |
| } |
| cal.setTime(syslogDate); |
| cal.set(Calendar.YEAR, syslogYear); |
| syslogDate = cal.getTime(); |
| assertTrue(syslogDate.compareTo(preDate) >= 0); |
| assertTrue(syslogDate.compareTo(postDate) <= 0); |
| } |
| |
| |
| /** |
| * Tests presence of tag if set |
| */ |
| public void testHeaderTagLogging() throws Exception { |
| String s = log(true, "testtag", "greetings", null, 1)[0]; |
| assertEquals("<14>", s.substring(0, 4)); |
| |
| StringTokenizer st = new StringTokenizer(s.substring(21), " "); |
| |
| // Throw away the hostname |
| st.nextToken(); |
| |
| assertEquals("testtag:", st.nextToken()); |
| } |
| |
| /** |
| * Tests presence of tag on every line of the exception |
| */ |
| public void testHeaderTagExceptionLogging() throws Exception { |
| String[] s = log(true, "testtag", "greetings", new Exception(), 6); |
| for(int i=0; i < s.length; i++) { |
| System.err.println(s[i]); |
| assertEquals("<11>", s[i].substring(0, 4)); |
| StringTokenizer st = new StringTokenizer(s[i].substring(21), " "); |
| // Throw away the hostname |
| st.nextToken(); |
| assertEquals("testtag:", st.nextToken()); |
| } |
| } |
| |
| /** |
| * Tests absesence of tag if set to null |
| */ |
| public void testHeaderNullTagLogging() throws Exception { |
| String s = log(true, null, "greetings", null, 1)[0]; |
| assertEquals("<14>", s.substring(0, 4)); |
| |
| StringTokenizer st = new StringTokenizer(s.substring(21), " "); |
| |
| // Throw away the hostname |
| st.nextToken(); |
| |
| assertEquals("greetings", st.nextToken()); |
| } |
| |
| /** |
| * Tests that any header or footer in layout is sent. |
| * @throws Exception if exception during test. |
| */ |
| public void testLayoutHeader() throws Exception { |
| DatagramSocket ds = new DatagramSocket(); |
| ds.setSoTimeout(2000); |
| |
| SyslogAppender appender = new SyslogAppender(); |
| appender.setSyslogHost("localhost:" + ds.getLocalPort()); |
| appender.setName("name"); |
| appender.setHeader(false); |
| HTMLLayout pl = new HTMLLayout(); |
| appender.setLayout(pl); |
| appender.activateOptions(); |
| |
| Logger l = Logger.getRootLogger(); |
| l.addAppender(appender); |
| l.info("Hello, World"); |
| appender.close(); |
| String[] s = new String[3]; |
| byte[] buf = new byte[1000]; |
| for(int i = 0; i < 3; i++) { |
| DatagramPacket p = new DatagramPacket(buf, 0, buf.length); |
| ds.receive(p); |
| s[i] = new String(p.getData(), 0, p.getLength()); |
| } |
| ds.close(); |
| assertEquals("<14><!DOCTYPE", s[0].substring(0,13)); |
| assertEquals("<14></table>", s[2].substring(0,12)); |
| } |
| |
| /** |
| * Tests that syslog packets do not exceed 1024 bytes. |
| * See bug 42087. |
| * @throws Exception if exception during test. |
| */ |
| public void testBigPackets() throws Exception { |
| DatagramSocket ds = new DatagramSocket(); |
| ds.setSoTimeout(2000); |
| |
| SyslogAppender appender = new SyslogAppender(); |
| appender.setSyslogHost("localhost:" + ds.getLocalPort()); |
| appender.setName("name"); |
| appender.setHeader(false); |
| PatternLayout pl = new PatternLayout("%m"); |
| appender.setLayout(pl); |
| appender.activateOptions(); |
| |
| Logger l = Logger.getRootLogger(); |
| l.addAppender(appender); |
| StringBuffer msgbuf = new StringBuffer(); |
| while(msgbuf.length() < 8000) { |
| msgbuf.append("0123456789"); |
| } |
| String msg = msgbuf.toString(); |
| l.info(msg); |
| appender.close(); |
| String[] s = new String[8]; |
| byte[] buf = new byte[1200]; |
| for(int i = 0; i < 8; i++) { |
| DatagramPacket p = new DatagramPacket(buf, 0, buf.length); |
| ds.receive(p); |
| assertTrue(p.getLength() <= 1024); |
| s[i] = new String(p.getData(), 0, p.getLength()); |
| } |
| ds.close(); |
| StringBuffer rcvbuf = new StringBuffer(s[0]); |
| rcvbuf.delete(0, 4); |
| for(int i = 1; i < 8; i++) { |
| rcvbuf.setLength(rcvbuf.length() - 3); |
| rcvbuf.append(s[i].substring(s[i].indexOf("...") + 3)); |
| } |
| assertEquals(msg.length(), rcvbuf.length()); |
| assertEquals(msg, rcvbuf.toString()); |
| } |
| |
| } |