Author: sdeboy
Date: Wed Mar 17 07:16:06 2010
New Revision: 924176
URL: http://svn.apache.org/viewvc?rev=924176&view=rev
Log:
Added ZeroConf support to most of the network-based appenders and receivers.
To enable ZeroConf advertising of an appender or receiver, a user can now:
- add jmdns jar to their classpath
- set the 'advertiseViaMulticastDNS' param to 'true'
Also added support for discovery of appenders in Chainsaw (Chainsaw will
automatically configure a matching receiver when connected).
Supported appenders:
SocketAppender
SocketHubAppender (ZeroConfSocketHubAppender is still functional)
UDPAppender
MulticastAppender
Supported receivers:
SocketReceiver
SocketHubReceiver (also receives events from ZeroConfSocketHubAppender)
XMLSocketReceiver (can receive events sent over TCP by other logging
frameworks)
UDPReceiver
MulticastReceiver
Implementation details:
- removed Zeroconf4log4j class, jmdns access is now through the
ZeroConfSupport class (class provides support of JmDNS and ServiceInfo creation
via reflection, and supports both jmdns 1.0 and jmdns 3.1 apis)
- ZeroConfSupport class is now used by ZeroConfSocketHubAppender, Chainsaw and
all appenders & receivers that can advertise their configuration via ZeroConf
- added new 'advertiseViaMulticastDNS' param to the appenders and receivers
that support ZeroConf
- updated the ZeroConf site documentation
- updated release notes
- updated the ZeroConfPlugin html file
- tested appenders with 1.0 and 3.1 jmdns jars
- updated log4j references in poms to log4j 1.2.16-snapshot where necessary
For those wanting to add ZeroConf support to third-party appenders and have
Chainsaw discover the appenders, the service info naming convention is
described here: https://issues.apache.org/bugzilla/show_bug.cgi?id=48907
Modified:
logging/chainsaw/trunk/pom.xml
logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/zeroconf/ZeroConfPlugin.java
logging/chainsaw/trunk/src/main/resources/org/apache/log4j/chainsaw/help/release-notes.html
logging/chainsaw/trunk/src/main/resources/org/apache/log4j/chainsaw/zeroconf/ZeroConfPlugin.html
logging/chainsaw/trunk/src/site/apt/zeroconf.apt
Modified: logging/chainsaw/trunk/pom.xml
URL:
http://svn.apache.org/viewvc/logging/chainsaw/trunk/pom.xml?rev=924176&r1=924175&r2=924176&view=diff
==============================================================================
--- logging/chainsaw/trunk/pom.xml (original)
+++ logging/chainsaw/trunk/pom.xml Wed Mar 17 07:16:06 2010
@@ -349,7 +349,7 @@
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
- <version>1.2.16</version>
+ <version>1.2.16-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>xstream</groupId>
Modified:
logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/zeroconf/ZeroConfPlugin.java
URL:
http://svn.apache.org/viewvc/logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/zeroconf/ZeroConfPlugin.java?rev=924176&r1=924175&r2=924176&view=diff
==============================================================================
---
logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/zeroconf/ZeroConfPlugin.java
(original)
+++
logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/zeroconf/ZeroConfPlugin.java
Wed Mar 17 07:16:06 2010
@@ -10,8 +10,10 @@ import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
+import java.util.Set;
import javax.jmdns.JmDNS;
import javax.jmdns.ServiceEvent;
@@ -41,12 +43,17 @@ import org.apache.log4j.chainsaw.help.He
import org.apache.log4j.chainsaw.icons.ChainsawIcons;
import org.apache.log4j.chainsaw.plugins.GUIPluginSkeleton;
import org.apache.log4j.chainsaw.prefs.SettingsManager;
+import org.apache.log4j.helpers.LogLog;
+import org.apache.log4j.net.MulticastReceiver;
import org.apache.log4j.net.SocketHubReceiver;
-import org.apache.log4j.net.ZeroConfSocketHubAppender;
-import org.apache.log4j.net.Zeroconf4log4j;
+import org.apache.log4j.net.SocketReceiver;
+import org.apache.log4j.net.UDPReceiver;
+import org.apache.log4j.net.XMLSocketReceiver;
+import org.apache.log4j.net.ZeroConfSupport;
import org.apache.log4j.plugins.Plugin;
import org.apache.log4j.plugins.PluginEvent;
import org.apache.log4j.plugins.PluginListener;
+import org.apache.log4j.plugins.Receiver;
import org.apache.log4j.spi.LoggerRepositoryEx;
import com.thoughtworks.xstream.XStream;
@@ -62,9 +69,6 @@ import com.thoughtworks.xstream.io.xml.D
* TODO add the
* default Zone, and the list of user-specified zones to a preferenceModel
*
- * To run this in trial mode, first run {...@link
ZeroConfSocketHubAppenderTestBed}, then
- * run this class' main(..) method.
- *
* @author psmith
*
*/
@@ -80,8 +84,6 @@ public class ZeroConfPlugin extends GUIP
private final JScrollPane scrollPane = new JScrollPane(deviceTable);
- private JmDNS jmDNS;
-
private ZeroConfPreferenceModel preferenceModel;
private Map serviceInfoToReceiveMap = new HashMap();
@@ -97,13 +99,19 @@ public class ZeroConfPlugin extends GUIP
});
private JMenuItem nothingToConnectTo = new JMenuItem("No devices
discovered");
-
+ private static final String MULTICAST_APPENDER_SERVICE_NAME =
"_log4j_xml_mcast_appender.local.";
+ private static final String UDP_APPENDER_SERVICE_NAME =
"_log4j_xml_udp_appender.local.";
+ private static final String XML_SOCKET_APPENDER_SERVICE_NAME =
"_log4j_xml_tcpconnect_appender.local.";
+ private static final String SOCKET_APPENDER_SERVICE_NAME =
"_log4j_obj_tcpconnect_appender.local.";
+ private static final String SOCKETHUB_APPENDER_SERVICE_NAME =
"_log4j_obj_tcpaccept_appender.local.";
+ private JmDNS jmDNS;
+
public ZeroConfPlugin() {
setName("Zeroconf");
}
public void shutdown() {
- Zeroconf4log4j.shutdown();
+ jmDNS.close();
save();
}
@@ -123,14 +131,10 @@ public class ZeroConfPlugin extends GUIP
public void activateOptions() {
setLayout(new BorderLayout());
- jmDNS = Zeroconf4log4j.getInstance();
+ jmDNS = (JmDNS) ZeroConfSupport.getJMDNSInstance();
- jmDNS.addServiceListener(
- ZeroConfSocketHubAppender.DEFAULT_ZEROCONF_ZONE,
- new ZeroConfServiceListener());
+ registerServiceListenersForAppenders();
-
jmDNS.addServiceListener(ZeroConfSocketHubAppender.DEFAULT_ZEROCONF_ZONE,
discoveredDevices);
-
deviceTable.addMouseListener(new ConnectorMouseListener());
@@ -179,7 +183,28 @@ public class ZeroConfPlugin extends GUIP
discoveredDevices.setZeroConfPreferenceModel(preferenceModel);
discoveredDevices.setZeroConfPluginParent(this);
}
-
+
+ private void registerServiceListenersForAppenders()
+ {
+ Set serviceNames = new HashSet();
+ serviceNames.add(MULTICAST_APPENDER_SERVICE_NAME);
+ serviceNames.add(SOCKET_APPENDER_SERVICE_NAME);
+ serviceNames.add(SOCKETHUB_APPENDER_SERVICE_NAME);
+ serviceNames.add(UDP_APPENDER_SERVICE_NAME);
+ serviceNames.add(XML_SOCKET_APPENDER_SERVICE_NAME);
+
+ for (Iterator iter = serviceNames.iterator(); iter.hasNext();) {
+ String serviceName = iter.next().toString();
+ jmDNS.addServiceListener(
+ serviceName,
+ new ZeroConfServiceListener());
+
+ jmDNS.addServiceListener(serviceName, discoveredDevices);
+ }
+
+ //now add each appender constant
+ }
+
/**
* Sets the icon of this parent container (a JTabbedPane, we hope
*
@@ -286,7 +311,7 @@ public class ZeroConfPlugin extends GUIP
connectToMenu.insert(connectToDeviceMenuItem,0);
}
// if the device name is one of the autoconnect devices, then connect
immediately
- if (preferenceModel.getAutoConnectDevices().contains(name)) {
+ if (preferenceModel != null && preferenceModel.getAutoConnectDevices()
!= null && preferenceModel.getAutoConnectDevices().contains(name)) {
new Thread(new Runnable() {
public void run() {
@@ -432,15 +457,12 @@ public class ZeroConfPlugin extends GUIP
*/
private void connectTo(ServiceInfo info) {
LOG.info("Connection request for " + info);
- int port = info.getPort();
- String hostAddress = info.getHostAddress();
-
-// TODO handle different receivers than just SocketHubReceiver
- SocketHubReceiver receiver = new SocketHubReceiver();
- receiver.setHost(hostAddress);
- receiver.setPort(port);
- receiver.setName(info.getName());
-
+ //Chainsaw can construct receivers from discovered appenders
+ Receiver receiver = getReceiver(info);
+ //if null, unable to resolve the service name..no-op
+ if (receiver == null) {
+ return;
+ }
((LoggerRepositoryEx)LogManager.getLoggerRepository()).getPluginRegistry().addPlugin(receiver);
receiver.activateOptions();
LOG.info("Receiver '" + receiver.getName() + "' has been started");
@@ -460,6 +482,69 @@ public class ZeroConfPlugin extends GUIP
// discoveredDevices.fireContentsChanged();
}
+ private Receiver getReceiver(ServiceInfo info) {
+ String zone = info.getType();
+ int port = info.getPort();
+ String hostAddress = info.getHostAddress();
+ String name = info.getName();
+ String decoderClass = info.getPropertyString("decoder");
+
+ //MulticastAppender
+ if (MULTICAST_APPENDER_SERVICE_NAME.equals(zone)) {
+ MulticastReceiver receiver = new MulticastReceiver();
+ //this needs to be a multicast address, not the host address, so
we need to use a property
+ receiver.setAddress(info.getPropertyString("multicastAddress"));
+ receiver.setPort(port);
+ receiver.setName(name + "-receiver");
+ if (decoderClass != null && !decoderClass.equals("")) {
+ receiver.setDecoder(decoderClass);
+ }
+
+ return receiver;
+ }
+ //UDPAppender
+ if (UDP_APPENDER_SERVICE_NAME.equals(zone)) {
+ UDPReceiver receiver = new UDPReceiver();
+ receiver.setPort(port);
+ receiver.setName(name + "-receiver");
+ if (decoderClass != null && !decoderClass.equals("")) {
+ receiver.setDecoder(decoderClass);
+ }
+ return receiver;
+ }
+
+ //non-log4j XML-based socketappender
+ if (XML_SOCKET_APPENDER_SERVICE_NAME.equals(zone)) {
+ XMLSocketReceiver receiver = new XMLSocketReceiver();
+ receiver.setPort(port);
+ receiver.setName(name + "-receiver");
+ if (decoderClass != null && !decoderClass.equals("")) {
+ receiver.setDecoder(decoderClass);
+ }
+ return receiver;
+ }
+
+ //SocketAppender
+ if (SOCKET_APPENDER_SERVICE_NAME.equals(zone)) {
+ SocketReceiver receiver = new SocketReceiver();
+ receiver.setPort(port);
+ receiver.setName(name + "-receiver");
+ return receiver;
+ }
+
+ //SocketHubAppender
+ if (SOCKETHUB_APPENDER_SERVICE_NAME.equals(zone)) {
+ SocketHubReceiver receiver = new SocketHubReceiver();
+ receiver.setHost(hostAddress);
+ receiver.setPort(port);
+ receiver.setName(name + "-receiver");
+ return receiver;
+ }
+ //not recognized
+ LogLog.debug("Unable to find receiver for appender with service name:
" + zone);
+ return null;
+ }
+
/**
* Finds the matching JMenuItem based on name, may return null if there is
no match.
*
Modified:
logging/chainsaw/trunk/src/main/resources/org/apache/log4j/chainsaw/help/release-notes.html
URL:
http://svn.apache.org/viewvc/logging/chainsaw/trunk/src/main/resources/org/apache/log4j/chainsaw/help/release-notes.html?rev=924176&r1=924175&r2=924176&view=diff
==============================================================================
---
logging/chainsaw/trunk/src/main/resources/org/apache/log4j/chainsaw/help/release-notes.html
(original)
+++
logging/chainsaw/trunk/src/main/resources/org/apache/log4j/chainsaw/help/release-notes.html
Wed Mar 17 07:16:06 2010
@@ -10,6 +10,23 @@
<b>NOTE:</b> The mechanism and format used to persist settings in Chainsaw is
subject to change. If you are experiencing problems displaying events in
Chainsaw, please delete everything in the $user.dir/.chainsaw directory and
restart Chainsaw.
<br>
<h1>1.99.99</h1>
+<h2>16 Mar 2010</h2>
+<ul>
+<li>
+Added ZeroConf support to most of the network-based appenders and receivers -
just add the jmdns jar to your classpath and set the 'advertiseViaMulticastDNS'
param to 'true'. Also added
+support for discovery of these appenders in Chainsaw (once you 'connect' to an
advertised appender, Chainsaw will automatically configure a matching
receiver).<br>
+Supported appenders:
+ <ul>SocketAppender</ul>
+ <ul>SocketHubAppender (ZeroConfSocketHubAppender is still functional)</ul>
+ <ul>UDPAppender</ul>
+ <ul>MulticastAppender</ul>
+Supported receivers:
+ <ul>SocketReceiver</ul>
+ <ul>SocketHubReceiver (also receives events from
ZeroConfSocketHubAppender)</ul>
+ <ul>XMLSocketReceiver (can receive events sent over TCP by other logging
frameworks)</ul>
+ <ul>UDPReceiver</ul>
+ <ul>MulticastReceiver</ul>
+</ul>
<h2>14 Mar 2010</h2>
<ul>
<li>
Modified:
logging/chainsaw/trunk/src/main/resources/org/apache/log4j/chainsaw/zeroconf/ZeroConfPlugin.html
URL:
http://svn.apache.org/viewvc/logging/chainsaw/trunk/src/main/resources/org/apache/log4j/chainsaw/zeroconf/ZeroConfPlugin.html?rev=924176&r1=924175&r2=924176&view=diff
==============================================================================
---
logging/chainsaw/trunk/src/main/resources/org/apache/log4j/chainsaw/zeroconf/ZeroConfPlugin.html
(original)
+++
logging/chainsaw/trunk/src/main/resources/org/apache/log4j/chainsaw/zeroconf/ZeroConfPlugin.html
Wed Mar 17 07:16:06 2010
@@ -20,7 +20,7 @@ devices on your local network such as pr
Zeroconf is an open-standard that many vendors are using to reduce cost of
configuration. The <b>JmDNS</b> project
is an Apache 2.0 licensed library that implements the ZeroConf protocol.
Chainsaw and log4j use
JmDNS to broadcast Appender information so that a matching Receiver can be
easily created to connect to each other
-to stream logging messages into Chainsaw.
+to stream logging messages into Chainsaw.
</p>
<p>
<ul>
@@ -30,19 +30,16 @@ to stream logging messages into Chainsaw
</p>
<h2>Interesting... So what do I need to use ZeroConf with Chainsaw &
log4j?</h2>
<p>
-The log4j team has created an additional JAR file that can be added to your
existing
-application to enable ZeroConf configuration. You just need to download the
<code>log4j-zeroconf.jar</code> and the JmDNS package (you must use
-at least version 1.0 of JmDNS) and add
-both JARs to your application's classpath. </p>
-<p> Then change your references from <code>SocketHubAppender</code>
-to <code><b>ZeroConf</b>SocketHubAppender</code>. (We recommend you change the
'name' propety from it's default to make it easy for you to use, other
-wise it's name will appear as the default 'SocketHubAppender').
-</p>
+Most of the network-based appenders are ZeroConf-capable - all you have to do
to use ZeroConf is to
+download the JmDNS package (at least version 1.0), add the JmDNS jar to your
application's classpath, and set the "advertiseViaMulticastDNS"
+parameter to 'true' for any of the appenders or receivers you want to
advertise (most of the time you will want to advertise appenders, so they can be
+automatically detected by Chainsaw).</p>
<p>You're log4j.xml configuration file could be as simple as this:</p>
<pre>
<log4j:configuration debug="false" threshold="debug"
xmlns:log4j="http://jakarta.apache.org/log4j/>
- <appender name="zeroconf"
class="org.apache.log4j.net.ZeroConfSocketHubAppender">
+ <appender name="zeroconf"
class="org.apache.log4j.net.SocketHubAppender">
<param name="Name" value="MyZeroConfSockeHubAppender" />
+ <param name="advertiseViaMulticastDNS" value="true" />
</appender>
<!--ROOT Logger-->
<root>
@@ -52,12 +49,16 @@ wise it's name will appear as the defaul
</log4j:configuration>
</pre>
<p>
-Once you have started your application using this new appender, then from
within Chainsaw, the ZeroConf tab will show detected
-applications. You can simply double click on the detected app, and Chainsaw
will connect a Receiver to it. You can even tick the "Auto-Connect"
+Once you have started your application using this configuration, from within
Chainsaw, the ZeroConf tab will show detected
+applications. You can simply double click on the detected appender and
Chainsaw will connect a Receiver to it. You can even tick the "Auto-Connect"
check box, and next time Chainsaw see's this application, it will
automatically connect to it.
</p>
+<p>Most of the network-based Receivers are also ZeroConf capable, giving
ZeroConf-aware appenders or applications
+the ability to discover the receivers and configure appenders to connect to
those Receivers.
+</p>
<h2>Cool... But I have some applications that use log4j 1.2.x. Will it still
work?</h2>
-<p>Yes. We have designed a backward compatible mechanism to expose log4j
1.2.x SocketHubAppender so that Chainsaw can detect it automatically.
+<p>Yes. We have designed a backward compatible mechanism to expose prior
versions of log4j's SocketHubAppender (ZeroConfSocketHubAppender)
+so that Chainsaw can detect it automatically.
</p>
<h2>But... Surely there's a catch?</h2>
Modified: logging/chainsaw/trunk/src/site/apt/zeroconf.apt
URL:
http://svn.apache.org/viewvc/logging/chainsaw/trunk/src/site/apt/zeroconf.apt?rev=924176&r1=924175&r2=924176&view=diff
==============================================================================
--- logging/chainsaw/trunk/src/site/apt/zeroconf.apt (original)
+++ logging/chainsaw/trunk/src/site/apt/zeroconf.apt Wed Mar 17 07:16:06 2010
@@ -14,21 +14,45 @@
~~ limitations under the License.
ZeroConf - Zero Configuration
- Chainsaw has ZeroConf elements embedded within it, but you'll need to
add a few things to your application to enable your application for ZeroConf.
+ Chainsaw can use ZeroConf to discover advertised appenders and
automatically configure a matching receiver, but you must update your
configuration in order to advertise your appender via ZeroConf.
+
+ If you are using a newer version of log4j (1.2.16 or greater), most of the
network-based appenders are capable of advertising their configurations via
ZeroConf, but have this
+capability disabled by default.
+ To advertise an appender via ZeroConf:
+ [[1]] Download {{{http://sourceforge.net/projects/jmdns/}JmDNS}}
- Download:
-
- [[1]]
{{{http://logging.apache.org/log4j/docs/webstart/chainsaw/log4j-zeroconf.zip}log4j
ZeroConf extension}}
-
- [[2]] {{{http://sourceforge.net/projects/jmdns/}JmDNS}}
-
- [[3]] Add the <log4j-zeroconf.jar> and the <jmdns.jar> from
these bundles and add them to your application's classpath.
-
- [[4]] Modify your log4j configuration so that it use the
ZeroConfSocketHubAppender.
-
- Here is a complete log4j.xml file that you can use as a base:
-
-+-------------------------------+
+ [[2]] Add the <jmdns.jar> to your application's classpath
+
+ [[3]] Modify your log4j configuration so that the appender is set to
advertise its configuration via ZeroConf (by setting the
'advertiseViaMulticastDNS' parameter to 'true')
+
+ Here is a complete log4j.xml file that you can use as a base
SocketAppender configuration which advertises the appender via ZeroConf:</p>
+
++-------------------------------+
+<log4j:configuration debug="false" threshold="debug"
xmlns:log4j="http://jakarta.apache.org/log4j/">
+ <appender name="socketAppender"
class="org.apache.log4j.net.SocketAppender">
+ <param name="Name" value="MySockeAppender" />
+ <param name="advertiseViaMulticastDNS" value="true" />
+ </appender>
+ <!--ROOT Logger-->
+ <root>
+ <level value="INFO" />
+ <appender-ref ref="socketAppender" />
+ </root>
+</log4j:configuration>
++-------------------------------+
+
+ If you are using an older version of log4j (prior to 1.2.16),
ZeroConfSocketHubAppender is a ZeroConf-capable appender which is backward
compatible with the prior versions of SocketHubAppender and can advertise the
appender configuration via ZeroConf:</p>
+ [[1]] Download {{{http://sourceforge.net/projects/jmdns/}JmDNS}}
+
+ [[2]] Add the <i>jmdns.jar</i> to your application's classpath
+
+ [[3]] Download
{{{http://logging.apache.org/log4j/docs/webstart/chainsaw/log4j-zeroconf.zip}log4j
ZeroConf extension (provides ZeroConfSocketHubAppender)}}
+
+ [[4]] Add the <log4j-zeroconf.jar> to your application's classpath
+
+ Here is a complete log4j.xml file that you can use as a base
ZeroConfSocketAppender configuration which advertises the appender via
ZeroConf:</p>
+
++-------------------------------+
<log4j:configuration debug="false" threshold="debug"
xmlns:log4j="http://jakarta.apache.org/log4j/">
<appender name="zeroconf"
class="org.apache.log4j.net.ZeroConfSocketHubAppender">
<param name="Name" value="MyZeroConfSockeHubAppender" />
@@ -41,12 +65,8 @@ ZeroConf - Zero Configuration
</log4j:configuration>
+-------------------------------+
- Once configured and your applicatiion started, you should be able to
click on the Zeroconf tab inside Chainsaw, and see the
"MyZeroConfSocketHubAppender" listed. If you double click on the row, Chainsaw
will automatically connect to your application and start receiving events. You
can tick the 'auto-connect' option to have Chainsaw immediately connect as soon
as it sees your application started. Great for Dev/QA environment.
-
- The Zeroconf-enabled SocketHubAppender broadcasts it's existence via a
multicast protocol, passing enough information for Chainsaw to be able to
connect to it.
-
-Firewalls
+ Once you have enabled ZeroConf in your log4j configuration and started
your application, you should be able to click on the Zeroconf tab inside
Chainsaw and see the advertised appenders listed. If you double click on a row,
+Chainsaw will automatically connect to your application and start receiving
events. You can tick the 'auto-connect' option to have Chainsaw immediately
connect as soon as it sees your application started. Great for Dev/QA
environment.</p>
- Multicast protocols generally don't pass through firewall, so in a
production environment Zeroconf won't work.
-
-
\ No newline at end of file
+Firewalls
+ Multicast protocols generally don't pass through firewall, so in a
production environment Zeroconf won't work.</p>