diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml
new file mode 100644
index 0000000000..22e41d0717
--- /dev/null
+++ b/.github/workflows/maven.yml
@@ -0,0 +1,97 @@
+name: Maven CI Build
+
+on: [push]
+
+jobs:
+ JDK6Toolchain:
+ name: Toolchain 1.6, JDK 11, OS ${{ matrix.os }}
+ runs-on: ${{ matrix.os }}
+ strategy:
+ matrix:
+ os: [ubuntu-18.04, ubuntu-20.04, windows-2019, windows-2022]
+ fail-fast: true
+ max-parallel: 2
+ steps:
+ - uses: actions/checkout@v1
+ - name: Install Toolchain JDK
+ uses: battila7/jdk-via-jabba@v1
+ with:
+ jdk: zulu@1.6.119
+ javaHomeEnvironmentVariable: TOOLCHAIN_JDK
+ addBinDirectoryToPath: false
+ - name: Configure Maven for Toolchain
+ shell: bash
+ run: |
+ mkdir -p $HOME/.m2 && cat >$HOME/.m2/toolchains.xml < WARNING: This version of JDBCAppender
- is very likely to be completely replaced in the future. Moreoever,
- it does not log exceptions.
-
- Each append call adds to an The Overriding the {@link #getLogStatement} method allows more
- explicit control of the statement used for logging.
-
- For use as a base class:
-
- ArrayList
buffer. When
- the buffer is filled each log event is placed in a sql statement
- (configurable) and executed.
-
- BufferSize, db URL, User, & Password are
- configurable options in the standard log4j ways.
-
- setSql(String sql)
sets the SQL statement to be
- used for logging -- this statement is sent to a
- PatternLayout
(either created automaticly by the
- appender or added by the user). Therefore by default all the
- conversion patterns in PatternLayout
can be used
- inside of the statement. (see the test cases for examples)
-
-
-
-
-
- @author Kevin Steppe (ksteppe@pacbell.net)
+ Changed in 1.2.18+ to complain about its use and do nothing else.
+ See the log4j 1.2 homepage
+ for more information on why this class is disabled since 1.2.18.
+ @author Kevin Steppe (ksteppe@pacbell.net)
+ @deprecated
*/
-public class JDBCAppender extends org.apache.log4j.AppenderSkeleton
- implements org.apache.log4j.Appender {
+public class JDBCAppender extends org.apache.log4j.AppenderSkeleton {
+
+ static final String JDBC_UNSUPPORTED =
+ "ERROR-LOG4J-NETWORKING-UNSUPPORTED: JDBC unsupported!" +
+ " This is a breaking change in Log4J 1 >=1.2.18. Change your config to stop using JDBC!";
- /**
- * URL of the DB for default connection handling
- */
protected String databaseURL = "jdbc:odbc:myDB";
- /**
- * User to connect as for default connection handling
- */
protected String databaseUser = "me";
- /**
- * User to use for default connection handling
- */
protected String databasePassword = "mypassword";
- /**
- * Connection used by default. The connection is opened the first time it
- * is needed and then held open until the appender is closed (usually at
- * garbage collection). This behavior is best modified by creating a
- * sub-class and overriding the getConnection()
to pass any connection
- you want. Typically this is used to enable application wide
- connection pooling.
-
- closeConnection(Connection con)
-- if
- you override getConnection make sure to implement
- closeConnection
to handle the connection you
- generated. Typically this would return the connection to the
- pool it came from.
+ The JDBCAppender provides for sending log events to a database
+ in Log4j up to 1.2.17.
- getLogStatement(LoggingEvent event)
to
- produce specialized or dynamic statements. The default uses the
- sql option value.
-
- getConnection
and
- * closeConnection
methods.
- */
protected Connection connection = null;
- /**
- * Stores the string given to the pattern layout for conversion into a SQL
- * statement, eg: insert into LogTable (Thread, Class, Message) values
- * ("%t", "%c", "%m").
- *
- * Be careful of quotes in your messages!
- *
- * Also see PatternLayout.
- */
protected String sqlStatement = "";
- /**
- * size of LoggingEvent buffer before writting to the database.
- * Default is 1.
- */
protected int bufferSize = 1;
- /**
- * ArrayList holding the buffer of Logging Events.
- */
protected ArrayList buffer;
- /**
- * Helper object for clearing out the buffer
- */
protected ArrayList removes;
- private boolean locationInfo = false;
-
public JDBCAppender() {
- super();
- buffer = new ArrayList(bufferSize);
- removes = new ArrayList(bufferSize);
+ LogLog.error(JDBC_UNSUPPORTED);
}
- /**
- * Gets whether the location of the logging request call
- * should be captured.
- *
- * @since 1.2.16
- * @return the current value of the LocationInfo option.
- */
public boolean getLocationInfo() {
- return locationInfo;
+ return false;
}
- /**
- * The LocationInfo option takes a boolean value. By default, it is
- * set to false which means there will be no effort to extract the location
- * information related to the event. As a result, the event that will be
- * ultimately logged will likely to contain the wrong location information
- * (if present in the log format).
- *
- *
- * Location information extraction is comparatively very slow and should be
- * avoided unless performance is not a concern.
- *
JMS {@link Topic topics} and {@link TopicConnectionFactory topic - * connection factories} are administered objects that are retrieved - * using JNDI messaging which in turn requires the retrieval of a JNDI - * {@link Context}. - - *
There are two common methods for retrieving a JNDI {@link - * Context}. If a file resource named jndi.properties is - * available to the JNDI API, it will use the information found - * therein to retrieve an initial JNDI context. To obtain an initial - * context, your code will simply call: - -
- InitialContext jndiContext = new InitialContext(); -- - *
Calling the no-argument InitialContext()
method
- * will also work from within Enterprise Java Beans (EJBs) because it
- * is part of the EJB contract for application servers to provide each
- * bean an environment naming context (ENC).
-
- *
In the second approach, several predetermined properties are set
- * and these properties are passed to the InitialContext
- * constructor to connect to the naming service provider. For example,
- * to connect to JBoss naming service one would write:
-
-
- Properties env = new Properties( ); - env.put(Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory"); - env.put(Context.PROVIDER_URL, "jnp://hostname:1099"); - env.put(Context.URL_PKG_PREFIXES, "org.jboss.naming:org.jnp.interfaces"); - InitialContext jndiContext = new InitialContext(env); -- - * where hostname is the host where the JBoss application - * server is running. - * - *
To connect to the the naming service of Weblogic application - * server one would write: - -
- Properties env = new Properties( ); - env.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory"); - env.put(Context.PROVIDER_URL, "t3://localhost:7001"); - InitialContext jndiContext = new InitialContext(env); -- - *
Other JMS providers will obviously require different values.
- *
- * The initial JNDI context can be obtained by calling the
- * no-argument InitialContext()
method in EJBs. Only
- * clients running in a separate JVM need to be concerned about the
- * jndi.properties file and calling {@link
- * InitialContext#InitialContext()} or alternatively correctly
- * setting the different properties before calling {@link
- * InitialContext#InitialContext(java.util.Hashtable)} method.
-
-
- @author Ceki Gülcü */
+ * A simple appender that used to publish to a JMS Topic in Log4j up to 1.2.17.
+ *
+ * Changed in 1.2.18+ to complain about its use and do nothing else.
+ * See the log4j 1.2 homepage
+ * for more information on why this class is disabled since 1.2.18.
+ *
+ * @author Ceki Gülcü
+ * @deprecated
+ * @noinspection unused
+ */
public class JMSAppender extends AppenderSkeleton {
- String securityPrincipalName;
- String securityCredentials;
- String initialContextFactoryName;
- String urlPkgPrefixes;
- String providerURL;
- String topicBindingName;
- String tcfBindingName;
- String userName;
- String password;
- boolean locationInfo;
-
- TopicConnection topicConnection;
- TopicSession topicSession;
- TopicPublisher topicPublisher;
+ static final String JMS_UNSUPPORTED =
+ "ERROR-LOG4J-NETWORKING-UNSUPPORTED: JMS unsupported!" +
+ " This is a breaking change in Log4J 1 >=1.2.18. Change your config to stop using JMS!";
public
JMSAppender() {
+ LogLog.error(JMS_UNSUPPORTED);
}
- /**
- The TopicConnectionFactoryBindingName option takes a
- string value. Its value will be used to lookup the appropriate
- TopicConnectionFactory
from the JNDI context.
- */
public
void setTopicConnectionFactoryBindingName(String tcfBindingName) {
- this.tcfBindingName = tcfBindingName;
}
- /**
- Returns the value of the TopicConnectionFactoryBindingName option.
- */
public
String getTopicConnectionFactoryBindingName() {
- return tcfBindingName;
+ return null;
}
- /**
- The TopicBindingName option takes a
- string value. Its value will be used to lookup the appropriate
- Topic
from the JNDI context.
- */
public
void setTopicBindingName(String topicBindingName) {
- this.topicBindingName = topicBindingName;
}
- /**
- Returns the value of the TopicBindingName option.
- */
public
String getTopicBindingName() {
- return topicBindingName;
+ return null;
}
-
- /**
- Returns value of the LocationInfo property which
- determines whether location (stack) info is sent to the remote
- subscriber. */
public
boolean getLocationInfo() {
- return locationInfo;
+ return false;
}
- /**
- * Options are activated and become effective only after calling
- * this method.*/
public void activateOptions() {
- TopicConnectionFactory topicConnectionFactory;
-
- try {
- Context jndi;
-
- LogLog.debug("Getting initial context.");
- if(initialContextFactoryName != null) {
- Properties env = new Properties( );
- env.put(Context.INITIAL_CONTEXT_FACTORY, initialContextFactoryName);
- if(providerURL != null) {
- env.put(Context.PROVIDER_URL, providerURL);
- } else {
- LogLog.warn("You have set InitialContextFactoryName option but not the "
- +"ProviderURL. This is likely to cause problems.");
- }
- if(urlPkgPrefixes != null) {
- env.put(Context.URL_PKG_PREFIXES, urlPkgPrefixes);
- }
-
- if(securityPrincipalName != null) {
- env.put(Context.SECURITY_PRINCIPAL, securityPrincipalName);
- if(securityCredentials != null) {
- env.put(Context.SECURITY_CREDENTIALS, securityCredentials);
- } else {
- LogLog.warn("You have set SecurityPrincipalName option but not the "
- +"SecurityCredentials. This is likely to cause problems.");
- }
- }
- jndi = new InitialContext(env);
- } else {
- jndi = new InitialContext();
- }
-
- LogLog.debug("Looking up ["+tcfBindingName+"]");
- topicConnectionFactory = (TopicConnectionFactory) lookup(jndi, tcfBindingName);
- LogLog.debug("About to create TopicConnection.");
- if(userName != null) {
- topicConnection = topicConnectionFactory.createTopicConnection(userName,
- password);
- } else {
- topicConnection = topicConnectionFactory.createTopicConnection();
- }
-
- LogLog.debug("Creating TopicSession, non-transactional, "
- +"in AUTO_ACKNOWLEDGE mode.");
- topicSession = topicConnection.createTopicSession(false,
- Session.AUTO_ACKNOWLEDGE);
-
- LogLog.debug("Looking up topic name ["+topicBindingName+"].");
- Topic topic = (Topic) lookup(jndi, topicBindingName);
-
- LogLog.debug("Creating TopicPublisher.");
- topicPublisher = topicSession.createPublisher(topic);
-
- LogLog.debug("Starting TopicConnection.");
- topicConnection.start();
-
- jndi.close();
- } catch(JMSException e) {
- errorHandler.error("Error while activating options for appender named ["+name+
- "].", e, ErrorCode.GENERIC_FAILURE);
- } catch(NamingException e) {
- errorHandler.error("Error while activating options for appender named ["+name+
- "].", e, ErrorCode.GENERIC_FAILURE);
- } catch(RuntimeException e) {
- errorHandler.error("Error while activating options for appender named ["+name+
- "].", e, ErrorCode.GENERIC_FAILURE);
- }
}
protected Object lookup(Context ctx, String name) throws NamingException {
- try {
- return ctx.lookup(name);
- } catch(NameNotFoundException e) {
- LogLog.error("Could not find name ["+name+"].");
- throw e;
- }
+ LogLog.error(JMS_UNSUPPORTED);
+ throw new NameNotFoundException(JMS_UNSUPPORTED);
}
+ /** @noinspection UnusedReturnValue*/
protected boolean checkEntryConditions() {
- String fail = null;
-
- if(this.topicConnection == null) {
- fail = "No TopicConnection";
- } else if(this.topicSession == null) {
- fail = "No TopicSession";
- } else if(this.topicPublisher == null) {
- fail = "No TopicPublisher";
- }
-
- if(fail != null) {
- errorHandler.error(fail +" for JMSAppender named ["+name+"].");
- return false;
- } else {
- return true;
- }
+ errorHandler.error(JMS_UNSUPPORTED);
+ return false;
}
- /**
- Close this JMSAppender. Closing releases all resources used by the
- appender. A closed appender cannot be re-opened. */
public synchronized void close() {
- // The synchronized modifier avoids concurrent append and close operations
-
- if(this.closed)
- return;
+ if(this.closed) {
+ return;
+ }
LogLog.debug("Closing appender ["+name+"].");
this.closed = true;
-
- try {
- if(topicSession != null)
- topicSession.close();
- if(topicConnection != null)
- topicConnection.close();
- } catch(JMSException e) {
- LogLog.error("Error while closing JMSAppender ["+name+"].", e);
- } catch(RuntimeException e) {
- LogLog.error("Error while closing JMSAppender ["+name+"].", e);
- }
- // Help garbage collection
- topicPublisher = null;
- topicSession = null;
- topicConnection = null;
}
- /**
- This method called by {@link AppenderSkeleton#doAppend} method to
- do most of the real appending work. */
public void append(LoggingEvent event) {
- if(!checkEntryConditions()) {
- return;
- }
-
- try {
- ObjectMessage msg = topicSession.createObjectMessage();
- if(locationInfo) {
- event.getLocationInformation();
- }
- msg.setObject(event);
- topicPublisher.publish(msg);
- } catch(JMSException e) {
- errorHandler.error("Could not publish message in JMSAppender ["+name+"].", e,
- ErrorCode.GENERIC_FAILURE);
- } catch(RuntimeException e) {
- errorHandler.error("Could not publish message in JMSAppender ["+name+"].", e,
- ErrorCode.GENERIC_FAILURE);
- }
+ checkEntryConditions();
}
- /**
- * Returns the value of the InitialContextFactoryName option.
- * See {@link #setInitialContextFactoryName} for more details on the
- * meaning of this option.
- * */
public String getInitialContextFactoryName() {
- return initialContextFactoryName;
+ return null;
}
- /**
- * Setting the InitialContextFactoryName method will cause
- * this JMSAppender
instance to use the {@link
- * InitialContext#InitialContext(Hashtable)} method instead of the
- * no-argument constructor. If you set this option, you should also
- * at least set the ProviderURL option.
- *
- *
See also {@link #setProviderURL(String)}. - * */ public void setInitialContextFactoryName(String initialContextFactoryName) { - this.initialContextFactoryName = initialContextFactoryName; } public String getProviderURL() { - return providerURL; + return null; } public void setProviderURL(String providerURL) { - this.providerURL = providerURL; } String getURLPkgPrefixes( ) { - return urlPkgPrefixes; + return null; } public void setURLPkgPrefixes(String urlPkgPrefixes ) { - this.urlPkgPrefixes = urlPkgPrefixes; } public String getSecurityCredentials() { - return securityCredentials; + return null; } public void setSecurityCredentials(String securityCredentials) { - this.securityCredentials = securityCredentials; } - - + public String getSecurityPrincipalName() { - return securityPrincipalName; + return null; } public void setSecurityPrincipalName(String securityPrincipalName) { - this.securityPrincipalName = securityPrincipalName; } public String getUserName() { - return userName; + return null; } - /** - * The user name to use when {@link - * TopicConnectionFactory#createTopicConnection(String, String) - * creating a topic session}. If you set this option, you should - * also set the Password option. See {@link - * #setPassword(String)}. - * */ public void setUserName(String userName) { - this.userName = userName; } public String getPassword() { - return password; + return null; } - /** - * The paswword to use when creating a topic session. - */ public void setPassword(String password) { - this.password = password; } - - /** - If true, the information sent to the remote subscriber will - include caller's location information. By default no location - information is sent to the subscriber. */ public void setLocationInfo(boolean locationInfo) { - this.locationInfo = locationInfo; } - /** - * Returns the TopicConnection used for this appender. Only valid after - * activateOptions() method has been invoked. - */ protected TopicConnection getTopicConnection() { - return topicConnection; + throw new IllegalStateException(JMS_UNSUPPORTED); } - /** - * Returns the TopicSession used for this appender. Only valid after - * activateOptions() method has been invoked. - */ protected TopicSession getTopicSession() { - return topicSession; + throw new IllegalStateException(JMS_UNSUPPORTED); } - /** - * Returns the TopicPublisher used for this appender. Only valid after - * activateOptions() method has been invoked. - */ protected TopicPublisher getTopicPublisher() { - return topicPublisher; + throw new IllegalStateException(JMS_UNSUPPORTED); } - /** - * The JMSAppender sends serialized events and consequently does not - * require a layout. - */ public boolean requiresLayout() { return false; } diff --git a/src/main/java/org/apache/log4j/net/JMSSink.java b/src/main/java/org/apache/log4j/net/JMSSink.java index 6a02831e1a..e64e4debd8 100644 --- a/src/main/java/org/apache/log4j/net/JMSSink.java +++ b/src/main/java/org/apache/log4j/net/JMSSink.java @@ -17,137 +17,45 @@ package org.apache.log4j.net; -import org.apache.log4j.Logger; -import org.apache.log4j.PropertyConfigurator; -import org.apache.log4j.spi.LoggingEvent; -import org.apache.log4j.xml.DOMConfigurator; +import org.apache.log4j.helpers.LogLog; -import javax.jms.JMSException; -import javax.jms.ObjectMessage; -import javax.jms.Session; -import javax.jms.Topic; -import javax.jms.TopicConnection; -import javax.jms.TopicConnectionFactory; -import javax.jms.TopicSession; -import javax.jms.TopicSubscriber; import javax.naming.Context; -import javax.naming.InitialContext; -import javax.naming.NameNotFoundException; import javax.naming.NamingException; -import java.io.BufferedReader; -import java.io.InputStreamReader; /** * A simple application that consumes logging events sent by a {@link - * JMSAppender}. + * JMSAppender} in Log4j up to 1.2.17. * + * Changed in 1.2.18+ to complain about its use and do nothing else. + * See the log4j 1.2 homepage + * for more information on why this class is disabled since 1.2.18. * * @author Ceki Gülcü - * */ + */ public class JMSSink implements javax.jms.MessageListener { - static Logger logger = Logger.getLogger(JMSSink.class); - static public void main(String[] args) throws Exception { - if(args.length != 5) { - usage("Wrong number of arguments."); - } - - String tcfBindingName = args[0]; - String topicBindingName = args[1]; - String username = args[2]; - String password = args[3]; - - - String configFile = args[4]; - - if(configFile.endsWith(".xml")) { - DOMConfigurator.configure(configFile); - } else { - PropertyConfigurator.configure(configFile); - } - - new JMSSink(tcfBindingName, topicBindingName, username, password); - - BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in)); - // Loop until the word "exit" is typed - System.out.println("Type \"exit\" to quit JMSSink."); - while(true){ - String s = stdin.readLine( ); - if (s.equalsIgnoreCase("exit")) { - System.out.println("Exiting. Kill the application if it does not exit " - + "due to daemon threads."); - return; - } - } + usage(); } - public JMSSink( String tcfBindingName, String topicBindingName, String username, - String password) { - - try { - Context ctx = new InitialContext(); - TopicConnectionFactory topicConnectionFactory; - topicConnectionFactory = (TopicConnectionFactory) lookup(ctx, - tcfBindingName); - - TopicConnection topicConnection = - topicConnectionFactory.createTopicConnection(username, - password); - topicConnection.start(); - - TopicSession topicSession = topicConnection.createTopicSession(false, - Session.AUTO_ACKNOWLEDGE); - - Topic topic = (Topic)ctx.lookup(topicBindingName); - - TopicSubscriber topicSubscriber = topicSession.createSubscriber(topic); - - topicSubscriber.setMessageListener(this); - - } catch(JMSException e) { - logger.error("Could not read JMS message.", e); - } catch(NamingException e) { - logger.error("Could not read JMS message.", e); - } catch(RuntimeException e) { - logger.error("Could not read JMS message.", e); - } + /** @noinspection unused*/ + public JMSSink(String tcfBindingName, String topicBindingName, String username, + String password) { + LogLog.error(JMSAppender.JMS_UNSUPPORTED); } public void onMessage(javax.jms.Message message) { - LoggingEvent event; - Logger remoteLogger; - - try { - if(message instanceof ObjectMessage) { - ObjectMessage objectMessage = (ObjectMessage) message; - event = (LoggingEvent) objectMessage.getObject(); - remoteLogger = Logger.getLogger(event.getLoggerName()); - remoteLogger.callAppenders(event); - } else { - logger.warn("Received message is of type "+message.getJMSType() - +", was expecting ObjectMessage."); - } - } catch(JMSException jmse) { - logger.error("Exception thrown while processing incoming message.", - jmse); - } + LogLog.error(JMSAppender.JMS_UNSUPPORTED); } - + /** @noinspection unused, UnusedReturnValue, SameParameterValue */ protected static Object lookup(Context ctx, String name) throws NamingException { - try { - return ctx.lookup(name); - } catch(NameNotFoundException e) { - logger.error("Could not find name ["+name+"]."); - throw e; - } + LogLog.error(JMSAppender.JMS_UNSUPPORTED); + throw new NamingException(JMSAppender.JMS_UNSUPPORTED); } - static void usage(String msg) { - System.err.println(msg); - System.err.println("Usage: java " + JMSSink.class.getName() - + " TopicConnectionFactoryBindingName TopicBindingName username password configFile"); + static void usage() { + System.err.println(JMSAppender.JMS_UNSUPPORTED); System.exit(1); } } diff --git a/src/main/java/org/apache/log4j/net/SMTPAppender.java b/src/main/java/org/apache/log4j/net/SMTPAppender.java index 7350474738..f6add1def5 100644 --- a/src/main/java/org/apache/log4j/net/SMTPAppender.java +++ b/src/main/java/org/apache/log4j/net/SMTPAppender.java @@ -48,6 +48,8 @@ import java.io.OutputStreamWriter; import java.io.UnsupportedEncodingException; import java.io.Writer; +import java.net.InetAddress; +import java.net.UnknownHostException; import java.util.Date; import java.util.Properties; @@ -74,6 +76,8 @@ class implements TriggeringEventEvaluator. Since 1.2.16, SMTP over SSL is supported by setting SMTPProtocol to "smpts". + Since 1.2.18, warns when using an smtp host that is not the local loopback. + @author Ceki Gülcü @since 1.0 */ public class SMTPAppender extends AppenderSkeleton @@ -134,6 +138,8 @@ public class SMTPAppender extends AppenderSkeleton recipient, from, etc. */ public void activateOptions() { + warnInCaseOfInsecureSMTP(); + Session session = createSession(); msg = new MimeMessage(session); @@ -154,7 +160,29 @@ void activateOptions() { ((OptionHandler) evaluator).activateOptions(); } } - + + void warnInCaseOfInsecureSMTP() { + boolean local = false; + if (smtpHost != null) { + try { + if (InetAddress.getByName(smtpHost).isLoopbackAddress()) { + local = true; + } + } catch (UnknownHostException e) { + // hope it'll work out later + } + } + if (!local) { + if ("smtps".equals(smtpProtocol)) { + LogLog.warn("WARN-LOG4J-NETWORKING-REMOTE-SMTPS: logging to remote SMTPS host '" + + smtpHost + "'! Log4J 1.2 cannot verify the host, upgrade to Log4J 2!"); + } else { + LogLog.warn("WARN-LOG4J-NETWORKING-REMOTE-SMTP: logging to remote SMTP host '" + + smtpHost + "'! SMTP is an unencrypted protocol."); + } + } + } + /** * Address message. * @param msg message, may not be null. @@ -342,8 +370,9 @@ protected String formatBody() { StringBuffer sbuf = new StringBuffer(); String t = layout.getHeader(); - if(t != null) - sbuf.append(t); + if(t != null) { + sbuf.append(t); + } int len = cb.length(); for(int i = 0; i < len; i++) { //sbuf.append(MimeUtility.encodeText(layout.format(cb.get()))); diff --git a/src/main/java/org/apache/log4j/net/SimpleSocketServer.java b/src/main/java/org/apache/log4j/net/SimpleSocketServer.java index c15aa3cca2..fc51b7a65f 100644 --- a/src/main/java/org/apache/log4j/net/SimpleSocketServer.java +++ b/src/main/java/org/apache/log4j/net/SimpleSocketServer.java @@ -17,81 +17,31 @@ package org.apache.log4j.net; -import java.net.ServerSocket; -import java.net.Socket; - -import org.apache.log4j.LogManager; -import org.apache.log4j.Logger; -import org.apache.log4j.PropertyConfigurator; -import org.apache.log4j.xml.DOMConfigurator; - - /** - * A simple {@link SocketNode} based server. + * A simple {@link SocketNode} based server in Log4j up to 1.2.17. * -
- Usage: java org.apache.log4j.net.SimpleSocketServer port configFile - - where port is a part number where the server listens and - configFile is a configuration file fed to the {@link - PropertyConfigurator} or to {@link DOMConfigurator} if an XML file. -- * - * @author Ceki Gülcü - * - * @since 0.8.4 - * */ + * Changed in 1.2.18+ to complain about its use and do nothing else. + * See the log4j 1.2 homepage + * for more information on why this class is disabled since 1.2.18. + * + * @author Ceki Gülcü + * @since 0.8.4 + */ public class SimpleSocketServer { - static Logger cat = Logger.getLogger(SimpleSocketServer.class); - - static int port; + static final String SOCKET_SERVER_UNSUPPORTED = + "ERROR-LOG4J-NETWORKING-UNSUPPORTED: SimpleSocketServer unsupported!" + + " This is a breaking change in Log4J 1 >=1.2.18. Stop using this class!"; public static void main(String argv[]) { - if(argv.length == 2) { - init(argv[0], argv[1]); - } else { - usage("Wrong number of arguments."); - } - - try { - cat.info("Listening on port " + port); - ServerSocket serverSocket = new ServerSocket(port); - while(true) { - cat.info("Waiting to accept a new client."); - Socket socket = serverSocket.accept(); - cat.info("Connected to client at " + socket.getInetAddress()); - cat.info("Starting new socket node."); - new Thread(new SocketNode(socket, - LogManager.getLoggerRepository()),"SimpleSocketServer-" + port).start(); - } - } catch(Exception e) { - e.printStackTrace(); - } + usage(); } - - static void usage(String msg) { - System.err.println(msg); - System.err.println( - "Usage: java " +SimpleSocketServer.class.getName() + " port configFile"); + static void usage() { + System.err.println(SOCKET_SERVER_UNSUPPORTED); System.exit(1); } - static void init(String portStr, String configFile) { - try { - port = Integer.parseInt(portStr); - } catch(java.lang.NumberFormatException e) { - e.printStackTrace(); - usage("Could not interpret port number ["+ portStr +"]."); - } - - if(configFile.endsWith(".xml")) { - DOMConfigurator.configure(configFile); - } else { - PropertyConfigurator.configure(configFile); - } - } } diff --git a/src/main/java/org/apache/log4j/net/SocketAppender.java b/src/main/java/org/apache/log4j/net/SocketAppender.java index 855b057931..8f305e6ff6 100644 --- a/src/main/java/org/apache/log4j/net/SocketAppender.java +++ b/src/main/java/org/apache/log4j/net/SocketAppender.java @@ -97,6 +97,10 @@ is slow but still faster than the rate of (log) event production @author Ceki Gülcü + @deprecated + The server side of the log4j socket protocol has been disabled + in Log4j >= 1.2.18. Change your config to ship logs using a + modern and secure protocol! @since 0.8.4 */ public class SocketAppender extends AppenderSkeleton { @@ -181,8 +185,9 @@ public void activateOptions() { * #cleanUp} method. * */ synchronized public void close() { - if(closed) - return; + if(closed) { + return; + } this.closed = true; if (advertiseViaMulticastDNS) { @@ -216,8 +221,9 @@ public void cleanUp() { } void connect(InetAddress address, int port) { - if(this.address == null) - return; + if(this.address == null) { + return; + } try { // First, close the previous connection if any. cleanUp(); @@ -241,8 +247,9 @@ void connect(InetAddress address, int port) { public void append(LoggingEvent event) { - if(event == null) - return; + if(event == null) { + return; + } if(address==null) { errorHandler.error("No remote host is set for SocketAppender named \""+ diff --git a/src/main/java/org/apache/log4j/net/SocketHubAppender.java b/src/main/java/org/apache/log4j/net/SocketHubAppender.java index 7c69acdf28..d8ba449b60 100644 --- a/src/main/java/org/apache/log4j/net/SocketHubAppender.java +++ b/src/main/java/org/apache/log4j/net/SocketHubAppender.java @@ -18,250 +18,63 @@ package org.apache.log4j.net; import java.io.IOException; -import java.io.InterruptedIOException; -import java.io.ObjectOutputStream; -import java.net.InetAddress; import java.net.ServerSocket; -import java.net.Socket; -import java.net.SocketException; -import java.util.Vector; import org.apache.log4j.AppenderSkeleton; -import org.apache.log4j.helpers.CyclicBuffer; import org.apache.log4j.helpers.LogLog; import org.apache.log4j.spi.LoggingEvent; /** Sends {@link LoggingEvent} objects to a set of remote log servers, - usually a {@link SocketNode SocketNodes}. - -
Acts just like {@link SocketAppender} except that instead of
- connecting to a given remote log server,
- SocketHubAppender
accepts connections from the remote
- log servers as clients. It can accept more than one connection.
- When a log event is received, the event is sent to the set of
- currently connected remote log servers. Implemented this way it does
- not require any update to the configuration file to send data to
- another remote log server. The remote log server simply connects to
- the host and port the SocketHubAppender
is running on.
-
-
The SocketHubAppender
does not store events such
- that the remote side will events that arrived after the
- establishment of its connection. Once connected, events arrive in
- order as guaranteed by the TCP protocol.
+ usually a {@link SocketNode SocketNodes} in Log4j up to 1.2.17.
-
This implementation borrows heavily from the {@link - SocketAppender}. - -
The SocketHubAppender has the following characteristics: - -
SocketHubAppender
does not use a layout. It
- ships a serialized {@link LoggingEvent} object to the remote side.
-
- SocketHubAppender
relies on the TCP
- protocol. Consequently, if the remote side is reachable, then log
- events will eventually arrive at remote client.
-
- On the other hand, if the network link is up, but the remote - client is down, the client will not be blocked when making log - requests but the log events will be lost due to client - unavailability. - -
The single remote client case extends to multiple clients - connections. The rate of logging will be determined by the slowest - link. - -
SocketHubAppender
exits
- before the SocketHubAppender
is closed either
- explicitly or subsequent to garbage collection, then there might
- be untransmitted data in the pipe which might be lost. This is a
- common problem on Windows based systems.
-
- To avoid lost data, it is usually sufficient to {@link #close}
- the SocketHubAppender
either explicitly or by calling
- the {@link org.apache.log4j.LogManager#shutdown} method before
- exiting the application.
-
-
address
and port
. */
public
SocketHubAppender(int _port) {
- port = _port;
- startServer();
+ LogLog.error(SOCKET_HUB_UNSUPPORTED);
}
- /**
- Set up the socket server on the specified port. */
public
void activateOptions() {
- if (advertiseViaMulticastDNS) {
- zeroConf = new ZeroConfSupport(ZONE, port, getName());
- zeroConf.advertise();
- }
- startServer();
}
- /**
- Close this appender.
- This will mark the appender as closed and - call then {@link #cleanUp} method. */ synchronized public void close() { - if(closed) - return; - - LogLog.debug("closing SocketHubAppender " + getName()); - this.closed = true; - if (advertiseViaMulticastDNS) { - zeroConf.unadvertise(); - } - cleanUp(); - - LogLog.debug("SocketHubAppender " + getName() + " closed"); } - /** - Release the underlying ServerMonitor thread, and drop the connections - to all connected remote servers. */ - public + public void cleanUp() { - // stop the monitor thread - LogLog.debug("stopping ServerSocket"); - serverMonitor.stopMonitor(); - serverMonitor = null; - - // close all of the connections - LogLog.debug("closing client connections"); - while (oosList.size() != 0) { - ObjectOutputStream oos = (ObjectOutputStream)oosList.elementAt(0); - if(oos != null) { - try { - oos.close(); - } catch(InterruptedIOException e) { - Thread.currentThread().interrupt(); - LogLog.error("could not close oos.", e); - } catch(IOException e) { - LogLog.error("could not close oos.", e); - } - - oosList.removeElementAt(0); - } - } } - /** - Append an event to all of current connections. */ public void append(LoggingEvent event) { - if (event != null) { - // set up location info if requested - if (locationInfo) { - event.getLocationInformation(); - } - if (application != null) { - event.setProperty("application", application); - } - event.getNDC(); - event.getThreadName(); - event.getMDCCopy(); - event.getRenderedMessage(); - event.getThrowableStrRep(); - - if (buffer != null) { - buffer.add(event); - } - } - - // if no event or no open connections, exit now - if ((event == null) || (oosList.size() == 0)) { - return; - } - - // loop through the current set of open connections, appending the event to each - for (int streamCount = 0; streamCount < oosList.size(); streamCount++) { - - ObjectOutputStream oos = null; - try { - oos = (ObjectOutputStream)oosList.elementAt(streamCount); - } - catch (ArrayIndexOutOfBoundsException e) { - // catch this, but just don't assign a value - // this should not really occur as this method is - // the only one that can remove oos's (besides cleanUp). - } - - // list size changed unexpectedly? Just exit the append. - if (oos == null) - break; - - try { - oos.writeObject(event); - oos.flush(); - // Failing to reset the object output stream every now and - // then creates a serious memory leak. - // right now we always reset. TODO - set up frequency counter per oos? - oos.reset(); - } - catch(IOException e) { - if (e instanceof InterruptedIOException) { - Thread.currentThread().interrupt(); - } - // there was an io exception so just drop the connection - oosList.removeElementAt(streamCount); - LogLog.debug("dropped connection"); - - // decrement to keep the counter in place (for loop always increments) - streamCount--; - } - } } /** @@ -272,241 +85,50 @@ boolean requiresLayout() { return false; } - /** - The Port option takes a positive integer representing - the port where the server is waiting for connections. */ public void setPort(int _port) { - port = _port; } - /** - * The App option takes a string value which should be the name of the application getting logged. If property was already set (via system - * property), don't set here. - */ - public + public void setApplication(String lapp) { - this.application = lapp; } - /** - * Returns value of the Application option. - */ - public + public String getApplication() { - return application; + return null; } - /** - Returns value of the Port option. */ public int getPort() { - return port; + return 0; } - /** - * The BufferSize option takes a positive integer representing the number of events this appender will buffer and send to newly connected - * clients. - */ - public + public void setBufferSize(int _bufferSize) { - buffer = new CyclicBuffer(_bufferSize); } - /** - * Returns value of the bufferSize option. - */ - public + public int getBufferSize() { - if (buffer == null) { - return 0; - } else { - return buffer.getMaxSize(); - } + return 0; } - /** - The LocationInfo option takes a boolean value. If true, - the information sent to the remote host will include location - information. By default no location information is sent to the server. */ public void setLocationInfo(boolean _locationInfo) { - locationInfo = _locationInfo; } - /** - Returns value of the LocationInfo option. */ public boolean getLocationInfo() { - return locationInfo; + return false; } public void setAdvertiseViaMulticastDNS(boolean advertiseViaMulticastDNS) { - this.advertiseViaMulticastDNS = advertiseViaMulticastDNS; } public boolean isAdvertiseViaMulticastDNS() { - return advertiseViaMulticastDNS; + return false; } - /** - Start the ServerMonitor thread. */ - private - void startServer() { - serverMonitor = new ServerMonitor(port, oosList); - } - - /** - * Creates a server socket to accept connections. - * @param socketPort port on which the socket should listen, may be zero. - * @return new socket. - * @throws IOException IO error when opening the socket. - */ protected ServerSocket createServerSocket(final int socketPort) throws IOException { - return new ServerSocket(socketPort); - } - - /** - This class is used internally to monitor a ServerSocket - and register new connections in a vector passed in the - constructor. */ - private class ServerMonitor implements Runnable { - private int port; - private Vector oosList; - private boolean keepRunning; - private Thread monitorThread; - - /** - Create a thread and start the monitor. */ - public - ServerMonitor(int _port, Vector _oosList) { - port = _port; - oosList = _oosList; - keepRunning = true; - monitorThread = new Thread(this); - monitorThread.setDaemon(true); - monitorThread.setName("SocketHubAppender-Monitor-" + port); - monitorThread.start(); - } - - /** - Stops the monitor. This method will not return until - the thread has finished executing. */ - public synchronized void stopMonitor() { - if (keepRunning) { - LogLog.debug("server monitor thread shutting down"); - keepRunning = false; - try { - if (serverSocket != null) { - serverSocket.close(); - serverSocket = null; - } - } catch (IOException ioe) {} - - try { - monitorThread.join(); - } - catch (InterruptedException e) { - Thread.currentThread().interrupt(); - // do nothing? - } - - // release the thread - monitorThread = null; - LogLog.debug("server monitor thread shut down"); - } - } - - private - void sendCachedEvents(ObjectOutputStream stream) throws IOException { - if (buffer != null) { - for (int i = 0; i < buffer.length(); i++) { - stream.writeObject(buffer.get(i)); - } - stream.flush(); - stream.reset(); - } - } - - /** - Method that runs, monitoring the ServerSocket and adding connections as - they connect to the socket. */ - public - void run() { - serverSocket = null; - try { - serverSocket = createServerSocket(port); - serverSocket.setSoTimeout(1000); - } - catch (Exception e) { - if (e instanceof InterruptedIOException || e instanceof InterruptedException) { - Thread.currentThread().interrupt(); - } - LogLog.error("exception setting timeout, shutting down server socket.", e); - keepRunning = false; - return; - } - - try { - try { - serverSocket.setSoTimeout(1000); - } - catch (SocketException e) { - LogLog.error("exception setting timeout, shutting down server socket.", e); - return; - } - - while (keepRunning) { - Socket socket = null; - try { - socket = serverSocket.accept(); - } - catch (InterruptedIOException e) { - // timeout occurred, so just loop - } - catch (SocketException e) { - LogLog.error("exception accepting socket, shutting down server socket.", e); - keepRunning = false; - } - catch (IOException e) { - LogLog.error("exception accepting socket.", e); - } - - // if there was a socket accepted - if (socket != null) { - try { - InetAddress remoteAddress = socket.getInetAddress(); - LogLog.debug("accepting connection from " + remoteAddress.getHostName() - + " (" + remoteAddress.getHostAddress() + ")"); - - // create an ObjectOutputStream - ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream()); - if (buffer != null && buffer.length() > 0) { - sendCachedEvents(oos); - } - - // add it to the oosList. OK since Vector is synchronized. - oosList.addElement(oos); - } catch (IOException e) { - if (e instanceof InterruptedIOException) { - Thread.currentThread().interrupt(); - } - LogLog.error("exception creating output stream on socket.", e); - } - } - } - } - finally { - // close the socket - try { - serverSocket.close(); - } catch(InterruptedIOException e) { - Thread.currentThread().interrupt(); - } catch (IOException e) { - // do nothing with it? - } - } - } + throw new IOException(SOCKET_HUB_UNSUPPORTED); } } - diff --git a/src/main/java/org/apache/log4j/net/SocketNode.java b/src/main/java/org/apache/log4j/net/SocketNode.java index e977f1333a..ae3827f2fa 100644 --- a/src/main/java/org/apache/log4j/net/SocketNode.java +++ b/src/main/java/org/apache/log4j/net/SocketNode.java @@ -17,13 +17,9 @@ package org.apache.log4j.net; -import java.io.BufferedInputStream; -import java.io.IOException; -import java.io.InterruptedIOException; -import java.io.ObjectInputStream; import java.net.Socket; -import org.apache.log4j.Logger; +import org.apache.log4j.helpers.LogLog; import org.apache.log4j.spi.LoggerRepository; import org.apache.log4j.spi.LoggingEvent; @@ -31,94 +27,29 @@ /** Read {@link LoggingEvent} objects sent from a remote client using - Sockets (TCP). These logging events are logged according to local - policy, as if they were generated locally. + Sockets (TCP) in Log4j up to 1.2.17. -
For example, the socket node might decide to log events to a - local file and also resent them to a second socket node. + Changed in 1.2.18+ to complain about its use and do nothing else. + See the log4j 1.2 homepage + for more information on why this class is disabled since 1.2.18. - @author Ceki Gülcü + @author Ceki Gülcü - @since 0.8.4 + @since 0.8.4 + @deprecated + @noinspection unused */ public class SocketNode implements Runnable { - Socket socket; - LoggerRepository hierarchy; - ObjectInputStream ois; - - static Logger logger = Logger.getLogger(SocketNode.class); + static final String SOCKET_NODE_UNSUPPORTED = + "ERROR-LOG4J-NETWORKING-UNSUPPORTED: SocketNode unsupported!" + + " This is a breaking change in Log4J 1 >=1.2.18. Stop using this class!"; public SocketNode(Socket socket, LoggerRepository hierarchy) { - this.socket = socket; - this.hierarchy = hierarchy; - try { - ois = new ObjectInputStream( - new BufferedInputStream(socket.getInputStream())); - } catch(InterruptedIOException e) { - Thread.currentThread().interrupt(); - logger.error("Could not open ObjectInputStream to "+socket, e); - } catch(IOException e) { - logger.error("Could not open ObjectInputStream to "+socket, e); - } catch(RuntimeException e) { - logger.error("Could not open ObjectInputStream to "+socket, e); - } + LogLog.error(SOCKET_NODE_UNSUPPORTED); } - //public - //void finalize() { - //System.err.println("-------------------------Finalize called"); - // System.err.flush(); - //} - public void run() { - LoggingEvent event; - Logger remoteLogger; - - try { - if (ois != null) { - while(true) { - // read an event from the wire - event = (LoggingEvent) ois.readObject(); - // get a logger from the hierarchy. The name of the logger is taken to be the name contained in the event. - remoteLogger = hierarchy.getLogger(event.getLoggerName()); - //event.logger = remoteLogger; - // apply the logger-level filter - if(event.getLevel().isGreaterOrEqual(remoteLogger.getEffectiveLevel())) { - // finally log the event as if was generated locally - remoteLogger.callAppenders(event); - } - } - } - } catch(java.io.EOFException e) { - logger.info("Caught java.io.EOFException closing conneciton."); - } catch(java.net.SocketException e) { - logger.info("Caught java.net.SocketException closing conneciton."); - } catch(InterruptedIOException e) { - Thread.currentThread().interrupt(); - logger.info("Caught java.io.InterruptedIOException: "+e); - logger.info("Closing connection."); - } catch(IOException e) { - logger.info("Caught java.io.IOException: "+e); - logger.info("Closing connection."); - } catch(Exception e) { - logger.error("Unexpected exception. Closing conneciton.", e); - } finally { - if (ois != null) { - try { - ois.close(); - } catch(Exception e) { - logger.info("Could not close connection.", e); - } - } - if (socket != null) { - try { - socket.close(); - } catch(InterruptedIOException e) { - Thread.currentThread().interrupt(); - } catch(IOException ex) { - } - } - } + LogLog.error(SOCKET_NODE_UNSUPPORTED); } } diff --git a/src/main/java/org/apache/log4j/net/SocketServer.java b/src/main/java/org/apache/log4j/net/SocketServer.java index 8ea3cb79a1..de2b7fa322 100644 --- a/src/main/java/org/apache/log4j/net/SocketServer.java +++ b/src/main/java/org/apache/log4j/net/SocketServer.java @@ -17,196 +17,44 @@ package org.apache.log4j.net; -import java.io.File; -import java.net.InetAddress; -import java.net.ServerSocket; -import java.net.Socket; -import java.util.Hashtable; +import org.apache.log4j.helpers.LogLog; -import org.apache.log4j.Hierarchy; -import org.apache.log4j.Level; -import org.apache.log4j.LogManager; -import org.apache.log4j.Logger; -import org.apache.log4j.PropertyConfigurator; -import org.apache.log4j.spi.LoggerRepository; -import org.apache.log4j.spi.RootLogger; +import java.io.File; /** A {@link SocketNode} based server that uses a different hierarchy - for each client. - -
- Usage: java org.apache.log4j.net.SocketServer port configFile configDir - - where port is a part number where the server listens, - configFile is a configuration file fed to the {@link PropertyConfigurator} and - configDir is a path to a directory containing configuration files, possibly one for each client host. -- -
The configFile
is used to configure the log4j
- default hierarchy that the SocketServer
will use to
- report on its actions.
-
-
When a new connection is opened from a previously unknown
- host, say foo.bar.net
, then the
- SocketServer
will search for a configuration file
- called foo.bar.net.lcf
under the directory
- configDir
that was passed as the third argument. If
- the file can be found, then a new hierarchy is instantiated and
- configured using the configuration file
- foo.bar.net.lcf
. If and when the host
- foo.bar.net
opens another connection to the server,
- then the previously configured hierarchy is used.
-
-
In case there is no file called foo.bar.net.lcf
- under the directory configDir
, then the
- generic hierarchy is used. The generic hierarchy is
- configured using a configuration file called
- generic.lcf
under the configDir
- directory. If no such file exists, then the generic hierarchy will be
- identical to the log4j default hierarchy.
-
-
Having different client hosts log using different hierarchies - ensures the total independence of the clients with respect to - their logging settings. + for each client in Log4j up to 1.2.17. -
Currently, the hierarchy that will be used for a given request
- depends on the IP address of the client host. For example, two
- separate applicatons running on the same host and logging to the
- same server will share the same hierarchy. This is perfectly safe
- except that it might not provide the right amount of independence
- between applications. The The TelnetAppender is a log4j appender that specializes in
- writing to a read-only socket. The output is provided in a
- telnet-friendly way so that a log can be monitored over TCP/IP.
- Clients using telnet connect to the socket and receive log data.
- This is handy for remote monitoring, especially when monitoring a
- servlet.
-
- Here is a list of the available configuration options:
-
- This method of triggering roll over has the advantage of being
- operating system independent, fast and reliable.
-
- A simple application {@link Roller} is provided to initiate the
- roll over.
-
- Note that the initiator is not authenticated. Anyone can trigger
- a rollover. In production environments, it is recommended that you
- add some form of protection to prevent undesired rollovers.
+ Port property for a "RollOver" message in Log4j up to 1.2.17.
+ Changed in 1.2.18+ to complain about its use and act as a regular
+ FileAppender otherwise. This may mean your files stop rolling over
+ if you keep using this class! See
+ the log4j 1.2 homepage
+ for more information on why this class is disabled since 1.2.18.
@author Ceki Gülcü
- @since version 0.9.0 */
+ @since version 0.9.0
+ @noinspection unused
+*/
public class ExternallyRolledFileAppender extends RollingFileAppender {
-
- /**
- The string constant sent to initiate a roll over. Current value of
- this string constant is RollOver.
- */
+ static final String EXTERNAL_ROLLING_UNSUPPORTED =
+ "ERROR-LOG4J-NETWORKING-UNSUPPORTED: External Rolled File Appender unsupported!" +
+ " This is a breaking change in Log4J 1 >=1.2.18. Change your config to stop using it!";
static final public String ROLL_OVER = "RollOver";
-
- /**
- The string constant sent to acknowledge a roll over. Current value of
- this string constant is OK.
- */
static final public String OK = "OK";
- int port = 0;
- HUP hup;
-
- /**
- The default constructor does nothing but calls its super-class
- constructor. */
public
ExternallyRolledFileAppender() {
+ super();
+ LogLog.error(EXTERNAL_ROLLING_UNSUPPORTED);
}
- /**
- The Port [roperty is used for setting the port for
- listening to external roll over messages.
- */
public
void setPort(int port) {
- this.port = port;
}
- /**
- Returns value of the Port option.
- */
public
int getPort() {
- return port;
+ return 0;
}
/**
@@ -94,96 +62,5 @@ int getPort() {
public
void activateOptions() {
super.activateOptions();
- if(port != 0) {
- if(hup != null) {
- hup.interrupt();
- }
- hup = new HUP(this, port);
- hup.setDaemon(true);
- hup.start();
- }
- }
-}
-
-
-class HUP extends Thread {
-
- int port;
- ExternallyRolledFileAppender er;
-
- HUP(ExternallyRolledFileAppender er, int port) {
- this.er = er;
- this.port = port;
- }
-
- public
- void run() {
- while(!isInterrupted()) {
- try {
- ServerSocket serverSocket = new ServerSocket(port);
- while(true) {
- Socket socket = serverSocket.accept();
- LogLog.debug("Connected to client at " + socket.getInetAddress());
- new Thread(new HUPNode(socket, er), "ExternallyRolledFileAppender-HUP").start();
- }
- } catch(InterruptedIOException e) {
- Thread.currentThread().interrupt();
- e.printStackTrace();
- } catch(IOException e) {
- e.printStackTrace();
- } catch(RuntimeException e) {
- e.printStackTrace();
- }
- }
}
}
-
-class HUPNode implements Runnable {
-
- Socket socket;
- DataInputStream dis;
- DataOutputStream dos;
- ExternallyRolledFileAppender er;
-
- public
- HUPNode(Socket socket, ExternallyRolledFileAppender er) {
- this.socket = socket;
- this.er = er;
- try {
- dis = new DataInputStream(socket.getInputStream());
- dos = new DataOutputStream(socket.getOutputStream());
- } catch(InterruptedIOException e) {
- Thread.currentThread().interrupt();
- e.printStackTrace();
- } catch(IOException e) {
- e.printStackTrace();
- } catch(RuntimeException e) {
- e.printStackTrace();
- }
- }
-
- public void run() {
- try {
- String line = dis.readUTF();
- LogLog.debug("Got external roll over signal.");
- if(ExternallyRolledFileAppender.ROLL_OVER.equals(line)) {
- synchronized(er) {
- er.rollOver();
- }
- dos.writeUTF(ExternallyRolledFileAppender.OK);
- }
- else {
- dos.writeUTF("Expecting [RollOver] string.");
- }
- dos.close();
- } catch(InterruptedIOException e) {
- Thread.currentThread().interrupt();
- LogLog.error("Unexpected exception. Exiting HUPNode.", e);
- } catch(IOException e) {
- LogLog.error("Unexpected exception. Exiting HUPNode.", e);
- } catch(RuntimeException e) {
- LogLog.error("Unexpected exception. Exiting HUPNode.", e);
- }
- }
-}
-
diff --git a/src/main/resources/META-INF/LICENSE b/src/main/resources/META-INF/LICENSE
deleted file mode 100644
index 6279e5206d..0000000000
--- a/src/main/resources/META-INF/LICENSE
+++ /dev/null
@@ -1,202 +0,0 @@
-
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
- APPENDIX: How to apply the Apache License to your work.
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "[]"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
- Copyright 1999-2005 The Apache Software Foundation
-
- Licensed 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.
diff --git a/src/main/resources/META-INF/NOTICE b/src/main/resources/META-INF/NOTICE
deleted file mode 100644
index 0375732360..0000000000
--- a/src/main/resources/META-INF/NOTICE
+++ /dev/null
@@ -1,5 +0,0 @@
-Apache log4j
-Copyright 2007 The Apache Software Foundation
-
-This product includes software developed at
-The Apache Software Foundation (http://www.apache.org/).
\ No newline at end of file
diff --git a/src/site/apt/download.apt b/src/site/apt/download.apt
index 7a4aa54b97..5e41d1e19c 100644
--- a/src/site/apt/download.apt
+++ b/src/site/apt/download.apt
@@ -30,9 +30,9 @@ Download Apache log4j 1.2.17
*-------------------------+---------+----------+-----------+
| | Mirrors | Checksum | Signature |
*-------------------------+---------+----------+-----------+
-| Apache log4j 1.2.17 (tar.gz) | {{{http://www.apache.org/dyn/closer.cgi/logging/log4j/1.2.17/apache-log4j-1.2.17.tar.gz} apache-log4j-1.2.17.tar.gz}} | {{{http://www.apache.org/dist/logging/log4j/1.2.17/apache-log4j-1.2.17.tar.gz.md5} apache-log4j-1.2.17.tar.gz.md5}} | {{{http://www.apache.org/dist/logging/log4j/1.2.17/apache-log4j-1.2.17.tar.gz.asc} apache-log4j-1.2.17.tar.gz.asc}} |
+| Apache log4j 1.2.17 (tar.gz) | {{{http://www.apache.org/dyn/closer.cgi/logging/log4j/1.2.17/log4j-1.2.17.tar.gz} log4j-1.2.17.tar.gz}} | {{{http://www.apache.org/dist/logging/log4j/1.2.17/log4j-1.2.17.tar.gz.md5} log4j-1.2.17.tar.gz.md5}} | {{{http://www.apache.org/dist/logging/log4j/1.2.17/log4j-1.2.17.tar.gz.asc} log4j-1.2.17.tar.gz.asc}} |
*-------------------------+---------+----------+-----------+
-| Apache log4j 1.2.17 (zip) | {{{http://www.apache.org/dyn/closer.cgi/logging/log4j/1.2.17/apache-log4j-1.2.17.zip} apache-log4j-1.2.17.zip}} | {{{http://www.apache.org/dist/logging/log4j/1.2.17/apache-log4j-1.2.17.zip.md5} apache-log4j-1.2.17.zip.md5}} | {{{http://www.apache.org/dist/logging/log4j/1.2.17/apache-log4j-1.2.17.zip.asc} apache-log4j-1.2.17.zip.asc}} |
+| Apache log4j 1.2.17 (zip) | {{{http://www.apache.org/dyn/closer.cgi/logging/log4j/1.2.17/log4j-1.2.17.zip} log4j-1.2.17.zip}} | {{{http://www.apache.org/dist/logging/log4j/1.2.17/log4j-1.2.17.zip.md5} log4j-1.2.17.zip.md5}} | {{{http://www.apache.org/dist/logging/log4j/1.2.17/log4j-1.2.17.zip.asc} log4j-1.2.17.zip.asc}} |
*-------------------------+---------+----------+-----------+
It is essential that you verify the integrity of the downloaded files using the PGP or MD5 signatures.
@@ -48,7 +48,7 @@ Download Apache log4j 1.2.17
% gpg --verify log4j-1.2.17.tar.gz.asc
---
- Apache log4j 1.2.17 is signed by Curt Arnold 70C9C3DO
+ Apache log4j 1.2.17 is signed by Christian Grobmeier 42196CA8
Alternatively, you can verify the MD5 signature on the files. A unix program called md5 or md5sum is included
in many unix distributions.
diff --git a/src/site/apt/roadmap.apt b/src/site/apt/roadmap.apt
deleted file mode 100644
index 7bb284f722..0000000000
--- a/src/site/apt/roadmap.apt
+++ /dev/null
@@ -1,22 +0,0 @@
-~~ 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.
-
-Apache log4j 1.2 Roadmap
-
- Apache log4j 1.2 is mature and widely deployed. Significant
- changes are unlikely. Bug fixes and maintenance releases are anticipated.
-
- The next major version with is {{{http://logging.apache.org/log4j/2.0/index.html}Apache log4j 2}}
-
diff --git a/src/site/default-site-macros.vm b/src/site/default-site-macros.vm
new file mode 100644
index 0000000000..20eb354e29
--- /dev/null
+++ b/src/site/default-site-macros.vm
@@ -0,0 +1,494 @@
+## 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.
+##
+#macro ( link $href $name $target $img $position $alt $border $width $height $title )
+#**##set ( $linkTitle = ' title="' + $name + '"' )
+#**##if( $target )
+#* *##set ( $linkTarget = ' target="' + $target + '"' )
+#**##else
+#* *##set ( $linkTarget = "" )
+#**##end
+#**##if ( $decoration.isLink( $href ) )
+#* *##set ( $linkClass = ' class="externalLink"' )
+#**##else
+#* *##set ( $linkClass = "" )
+#**##end
+#**##if ( $img )
+#* *##if ( $position == "left" )
+#* *##image($img $alt $border $width $height $title)$name##
+#* *##else
+#* *#$name #image($img $alt $border $width $height $title)##
+#* *##end
+#**##else
+#* *#$name##
+#**##end
+#end
+##
+#macro ( image $img $alt $border $width $height $title )
+#**##if( $img )
+#* *##if ( !$decoration.isLink( $img ) )
+#* *##set ( $imgSrc = $PathTool.calculateLink( $img, $relativePath ) )
+#* *##set ( $imgSrc = $imgSrc.replaceAll( '\\', '/' ) )
+#* *##set ( $imgSrc = ' src="' + $imgSrc + '"' )
+#* *##else
+#* *##set ( $imgSrc = ' src="' + $img + '"' )
+#* *##end
+#* *##if( $alt )
+#* *##set ( $imgAlt = ' alt="' + $alt + '"' )
+#* *##else
+#* *##set ( $imgAlt = ' alt=""' )
+#* *##end
+#* *##if( $border )
+#* *##set ( $imgBorder = ' border="' + $border + '"' )
+#* *##else
+#* *##set ( $imgBorder = "" )
+#* *##end
+#* *##if( $width )
+#* *##set ( $imgWidth = ' width="' + $width + '"' )
+#* *##else
+#* *##set ( $imgWidth = "" )
+#* *##end
+#* *##if( $height )
+#* *##set ( $imgHeight = ' height="' + $height + '"' )
+#* *##else
+#* *##set ( $imgHeight = "" )
+#* *##end
+#* *##if( $title )
+#* *##set ( $imgTitle = ' title="' + $title + '"' )
+#* *##else
+#* *##set ( $imgTitle = "" )
+#* *##end
+#* *# On August 5, 2015 the Logging Services Project
+ Management Committee announced that Log4j 1.x had reached end of life.
+ For complete text of the announcement please see the
+ Apache Blog.
+ Users of Log4j 1 are recommended to upgrade to
+ Apache Log4j 2. Create a local ssh key with no passphrase to enable
"deployment" of site back to the local machine using scp. Instructions not tested for Log4J 1.2.18. The switch to Maven 3 and git probably mean changes. Make sure to check the INSTALL file at https://github.com/apache/log4j/blob/trunk/INSTALL Before you build, please make sure you have a nonblocking editor set as SVN editor. Like: Before you build, please make sure you have a nonblocking editor set as GIT editor. Like: Other checks: The release artifacts were originally built by: Untested: the release artifacts might be buildable with: Note: you'll be ask for a SVN tagname. Please use the following pattern: v1.2.17-RC1. Note: you'll be ask for a git tagname. Please use the following pattern: v1.2.17-RC1.
Attention: this is an non-interactive build. In some cases it is necessary
@@ -140,13 +134,35 @@ to the release plugin commands. This is surely not safe because your password
can be seen clearly.
The release artifacts can be rebuilt by: Outdated: The release artifacts can be rebuilt by: Building site and artifacts from a tag: ATTENTION: if your asc files are not created, you need to create them manually. F. e. Outdated: building site and artifacts from a tag:SocketServer
is intended
- as an example to be enhanced in order to implement more elaborate
- policies.
-
-
- @author Ceki Gülcü
-
- @since 1.0 */
+ Changed in 1.2.18+ to complain about its use and do nothing else.
+ See the log4j 1.2 homepage
+ for more information on why this class is disabled since 1.2.18.
+ @author Ceki Gülcü
+ @since 1.0
+ */
public class SocketServer {
- static String GENERIC = "generic";
- static String CONFIG_FILE_EXT = ".lcf";
-
- static Logger cat = Logger.getLogger(SocketServer.class);
- static SocketServer server;
- static int port;
-
- // key=inetAddress, value=hierarchy
- Hashtable hierarchyMap;
- LoggerRepository genericHierarchy;
- File dir;
+ static final String SOCKET_SERVER_UNSUPPORTED =
+ "ERROR-LOG4J-NETWORKING-UNSUPPORTED: SocketServer unsupported!" +
+ " This is a breaking change in Log4J 1 >=1.2.18. Stop using this class!";
public
static
void main(String argv[]) {
- if(argv.length == 3)
- init(argv[0], argv[1], argv[2]);
- else
- usage("Wrong number of arguments.");
-
- try {
- cat.info("Listening on port " + port);
- ServerSocket serverSocket = new ServerSocket(port);
- while(true) {
- cat.info("Waiting to accept a new client.");
- Socket socket = serverSocket.accept();
- InetAddress inetAddress = socket.getInetAddress();
- cat.info("Connected to client at " + inetAddress);
-
- LoggerRepository h = (LoggerRepository) server.hierarchyMap.get(inetAddress);
- if(h == null) {
- h = server.configureHierarchy(inetAddress);
- }
-
- cat.info("Starting new socket node.");
- new Thread(new SocketNode(socket, h)).start();
- }
- }
- catch(Exception e) {
- e.printStackTrace();
- }
+ usage();
}
static
- void usage(String msg) {
- System.err.println(msg);
- System.err.println(
- "Usage: java " +SocketServer.class.getName() + " port configFile directory");
+ void usage() {
+ System.err.println(SOCKET_SERVER_UNSUPPORTED);
System.exit(1);
}
- static
- void init(String portStr, String configFile, String dirStr) {
- try {
- port = Integer.parseInt(portStr);
- }
- catch(java.lang.NumberFormatException e) {
- e.printStackTrace();
- usage("Could not interpret port number ["+ portStr +"].");
- }
-
- PropertyConfigurator.configure(configFile);
-
- File dir = new File(dirStr);
- if(!dir.isDirectory()) {
- usage("["+dirStr+"] is not a directory.");
- }
- server = new SocketServer(dir);
- }
-
-
+ /** @noinspection unused*/
public
SocketServer(File directory) {
- this.dir = directory;
- hierarchyMap = new Hashtable(11);
- }
-
- // This method assumes that there is no hiearchy for inetAddress
- // yet. It will configure one and return it.
- LoggerRepository configureHierarchy(InetAddress inetAddress) {
- cat.info("Locating configuration file for "+inetAddress);
- // We assume that the toSting method of InetAddress returns is in
- // the format hostname/d1.d2.d3.d4 e.g. torino/192.168.1.1
- String s = inetAddress.toString();
- int i = s.indexOf("/");
- if(i == -1) {
- cat.warn("Could not parse the inetAddress ["+inetAddress+
- "]. Using default hierarchy.");
- return genericHierarchy();
- } else {
- String key = s.substring(0, i);
-
- File configFile = new File(dir, key+CONFIG_FILE_EXT);
- if(configFile.exists()) {
- Hierarchy h = new Hierarchy(new RootLogger(Level.DEBUG));
- hierarchyMap.put(inetAddress, h);
-
- new PropertyConfigurator().doConfigure(configFile.getAbsolutePath(), h);
-
- return h;
- } else {
- cat.warn("Could not find config file ["+configFile+"].");
- return genericHierarchy();
- }
- }
- }
-
- LoggerRepository genericHierarchy() {
- if(genericHierarchy == null) {
- File f = new File(dir, GENERIC+CONFIG_FILE_EXT);
- if(f.exists()) {
- genericHierarchy = new Hierarchy(new RootLogger(Level.DEBUG));
- new PropertyConfigurator().doConfigure(f.getAbsolutePath(), genericHierarchy);
- } else {
- cat.warn("Could not find config file ["+f+
- "]. Will use the default hierarchy.");
- genericHierarchy = LogManager.getLoggerRepository();
- }
- }
- return genericHierarchy;
+ LogLog.error(SOCKET_SERVER_UNSUPPORTED);
}
}
diff --git a/src/main/java/org/apache/log4j/net/SyslogAppender.java b/src/main/java/org/apache/log4j/net/SyslogAppender.java
index 6ab7eddfd0..124ac3a388 100644
--- a/src/main/java/org/apache/log4j/net/SyslogAppender.java
+++ b/src/main/java/org/apache/log4j/net/SyslogAppender.java
@@ -17,25 +17,29 @@
package org.apache.log4j.net;
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+import java.util.regex.Pattern;
+
import org.apache.log4j.AppenderSkeleton;
import org.apache.log4j.Layout;
import org.apache.log4j.helpers.SyslogQuietWriter;
import org.apache.log4j.helpers.SyslogWriter;
import org.apache.log4j.spi.LoggingEvent;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.Locale;
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.io.IOException;
-
// Contributors: Yves Bossel
-
+ The TelnetAppender is a log4j appender that specializes in
+ writing to a read-only socket in Log4j up to 1.2.17.
+
+ Changed in 1.2.18+ to complain about its use and do nothing else.
+ See the log4j 1.2 homepage
+ for more information on why this class is disabled since 1.2.18.
@author Jay Funnell
+ @deprecated
+ @noinspection unused
*/
public class TelnetAppender extends AppenderSkeleton {
- private SocketHandler sh;
- private int port = 23;
+ static final String TELNET_APPENDER_UNSUPPORTED =
+ "ERROR-LOG4J-NETWORKING-UNSUPPORTED: TelnetAppender unsupported!" +
+ " This is a breaking change in Log4J 1 >=1.2.18. Stop using this class!";
+
+ public TelnetAppender() {
+ LogLog.error(TELNET_APPENDER_UNSUPPORTED);
+ }
- /**
- This appender requires a layout to format the text to the
- attached client(s). */
+ /**
+ In 1.2.17 this appender required a layout to format the text to the
+ attached client(s), keep the same for compatibility. */
public boolean requiresLayout() {
return true;
}
- /** all of the options have been set, create the socket handler and
- wait for connections. */
public void activateOptions() {
- try {
- sh = new SocketHandler(port);
- sh.start();
- }
- catch(InterruptedIOException e) {
- Thread.currentThread().interrupt();
- e.printStackTrace();
- } catch(IOException e) {
- e.printStackTrace();
- } catch(RuntimeException e) {
- e.printStackTrace();
- }
- super.activateOptions();
+ LogLog.error(TELNET_APPENDER_UNSUPPORTED);
}
public
int getPort() {
- return port;
+ return 0;
}
public
void setPort(int port) {
- this.port = port;
}
-
- /** shuts down the appender. */
public void close() {
- if (sh != null) {
- sh.close();
- try {
- sh.join();
- } catch(InterruptedException ex) {
- Thread.currentThread().interrupt();
- }
- }
}
- /** Handles a log event. For this appender, that means writing the
- message to each connected client. */
protected void append(LoggingEvent event) {
- if(sh != null) {
- sh.send(layout.format(event));
- if(layout.ignoresThrowable()) {
- String[] s = event.getThrowableStrRep();
- if (s != null) {
- StringBuffer buf = new StringBuffer();
- for(int i = 0; i < s.length; i++) {
- buf.append(s[i]);
- buf.append("\r\n");
- }
- sh.send(buf.toString());
- }
- }
- }
+ errorHandler.error(TELNET_APPENDER_UNSUPPORTED);
}
- //---------------------------------------------------------- SocketHandler:
-
- /** The SocketHandler class is used to accept connections from
- clients. It is threaded so that clients can connect/disconnect
- asynchronously. */
+ /** @noinspection InnerClassMayBeStatic, FinalizeNotProtected */
protected class SocketHandler extends Thread {
- private Vector writers = new Vector();
- private Vector connections = new Vector();
- private ServerSocket serverSocket;
- private int MAX_CONNECTIONS = 20;
-
public void finalize() {
close();
}
- /**
- * make sure we close all network connections when this handler is destroyed.
- * @since 1.2.15
- */
public void close() {
- synchronized(this) {
- for(Enumeration e = connections.elements();e.hasMoreElements();) {
- try {
- ((Socket)e.nextElement()).close();
- } catch(InterruptedIOException ex) {
- Thread.currentThread().interrupt();
- } catch(IOException ex) {
- } catch(RuntimeException ex) {
- }
- }
- }
-
- try {
- serverSocket.close();
- } catch(InterruptedIOException ex) {
- Thread.currentThread().interrupt();
- } catch(IOException ex) {
- } catch(RuntimeException ex) {
- }
}
- /** sends a message to each of the clients in telnet-friendly output. */
public synchronized void send(final String message) {
- Iterator ce = connections.iterator();
- for(Iterator e = writers.iterator();e.hasNext();) {
- ce.next();
- PrintWriter writer = (PrintWriter)e.next();
- writer.print(message);
- if(writer.checkError()) {
- ce.remove();
- e.remove();
- }
- }
+ errorHandler.error(TELNET_APPENDER_UNSUPPORTED);
}
- /**
- Continually accepts client connections. Client connections
- are refused when MAX_CONNECTIONS is reached.
- */
public void run() {
- while(!serverSocket.isClosed()) {
- try {
- Socket newClient = serverSocket.accept();
- PrintWriter pw = new PrintWriter(newClient.getOutputStream());
- if(connections.size() < MAX_CONNECTIONS) {
- synchronized(this) {
- connections.addElement(newClient);
- writers.addElement(pw);
- pw.print("TelnetAppender v1.0 (" + connections.size()
- + " active connections)\r\n\r\n");
- pw.flush();
- }
- } else {
- pw.print("Too many connections.\r\n");
- pw.flush();
- newClient.close();
- }
- } catch(Exception e) {
- if (e instanceof InterruptedIOException || e instanceof InterruptedException) {
- Thread.currentThread().interrupt();
- }
- if (!serverSocket.isClosed()) {
- LogLog.error("Encountered error while in SocketHandler loop.", e);
- }
- break;
- }
- }
-
- try {
- serverSocket.close();
- } catch(InterruptedIOException ex) {
- Thread.currentThread().interrupt();
- } catch(IOException ex) {
- }
+ errorHandler.error(TELNET_APPENDER_UNSUPPORTED);
}
public SocketHandler(int port) throws IOException {
- serverSocket = new ServerSocket(port);
- setName("TelnetAppender-" + getName() + "-" + port);
+ LogLog.error(TELNET_APPENDER_UNSUPPORTED);
+ throw new IOException(TELNET_APPENDER_UNSUPPORTED);
}
-
}
}
diff --git a/src/main/java/org/apache/log4j/varia/ExternallyRolledFileAppender.java b/src/main/java/org/apache/log4j/varia/ExternallyRolledFileAppender.java
index 26e7d842bc..e51353207a 100644
--- a/src/main/java/org/apache/log4j/varia/ExternallyRolledFileAppender.java
+++ b/src/main/java/org/apache/log4j/varia/ExternallyRolledFileAppender.java
@@ -17,75 +17,43 @@
package org.apache.log4j.varia;
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.io.IOException;
-import java.io.InterruptedIOException;
-import java.net.ServerSocket;
-import java.net.Socket;
-
import org.apache.log4j.RollingFileAppender;
import org.apache.log4j.helpers.LogLog;
/**
This appender listens on a socket on the port specified by the
- Port property for a "RollOver" message. When such a message
- is received, the underlying log file is rolled over and an
- acknowledgment message is sent back to the process initiating the
- roll over.
-
-
-
-
- Name
- Requirement
- Description
- Sample Value
-
- Port
- optional
- This parameter determines the port to use for announcing log events. The default port is 23 (telnet).
- 5875
- ##
+#**##end
+#end
+##
+#macro ( banner $banner $id )
+#**##if ( $banner )
+#* *##if( $banner.href )
+#* *##set ( $hrf = $banner.href )
+#* *##if ( !$decoration.isLink( $hrf ) )
+#* *##set ( $hrf = $PathTool.calculateLink( $hrf, $relativePath ) )
+#* *##set ( $hrf = $hrf.replaceAll( '\\', '/' ) )
+#* *##if ( ( $hrf == '' ) )
+#* *##set ( $hrf = './' )
+#* *##end
+#* *##end
+#* *###
+#* *##else
+#* *#
##
+#* *##else
+#* *#$banner.name
+#* *##end
+##
+#* *##if( $banner.href )
+#* *###
+#* *##else
+#* *#
+#* *##foreach( $subitem in $item.items )
+#* *##menuItem( $subitem "$indent " )
+#* *##end
+$indent
##
+#* *##end
+#**##end
+#**#" )
+##
+#* *##if ( $position == "left" )
+
$img $menu.name
+#* *##else
+ $menu.name $img
+#* *##end
+#* *##else
+ $menu.name
+#* *##end
+#* *##end
+#* *##if ( $menu.items && $menu.items.size() > 0 )
+
+#* *##foreach( $item in $menu.items )
+#* *##menuItem( $item '' )
+#* *##end
+
+#* *##end
+#**##end
+#end
+##
+#macro ( copyright )
+#**##if ( $project )
+#* *##if ( ${project.organization} && ${project.organization.name} )
+#* *##set ( $period = "" )
+#* *##else
+#* *##set ( $period = "." )
+#* *##end
+##
+#* *##set ( $currentYear = ${currentDate.year} + 1900 )
+##
+#* *##if ( ${project.inceptionYear} && ( ${project.inceptionYear} != ${currentYear.toString()} ) )
+ ${project.inceptionYear}–${currentYear}${period}##
+#* *##else
+ ${currentYear}${period}##
+#* *##end
+##
+#* *##if ( ${project.organization} )
+#* *##if ( ${project.organization.name} && ${project.organization.url} )
+#* *#${project.organization.name}.
+#* *##elseif ( ${project.organization.name} )
+#* *#${project.organization.name}.
+#* *##end
+#* *##end
+#**##end
+#end
+##
+#macro ( publishDate $position $decorationPublishDate $version )
+#**##if ( $publishDate )
+#* *##set ( $dateValue = $dateFormat.format( $publishDate ) )
+#**##elseif ( $decoration.custom.getChild( 'publishDate' ) )
+#* *##set ( $dateValue = $decoration.custom.getChild( 'publishDate' ).getValue() )
+#**##else
+#* *##set ( $dateValue = $dateFormat.format( $currentDate ) )
+#**##end
+##
+#**##set ( $datePosition = $decorationPublishDate.position )
+#**##set ( $versionPosition = $version.position )
+##
+#**##set ( $breadcrumbs = $decoration.body.breadcrumbs )
+#**##set ( $links = $decoration.body.links )
+##
+#**##if ( $datePosition.equalsIgnoreCase( "right" ) && $links && $links.size() > 0 )
+#* *##set ( $prefix = " |" )
+#**##else
+#* *##set ( $prefix = "" )
+#**##end
+##
+#**##if ( $datePosition.equalsIgnoreCase( $position ) )
+#* *##if ( ( $datePosition.equalsIgnoreCase( "right" ) ) || ( $datePosition.equalsIgnoreCase( "bottom" ) ) )
+ $prefix $i18n.getString( "site-renderer", $locale, "template.lastpublished" ): $dateValue
+#* *##if ( $versionPosition.equalsIgnoreCase( $position ) )
+ | $i18n.getString( "site-renderer", $locale, "template.version" ): ${project.version}
+#* *##end
+#* *##elseif ( ( $datePosition.equalsIgnoreCase( "navigation-bottom" ) ) || ( $datePosition.equalsIgnoreCase( "navigation-top" ) ) )
+
+
+#* *##end
+#* *##if( $poweredBy.isEmpty() )
+
+
+
+#* *##end
+#**##else
+
+
+
+#**##end
+#end
+##
+#macro ( googleAnalytics $accountId )
+#**##if( $accountId && $accountId != "" )
+
+
+#**##end
+#end
+##
+#macro( generatedBy )
+Apache Maven Doxia Site Renderer#if( $doxiaSiteRendererVersion ) $doxiaSiteRendererVersion#end##
+#end
+##
\ No newline at end of file
diff --git a/src/site/maven-site.vm b/src/site/maven-site.vm
deleted file mode 100644
index 45de1aced7..0000000000
--- a/src/site/maven-site.vm
+++ /dev/null
@@ -1,522 +0,0 @@
-
-
-
-#macro ( link $href $name $target $img $position $alt $border $width $height )
- #set ( $linkTitle = ' title="' + $name + '"' )
- #if( $target )
- #set ( $linkTarget = ' target="' + $target + '"' )
- #else
- #set ( $linkTarget = "" )
- #end
- #if ( ( $href.toLowerCase().startsWith("http") || $href.toLowerCase().startsWith("https") ) )
- #set ( $linkClass = ' class="externalLink"' )
- #else
- #set ( $linkClass = "" )
- #end
- #if ( $img )
- #if ( $position == "left" )
- #image($img $alt $border $width $height)$name
- #else
- $name #image($img $alt $border $width $height)
- #end
- #else
- $name
- #end
-#end
-##
-#macro ( image $img $alt $border $width $height )
- #if( $img )
- #if ( ! ( $img.toLowerCase().startsWith("http") || $img.toLowerCase().startsWith("https") ) )
- #set ( $imgSrc = $PathTool.calculateLink( $img, $relativePath ) )
- #set ( $imgSrc = $imgSrc.replaceAll( '\\', '/' ) )
- #set ( $imgSrc = ' src="' + $imgSrc + '"' )
- #else
- #set ( $imgSrc = ' src="' + $img + '"' )
- #end
- #if( $alt )
- #set ( $imgAlt = ' alt="' + $alt + '"' )
- #else
- #set ( $imgAlt = ' alt=""' )
- #end
- #if( $border )
- #set ( $imgBorder = ' border="' + $border + '"' )
- #else
- #set ( $imgBorder = "" )
- #end
- #if( $width )
- #set ( $imgWidth = ' width="' + $width + '"' )
- #else
- #set ( $imgWidth = "" )
- #end
- #if( $height )
- #set ( $imgHeight = ' height="' + $height + '"' )
- #else
- #set ( $imgHeight = "" )
- #end
-
- #end
-#end
-#macro ( banner $banner $id )
- #if ( $banner )
- #if( $banner.href )
-
- #else
-
- #else
- $banner.name
- #end
-##
- #if( $banner.href )
-
- #else
-
- #foreach( $subitem in $item.items )
- #menuItem( $subitem )
- #end
-
- #end
- #end
- " )
-##
- #if ( $position == "left" )
-
$img $menu.name
- #else
- $menu.name $img
- #end
- #else
- $menu.name
- #end
- #end
- #if ( $menu.items && $menu.items.size() > 0 )
-
- #foreach( $item in $menu.items )
- #menuItem( $item )
- #end
-
- #end
- #end
-#end
-##
-#macro ( copyright )
- #if ( $project )
- #if ( ${project.organization} && ${project.organization.name} )
- #set ( $period = "" )
- #else
- #set ( $period = "." )
- #end
-##
- #set ( $currentYear = ${currentDate.year} + 1900 )
-##
- #if ( ${project.inceptionYear} && ( ${project.inceptionYear} != ${currentYear.toString()} ) )
- ${project.inceptionYear}-${currentYear}${period}
- #else
- ${currentYear}${period}
- #end
-##
- #if ( ${project.organization} )
- #if ( ${project.organization.name} && ${project.organization.url} )
- ${project.organization.name}.
- #elseif ( ${project.organization.name} )
- ${project.organization.name}.
- #end
- #end
- #end
-#end
-##
-#macro ( publishDate $position $publishDate $version )
- #if ( $publishDate && $publishDate.format )
- #set ( $format = $publishDate.format )
- #else
- #set ( $format = "yyyy-MM-dd" )
- #end
-##
- $dateFormat.applyPattern( $format )
-##
- #set ( $dateToday = $dateFormat.format( $currentDate ) )
-##
- #if ( $publishDate && $publishDate.position )
- #set ( $datePosition = $publishDate.position )
- #else
- #set ( $datePosition = "left" )
- #end
-##
- #if ( $version )
- #if ( $version.position )
- #set ( $versionPosition = $version.position )
- #else
- #set ( $versionPosition = "left" )
- #end
- #else
- #set ( $version = "" )
- #set ( $versionPosition = "left" )
- #end
-##
- #set ( $breadcrumbs = $decoration.body.breadcrumbs )
- #set ( $links = $decoration.body.links )
-
- #if ( $datePosition.equalsIgnoreCase( "right" ) && $links && $links.size() > 0 )
- #set ( $prefix = " |" )
- #else
- #set ( $prefix = "" )
- #end
-##
- #if ( $datePosition.equalsIgnoreCase( $position ) )
- #if ( ( $datePosition.equalsIgnoreCase( "right" ) ) || ( $datePosition.equalsIgnoreCase( "bottom" ) ) )
- $prefix $i18n.getString( "site-renderer", $locale, "template.lastpublished" ): $dateToday
- #if ( $versionPosition.equalsIgnoreCase( $position ) )
- | $i18n.getString( "site-renderer", $locale, "template.version" ): ${project.version}
- #end
- #elseif ( ( $datePosition.equalsIgnoreCase( "navigation-bottom" ) ) || ( $datePosition.equalsIgnoreCase( "navigation-top" ) ) )
-
-
- #end
- #if( $poweredBy.isEmpty() )
-
-
-
- #end
- #else
-
-
-
- #end
-#end
-##
-
-
-
-
- End of Life
+ Install Maven 2, Subversion, mingw and xemacs21, openssh-server:
+Install Maven 3, Subversion, mingw and xemacs21, openssh-server:
-$> sudo apt-get install maven2 subversion mingw32 xemacs21 openssh-server
+$> sudo apt-get install maven3 git mingw32 xemacs21 openssh-server
-Copy Win32 version of jni_md.h for NTEventLogAppender.dll
-
-
-c:\>cd "\Program Files\Java\jdk_1.6.0_16\include\win32
-c:\>scp jni_md.h username@hostname:
-
-$> export JNI_WIN32_INCLUDE_DIR=/home/username
-
-
-Signing & Deploying
+Outdated: signing & Deploying
Building release artifacts
+Untested: Building release artifacts
+
+
-$ export SVN_EDITOR=xemacs
+$ export GIT_EDITOR=xemacs
-$> svn co http://svn.apache.org/repos/asf/logging/log4j/trunk log4j
+$> git clone git@github.com:apache/log4j.git
$> cd log4j
$> mvn package release:prepare
$> mvn release:perform
-
$ mvn release:perform -DconnectionUrl=scm:svn:https://svn.apache.org/repos/asf/logging/log4j/tags/v1_2_16
-
+ #!/bin/sh
+
+ if [ -n "$1" ]
+ then
+ root_dir=$1
+ else
+ root_dir=.
+ fi
+
+ for file in $root_dir/*.jar $root_dir/*.pom $root_dir/*.zip $root_dir/*.tar.gz; do
+ echo §file
+ gpg --armor --output $file.asc --detach-sig $file
+ echo "GPG verification output"
+ gpg --verify $file.asc $file
+ echo "~~~~~~~~~~~~~~~~~~~~~~~"
+ done
+
+
+
+
$ svn co https://svn.apache.org/repos/asf/logging/log4j/tags/v1_2_16
@@ -173,7 +189,7 @@ The staged version can be published to the main public site by executing
"svn update" in /www/logging.apache.org/log4j/1.2 on people.apache.org.
http://people.apache.org/builds/logging/repo/log4j/log4j/
If a RC has passed the vote, these steps are necessary:
@@ -190,8 +206,12 @@ The staged version can be published to the main public site by executing $> svn mv https://svn.apache.org/repos/asf/logging/log4j/tags/log4j-1.2.17-RC1 https://svn.apache.org/repos/asf/logging/log4j/tags/log4j-1.2.17 -Change the pom.xml version to the prior version number.
+mv the tar.gz and the zip files to p.a.o dist
+Create a jar file containing your artifacts: jar cf log4j-bundle-1217.jar *
+Upload the bundle to repository.apache.org and follow the instructions to get the artifacts from staging to proper
+ +Send an announcement to: announce@apache.org, general@logging.apache.org, log4j-dev@logging.apache.org, log4j-user@logging.apache.org