Have most receivers converted to be new style. Most are untested
diff --git a/src/main/java/org/apache/log4j/chainsaw/ChainsawReceiver.java b/src/main/java/org/apache/log4j/chainsaw/ChainsawReceiver.java
index c93521e..2080359 100644
--- a/src/main/java/org/apache/log4j/chainsaw/ChainsawReceiver.java
+++ b/src/main/java/org/apache/log4j/chainsaw/ChainsawReceiver.java
@@ -20,7 +20,8 @@
import org.apache.log4j.chainsaw.logevents.Level;
/**
- * A receiver receives log events from a source.
+ * A receiver receives log events from a source. A ChainsawReceiver will create
+ * from 1...N ChainsawReceiverNodes
*/
public interface ChainsawReceiver {
diff --git a/src/main/java/org/apache/log4j/chainsaw/ChainsawReceiverNode.java b/src/main/java/org/apache/log4j/chainsaw/ChainsawReceiverNode.java
new file mode 100644
index 0000000..ea1d748
--- /dev/null
+++ b/src/main/java/org/apache/log4j/chainsaw/ChainsawReceiverNode.java
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.log4j.chainsaw;
+
+/**
+ * Each ChainsawReceiver may have multiple Nodes associated with it. For example,
+ * if a ChainsawReceiver listens on a port for incoming connections, each
+ * incoming connection will create a new ChainsawReceiverNode that will read and
+ * parse messages.
+ *
+ * Other receivers may not need to create sub-nodes.
+ */
+public interface ChainsawReceiverNode {
+
+}
diff --git a/src/main/java/org/apache/log4j/chainsaw/LogUI.java b/src/main/java/org/apache/log4j/chainsaw/LogUI.java
index 22ef132..fb706c1 100644
--- a/src/main/java/org/apache/log4j/chainsaw/LogUI.java
+++ b/src/main/java/org/apache/log4j/chainsaw/LogUI.java
@@ -1274,8 +1274,8 @@
fileReceiver.setTailing(true);
fileReceiver.setLogFormat(receiverPattern);
fileReceiver.setTimestampFormat(timestampFormat);
- fileReceiver.setThreshold(Level.TRACE);
- pluginRegistry.addPlugin(fileReceiver);
+// fileReceiver.setThreshold(Level.TRACE);
+// pluginRegistry.addPlugin(fileReceiver);
fileReceiver.activateOptions();
receiversPanel.updateReceiverTreeInDispatchThread();
} catch (URISyntaxException e1) {
@@ -1305,9 +1305,9 @@
fileReceiver.setLogFormat(receiverConfigurationPanel.getModel().getLogFormat());
}
fileReceiver.setTimestampFormat(receiverConfigurationPanel.getModel().getLogFormatTimestampFormat());
- fileReceiver.setThreshold(Level.TRACE);
-
- pluginRegistry.addPlugin(fileReceiver);
+// fileReceiver.setThreshold(Level.TRACE);
+//
+// pluginRegistry.addPlugin(fileReceiver);
fileReceiver.activateOptions();
receiversPanel.updateReceiverTreeInDispatchThread();
}
diff --git a/src/main/java/org/apache/log4j/chainsaw/vfs/VFSLogFilePatternReceiver.java b/src/main/java/org/apache/log4j/chainsaw/vfs/VFSLogFilePatternReceiver.java
index 0675220..f52a156 100644
--- a/src/main/java/org/apache/log4j/chainsaw/vfs/VFSLogFilePatternReceiver.java
+++ b/src/main/java/org/apache/log4j/chainsaw/vfs/VFSLogFilePatternReceiver.java
@@ -27,6 +27,8 @@
import java.awt.*;
import java.io.*;
import java.util.zip.GZIPInputStream;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
/**
* A VFS-enabled version of org.apache.log4j.varia.LogFilePatternReceiver.
@@ -150,12 +152,15 @@
private boolean autoReconnect;
private VFSReader vfsReader;
+ private static final Logger logger = LogManager.getLogger();
+
public VFSLogFilePatternReceiver() {
super();
}
+ @Override
public void shutdown() {
- getLogger().info("shutdown VFSLogFilePatternReceiver");
+ logger.info("shutdown VFSLogFilePatternReceiver");
active = false;
container = null;
if (vfsReader != null) {
@@ -231,7 +236,7 @@
while (container == null) {
try {
waitForContainerLock.wait(1000);
- getLogger().debug("waiting for setContainer call");
+ logger.debug("waiting for setContainer call");
} catch (InterruptedException ie) {
}
}
@@ -246,7 +251,7 @@
while ((containerFrame1 = (Frame) SwingUtilities.getAncestorOfClass(Frame.class, container)) == null) {
try {
waitForContainerLock.wait(1000);
- getLogger().debug("waiting for container's frame to be available");
+ logger.debug("waiting for container's frame to be available");
} catch (InterruptedException ie) {
}
}
@@ -265,7 +270,7 @@
f.setLocation(d.width / 2, d.height / 2);
f.setVisible(true);
if (null == f.getUserName() || null == f.getPassword()) {
- getLogger().info("Username and password not both provided, not using credentials");
+ logger.info("Username and password not both provided, not using credentials");
} else {
String oldURL = getFileURL();
int index = oldURL.indexOf("://");
@@ -305,7 +310,7 @@
vfsReader = new VFSReader();
new Thread(vfsReader).start();
} else {
- getLogger().info("null URL - unable to parse file");
+ logger.info("null URL - unable to parse file");
}
}
}
@@ -326,7 +331,7 @@
int protocolIndex = getFileURL().indexOf("://");
String loggableFileURL = atIndex > -1 ? getFileURL().substring(0, protocolIndex + "://".length()) + "username:password" + getFileURL().substring(atIndex) : getFileURL();
- getLogger().info("attempting to load file: " + loggableFileURL);
+ logger.info("attempting to load file: " + loggableFileURL);
try {
FileSystemManager fileSystemManager = VFS.getManager();
FileSystemOptions opts = new FileSystemOptions();
@@ -334,7 +339,7 @@
try {
SftpFileSystemConfigBuilder.getInstance().setStrictHostKeyChecking(opts, "no");
} catch (NoClassDefFoundError ncdfe) {
- getLogger().warn("JSch not on classpath!", ncdfe);
+ logger.warn("JSch not on classpath!", ncdfe);
}
synchronized (fileSystemManager) {
@@ -349,13 +354,13 @@
setPath(urlFileName.getPath());
}
} else {
- getLogger().info(loggableFileURL + " not available - will re-attempt to load after waiting " + MISSING_FILE_RETRY_MILLIS + " millis");
+ logger.info(loggableFileURL + " not available - will re-attempt to load after waiting " + MISSING_FILE_RETRY_MILLIS + " millis");
}
}
} catch (FileSystemException fse) {
- getLogger().info(loggableFileURL + " not available - may be due to incorrect credentials, but will re-attempt to load after waiting " + MISSING_FILE_RETRY_MILLIS + " millis", fse);
+ logger.info(loggableFileURL + " not available - may be due to incorrect credentials, but will re-attempt to load after waiting " + MISSING_FILE_RETRY_MILLIS + " millis", fse);
} catch (UnsupportedEncodingException e) {
- getLogger().info("UTF-8 not available", e);
+ logger.info("UTF-8 not available", e);
}
if (reader == null) {
synchronized (this) {
@@ -371,7 +376,7 @@
return;
}
initialize();
- getLogger().debug(getPath() + " exists");
+ logger.debug(getPath() + " exists");
boolean readingFinished = false;
do {
@@ -386,7 +391,7 @@
try {
SftpFileSystemConfigBuilder.getInstance().setStrictHostKeyChecking(opts, "no");
} catch (NoClassDefFoundError ncdfe) {
- getLogger().warn("JSch not on classpath!", ncdfe);
+ logger.warn("JSch not on classpath!", ncdfe);
}
//fileobject was created above, release it and construct a new one
@@ -407,7 +412,7 @@
//available in vfs as of 30 Mar 2006 - will load but not tail if not available
fileObject.refresh();
} catch (Error err) {
- getLogger().info(getPath() + " - unable to refresh fileobject", err);
+ logger.info(getPath() + " - unable to refresh fileobject", err);
}
if (isGZip(getFileURL())) {
@@ -420,7 +425,7 @@
//could have been truncated or appended to (don't do anything if same size)
if (fileObject.getContent().getSize() < lastFileSize) {
reader = new InputStreamReader(fileObject.getContent().getInputStream(), "UTF-8");
- getLogger().debug(getPath() + " was truncated");
+ logger.debug(getPath() + " was truncated");
lastFileSize = 0; //seek to beginning of file
lastFilePointer = 0;
} else if (fileObject.getContent().getSize() > lastFileSize) {
@@ -440,10 +445,10 @@
reader = null;
}
} catch (IOException ioe) {
- getLogger().debug(getPath() + " - unable to close reader", ioe);
+ logger.debug(getPath() + " - unable to close reader", ioe);
}
} else {
- getLogger().info(getPath() + " - not available - will re-attempt to load after waiting " + getWaitMillis() + " millis");
+ logger.info(getPath() + " - not available - will re-attempt to load after waiting " + getWaitMillis() + " millis");
}
try {
@@ -453,17 +458,17 @@
} catch (InterruptedException ie) {
}
if (isTailing() && fileLarger && !terminated) {
- getLogger().debug(getPath() + " - tailing file - file size: " + lastFileSize);
+ logger.debug(getPath() + " - tailing file - file size: " + lastFileSize);
}
} while (isTailing() && !terminated && !readingFinished);
} catch (IOException ioe) {
- getLogger().info(getPath() + " - exception processing file", ioe);
+ logger.info(getPath() + " - exception processing file", ioe);
try {
if (fileObject != null) {
fileObject.close();
}
} catch (FileSystemException e) {
- getLogger().info(getPath() + " - exception processing file", e);
+ logger.info(getPath() + " - exception processing file", e);
}
try {
synchronized (this) {
@@ -473,7 +478,7 @@
}
}
} while (isAutoReconnect() && !terminated && !readingFinished);
- getLogger().debug(getPath() + " - processing complete");
+ logger.debug(getPath() + " - processing complete");
}
public void terminate() {
diff --git a/src/main/java/org/apache/log4j/chainsaw/zeroconf/ZeroConfPlugin.java b/src/main/java/org/apache/log4j/chainsaw/zeroconf/ZeroConfPlugin.java
index ba36fa3..eb47a58 100644
--- a/src/main/java/org/apache/log4j/chainsaw/zeroconf/ZeroConfPlugin.java
+++ b/src/main/java/org/apache/log4j/chainsaw/zeroconf/ZeroConfPlugin.java
@@ -50,6 +50,7 @@
import java.io.FileReader;
import java.io.FileWriter;
import java.util.*;
+import org.apache.log4j.chainsaw.ChainsawReceiver;
/**
* This plugin is designed to detect specific Zeroconf zones (Rendevouz/Bonjour,
@@ -436,19 +437,21 @@
private void connectTo(ServiceInfo info) {
LOG.info("Connection request for " + info);
//Chainsaw can construct receivers from discovered appenders
- Receiver receiver = getReceiver(info);
+ ChainsawReceiver 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");
+ // TODO tell LogUI that we have a new receiver
- // ServiceInfo obeys equals() and hashCode() contracts, so this should be safe.
- synchronized (serviceInfoToReceiveMap) {
- serviceInfoToReceiveMap.put(info, receiver);
- }
+// ((LoggerRepositoryEx) LogManager.getLoggerRepository()).getPluginRegistry().addPlugin(receiver);
+// receiver.activateOptions();
+// LOG.info("Receiver '" + receiver.getName() + "' has been started");
+//
+// // ServiceInfo obeys equals() and hashCode() contracts, so this should be safe.
+// synchronized (serviceInfoToReceiveMap) {
+// serviceInfoToReceiveMap.put(info, receiver);
+// }
// this instance of the menu item needs to be disabled, and have an icon added
JMenuItem item = locateMatchingMenuItem(info.getName());
@@ -460,7 +463,7 @@
// discoveredDevices.fireContentsChanged();
}
- private Receiver getReceiver(ServiceInfo info) {
+ private ChainsawReceiver getReceiver(ServiceInfo info) {
String zone = info.getType();
int port = info.getPort();
String hostAddress = info.getHostAddress();
diff --git a/src/main/java/org/apache/log4j/net/MulticastReceiver.java b/src/main/java/org/apache/log4j/net/MulticastReceiver.java
index 6e7ba3c..a256ede 100644
--- a/src/main/java/org/apache/log4j/net/MulticastReceiver.java
+++ b/src/main/java/org/apache/log4j/net/MulticastReceiver.java
@@ -20,12 +20,15 @@
import org.apache.log4j.plugins.Pauseable;
import org.apache.log4j.plugins.Receiver;
import org.apache.log4j.spi.Decoder;
-import org.apache.log4j.spi.LoggingEvent;
import java.io.IOException;
import java.net.*;
import java.util.ArrayList;
import java.util.List;
+import org.apache.log4j.chainsaw.ChainsawReceiverSkeleton;
+import org.apache.log4j.chainsaw.logevents.ChainsawLoggingEvent;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
/**
@@ -35,8 +38,8 @@
*
* @author Scott Deboy <sdeboy@apache.org>
*/
-public class MulticastReceiver extends Receiver implements PortBased,
- AddressBased, Pauseable {
+public class MulticastReceiver extends ChainsawReceiverSkeleton implements PortBased,
+ AddressBased {
private static final int PACKET_LENGTH = 16384;
private int port;
private String address;
@@ -46,11 +49,12 @@
//default to log4j xml decoder
private String decoder = "org.apache.log4j.xml.XMLDecoder";
private Decoder decoderImpl;
- private MulticastHandlerThread handlerThread;
private MulticastReceiverThread receiverThread;
- private boolean paused;
private boolean advertiseViaMulticastDNS;
private ZeroConfSupport zeroConf;
+ private boolean active = false;
+
+ private static final Logger logger = LogManager.getLogger();
/**
* The MulticastDNS zone advertised by a MulticastReceiver
@@ -97,9 +101,6 @@
if (advertiseViaMulticastDNS) {
zeroConf.unadvertise();
}
- if (handlerThread != null) {
- handlerThread.interrupt();
- }
if (receiverThread != null) {
receiverThread.interrupt();
}
@@ -112,15 +113,16 @@
this.address = address;
}
- public boolean isPaused() {
- return paused;
+ public void setAdvertiseViaMulticastDNS(boolean advertiseViaMulticastDNS) {
+ this.advertiseViaMulticastDNS = advertiseViaMulticastDNS;
}
- public void setPaused(boolean b) {
- paused = b;
+ public boolean isAdvertiseViaMulticastDNS() {
+ return advertiseViaMulticastDNS;
}
- public void activateOptions() {
+ @Override
+ public void start() {
InetAddress addr = null;
try {
@@ -131,9 +133,9 @@
this.decoderImpl = (Decoder) o;
}
} catch (ClassNotFoundException cnfe) {
- getLogger().warn("Unable to find decoder", cnfe);
+ logger.warn("Unable to find decoder", cnfe);
} catch (IllegalAccessException | InstantiationException iae) {
- getLogger().warn("Could not construct decoder", iae);
+ logger.warn("Could not construct decoder", iae);
}
try {
@@ -148,8 +150,6 @@
socket.joinGroup(addr);
receiverThread = new MulticastReceiverThread();
receiverThread.start();
- handlerThread = new MulticastHandlerThread();
- handlerThread.start();
if (advertiseViaMulticastDNS) {
zeroConf = new ZeroConfSupport(ZONE, port, getName());
zeroConf.advertise();
@@ -160,12 +160,9 @@
}
}
- public void setAdvertiseViaMulticastDNS(boolean advertiseViaMulticastDNS) {
- this.advertiseViaMulticastDNS = advertiseViaMulticastDNS;
- }
-
- public boolean isAdvertiseViaMulticastDNS() {
- return advertiseViaMulticastDNS;
+ @Override
+ public boolean isActive() {
+ return active;
}
class MulticastHandlerThread extends Thread {
@@ -204,16 +201,7 @@
for (Object aList2 : list2) {
String data = (String) aList2;
- List<LoggingEvent> v = decoderImpl.decodeEvents(data.trim());
-
- if (v != null) {
-
- for (Object aV : v) {
- if (!isPaused()) {
- doPost((LoggingEvent) aV);
- }
- }
- }
+
}
list2.clear();
@@ -246,12 +234,22 @@
//this string constructor which accepts a charset throws an exception if it is
//null
+ String data;
if (encoding == null) {
- handlerThread.append(
- new String(p.getData(), 0, p.getLength()));
+ data =
+ new String(p.getData(), 0, p.getLength());
} else {
- handlerThread.append(
- new String(p.getData(), 0, p.getLength(), encoding));
+ data =
+ new String(p.getData(), 0, p.getLength(), encoding);
+ }
+
+ List<ChainsawLoggingEvent> v = decoderImpl.decodeEvents(data.trim());
+
+ if (v != null) {
+
+ for (ChainsawLoggingEvent aV : v) {
+ append(aV);
+ }
}
} catch (SocketException se) {
//disconnected
@@ -260,7 +258,7 @@
}
}
- getLogger().debug("{}'s thread is ending.", MulticastReceiver.this.getName());
+ logger.debug("{}'s thread is ending.", MulticastReceiver.this.getName());
}
}
}
diff --git a/src/main/java/org/apache/log4j/net/MulticastReceiverFactory.java b/src/main/java/org/apache/log4j/net/MulticastReceiverFactory.java
new file mode 100644
index 0000000..6425a70
--- /dev/null
+++ b/src/main/java/org/apache/log4j/net/MulticastReceiverFactory.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.log4j.net;
+
+import java.beans.IntrospectionException;
+import java.beans.PropertyDescriptor;
+import org.apache.log4j.chainsaw.ChainsawReceiver;
+import org.apache.log4j.chainsaw.ChainsawReceiverFactory;
+
+/**
+ *
+ */
+public class MulticastReceiverFactory implements ChainsawReceiverFactory{
+
+ @Override
+ public ChainsawReceiver create() {
+ return new MulticastReceiver();
+ }
+
+ @Override
+ public PropertyDescriptor[] getPropertyDescriptors() throws IntrospectionException {
+ return new PropertyDescriptor[]{
+ new PropertyDescriptor("name", MulticastReceiver.class),
+ new PropertyDescriptor("port", MulticastReceiver.class),
+ new PropertyDescriptor("address", MulticastReceiver.class),
+ new PropertyDescriptor("encoding", MulticastReceiver.class),
+ new PropertyDescriptor("decoder", MulticastReceiver.class),
+ };
+ }
+
+ @Override
+ public String getReceiverName() {
+ return "MulticastReceiver";
+ }
+
+}
diff --git a/src/main/java/org/apache/log4j/net/UDPReceiver.java b/src/main/java/org/apache/log4j/net/UDPReceiver.java
index ae990f7..b41cd39 100644
--- a/src/main/java/org/apache/log4j/net/UDPReceiver.java
+++ b/src/main/java/org/apache/log4j/net/UDPReceiver.java
@@ -28,6 +28,10 @@
import java.net.SocketException;
import java.util.ArrayList;
import java.util.List;
+import org.apache.log4j.chainsaw.ChainsawReceiverSkeleton;
+import org.apache.log4j.chainsaw.logevents.ChainsawLoggingEvent;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
/**
@@ -36,7 +40,7 @@
*
* @author Scott Deboy <sdeboy@apache.org>
*/
-public class UDPReceiver extends Receiver implements PortBased, Pauseable {
+public class UDPReceiver extends ChainsawReceiverSkeleton implements PortBased {
private static final int PACKET_LENGTH = 16384;
private UDPReceiverThread receiverThread;
private String encoding;
@@ -44,13 +48,14 @@
//default to log4j xml decoder
private String decoder = "org.apache.log4j.xml.XMLDecoder";
private Decoder decoderImpl;
- protected boolean paused;
- private transient boolean closed = false;
+ private boolean closed = false;
private int port;
private DatagramSocket socket;
- UDPHandlerThread handlerThread;
private boolean advertiseViaMulticastDNS;
private ZeroConfSupport zeroConf;
+ private boolean active = true;
+
+ private static final Logger logger = LogManager.getLogger();
/**
* The MulticastDNS zone advertised by a UDPReceiver
@@ -89,14 +94,6 @@
this.decoder = decoder;
}
- public boolean isPaused() {
- return paused;
- }
-
- public void setPaused(boolean b) {
- paused = b;
- }
-
public void setAdvertiseViaMulticastDNS(boolean advertiseViaMulticastDNS) {
this.advertiseViaMulticastDNS = advertiseViaMulticastDNS;
}
@@ -122,10 +119,6 @@
}
try {
- if (handlerThread != null) {
- handlerThread.close();
- handlerThread.join();
- }
if (receiverThread != null) {
receiverThread.join();
}
@@ -133,13 +126,8 @@
}
}
- /**
- * Returns true if this receiver is active.
- */
-// public synchronized boolean isActive() {
-// return isActive;
-//}
- public void activateOptions() {
+ @Override
+ public void start() {
try {
Class c = Class.forName(decoder);
Object o = c.newInstance();
@@ -148,17 +136,15 @@
this.decoderImpl = (Decoder) o;
}
} catch (ClassNotFoundException cnfe) {
- getLogger().warn("Unable to find decoder", cnfe);
+ logger.warn("Unable to find decoder", cnfe);
} catch (IllegalAccessException | InstantiationException iae) {
- getLogger().warn("Could not construct decoder", iae);
+ logger.warn("Could not construct decoder", iae);
}
try {
socket = new DatagramSocket(port);
receiverThread = new UDPReceiverThread();
receiverThread.start();
- handlerThread = new UDPHandlerThread();
- handlerThread.start();
if (advertiseViaMulticastDNS) {
zeroConf = new ZeroConfSupport(ZONE, port, getName());
zeroConf.advertise();
@@ -169,76 +155,10 @@
}
}
- class UDPHandlerThread extends Thread {
- private final List<String> list = new ArrayList<>();
-
- public UDPHandlerThread() {
- setDaemon(true);
- }
-
- public void append(String data) {
- synchronized (list) {
- list.add(data);
- list.notify();
- }
- }
-
- /**
- * Allow the UDPHandlerThread to wakeup and exit gracefully.
- */
- void close() {
- synchronized (list) {
- list.notify();
- }
- }
-
- public void run() {
- ArrayList<String> list2 = new ArrayList<>();
-
- while (!UDPReceiver.this.closed) {
- synchronized (list) {
- try {
- while (!UDPReceiver.this.closed && list.size() == 0) {
- list.wait(300);
- }
-
- if (list.size() > 0) {
- list2.addAll(list);
- list.clear();
- }
- } catch (InterruptedException ie) {
- }
- }
-
- if (list2.size() > 0) {
-
- for (Object aList2 : list2) {
- String data = (String) aList2;
- List<LoggingEvent> v = decoderImpl.decodeEvents(data);
-
- if (v != null) {
-
- for (Object aV : v) {
- if (!isPaused()) {
- doPost((LoggingEvent) aV);
- }
- }
- }
- }
-
- list2.clear();
- } else {
- try {
- synchronized (this) {
- wait(1000);
- }
- } catch (InterruptedException ie) {
- }
- }
- } // while
- getLogger().debug(UDPReceiver.this.getName() + "'s handler thread is exiting");
- } // run
- } // UDPHandlerThread
+ @Override
+ public boolean isActive() {
+ return active;
+ }
class UDPReceiverThread extends Thread {
public UDPReceiverThread() {
@@ -255,12 +175,16 @@
//this string constructor which accepts a charset throws an exception if it is
//null
+ String data;
if (encoding == null) {
- handlerThread.append(
- new String(p.getData(), 0, p.getLength()));
+ data = new String(p.getData(), 0, p.getLength());
} else {
- handlerThread.append(
- new String(p.getData(), 0, p.getLength(), encoding));
+ data = new String(p.getData(), 0, p.getLength(), encoding);
+ }
+
+ List<ChainsawLoggingEvent> v = decoderImpl.decodeEvents(data);
+ for( ChainsawLoggingEvent evt : v ){
+ append(evt);
}
} catch (SocketException se) {
//disconnected
diff --git a/src/main/java/org/apache/log4j/net/UDPReceiverFactory.java b/src/main/java/org/apache/log4j/net/UDPReceiverFactory.java
new file mode 100644
index 0000000..d6181c4
--- /dev/null
+++ b/src/main/java/org/apache/log4j/net/UDPReceiverFactory.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.log4j.net;
+
+import java.beans.IntrospectionException;
+import java.beans.PropertyDescriptor;
+import org.apache.log4j.chainsaw.ChainsawReceiver;
+import org.apache.log4j.chainsaw.ChainsawReceiverFactory;
+
+/**
+ *
+ */
+public class UDPReceiverFactory implements ChainsawReceiverFactory{
+
+ @Override
+ public ChainsawReceiver create() {
+ return new UDPReceiver();
+ }
+
+ @Override
+ public PropertyDescriptor[] getPropertyDescriptors() throws IntrospectionException {
+ return new PropertyDescriptor[]{
+ new PropertyDescriptor("name", UDPReceiver.class),
+ new PropertyDescriptor("port", UDPReceiver.class),
+ new PropertyDescriptor("encoding", UDPReceiver.class),
+ new PropertyDescriptor("decoder", UDPReceiver.class),
+ };
+ }
+
+ @Override
+ public String getReceiverName() {
+ return "UDPReceiver";
+ }
+}
diff --git a/src/main/java/org/apache/log4j/net/XMLReceiverFactory.java b/src/main/java/org/apache/log4j/net/XMLReceiverFactory.java
new file mode 100644
index 0000000..a7a066c
--- /dev/null
+++ b/src/main/java/org/apache/log4j/net/XMLReceiverFactory.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.log4j.net;
+
+import java.beans.IntrospectionException;
+import java.beans.PropertyDescriptor;
+import org.apache.log4j.chainsaw.ChainsawReceiver;
+import org.apache.log4j.chainsaw.ChainsawReceiverFactory;
+
+/**
+ *
+ * @author robert
+ */
+public class XMLReceiverFactory implements ChainsawReceiverFactory{
+
+ @Override
+ public ChainsawReceiver create() {
+ return new XMLSocketReceiver();
+ }
+
+ @Override
+ public PropertyDescriptor[] getPropertyDescriptors() throws IntrospectionException {
+ return new PropertyDescriptor[]{
+ new PropertyDescriptor("name", XMLSocketReceiver.class),
+ new PropertyDescriptor("port", XMLSocketReceiver.class),
+ };
+ }
+
+ @Override
+ public String getReceiverName() {
+ return "XMLSocketReceiver";
+ }
+
+}
diff --git a/src/main/java/org/apache/log4j/net/XMLSocketNode.java b/src/main/java/org/apache/log4j/net/XMLSocketNode.java
index e97b7a9..e592ae1 100644
--- a/src/main/java/org/apache/log4j/net/XMLSocketNode.java
+++ b/src/main/java/org/apache/log4j/net/XMLSocketNode.java
@@ -1,201 +1,201 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.log4j.net;
-
-import org.apache.log4j.Logger;
-import org.apache.log4j.helpers.Constants;
-import org.apache.log4j.plugins.Receiver;
-import org.apache.log4j.spi.ComponentBase;
-import org.apache.log4j.spi.Decoder;
-import org.apache.log4j.spi.LoggerRepository;
-import org.apache.log4j.spi.LoggingEvent;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.Socket;
-import java.util.List;
-
-
-/**
- * Read {@link LoggingEvent} objects sent from a remote client using XML over
- * Sockets (TCP). These logging events are logged according to local
- * policy, as if they were generated locally.
- * <p>
- * <p>For example, the socket node might decide to log events to a
- * local file and also resent them to a second socket node.
- *
- * @author Scott Deboy <sdeboy@apache.org>;
- * @since 0.8.4
- */
-public class XMLSocketNode extends ComponentBase implements Runnable {
- Socket socket;
- Receiver receiver;
- Decoder decoder;
- SocketNodeEventListener listener;
-
- /**
- * Constructor for socket and logger repository.
- */
- public XMLSocketNode(
- String decoder, Socket socket, LoggerRepository hierarchy) {
- this.repository = hierarchy;
- try {
- Class c = Class.forName(decoder);
- Object o = c.newInstance();
-
- if (o instanceof Decoder) {
- this.decoder = (Decoder) o;
- }
- } catch (ClassNotFoundException cnfe) {
- getLogger().warn("Unable to find decoder", cnfe);
- } catch (IllegalAccessException | InstantiationException iae) {
- getLogger().warn("Unable to construct decoder", iae);
- }
-
- this.socket = socket;
- }
-
- /**
- * Constructor for socket and reciever.
- */
- public XMLSocketNode(String decoder, Socket socket, Receiver receiver) {
- try {
- Class c = Class.forName(decoder);
- Object o = c.newInstance();
-
- if (o instanceof Decoder) {
- this.decoder = (Decoder) o;
- }
- } catch (ClassNotFoundException cnfe) {
- getLogger().warn("Unable to find decoder", cnfe);
- } catch (IllegalAccessException | InstantiationException iae) {
- getLogger().warn("Unable to construct decoder", iae);
- }
-
- this.socket = socket;
- this.receiver = receiver;
- }
-
- /**
- * Set the event listener on this node.
- */
- public void setListener(SocketNodeEventListener _listener) {
- listener = _listener;
- }
-
- public void run() {
- Logger remoteLogger;
- Exception listenerException = null;
- InputStream is;
-
- if ((this.receiver == null) || (this.decoder == null)) {
- listenerException =
- new Exception(
- "No receiver or decoder provided. Cannot process xml socket events");
- getLogger().error(
- "Exception constructing XML Socket Receiver", listenerException);
- }
-
- try {
- is = socket.getInputStream();
- } catch (Exception e) {
- is = null;
- listenerException = e;
- getLogger().error("Exception opening InputStream to " + socket, e);
- }
-
- if (is != null) {
- String hostName = socket.getInetAddress().getHostName();
- String remoteInfo = hostName + ":" + socket.getPort();
-
- try {
- //read data from the socket
- //it's up to the individual decoder to handle incomplete event data
- while (true) {
- byte[] b = new byte[1024];
- int length = is.read(b);
- if (length == -1) {
- getLogger().info(
- "no bytes read from stream - closing connection.");
- break;
- }
- List<LoggingEvent> v = decoder.decodeEvents(new String(b, 0, length));
-
- if (v != null) {
-
- for (Object aV : v) {
- LoggingEvent e = (LoggingEvent) aV;
- e.setProperty(Constants.HOSTNAME_KEY, hostName);
-
- // store the known remote info in an event property
- e.setProperty("log4j.remoteSourceInfo", remoteInfo);
-
- // if configured with a receiver, tell it to post the event
- if (receiver != null) {
- receiver.doPost(e);
-
- // else post it via the hierarchy
- } else {
- // get a logger from the hierarchy. The name of the logger
- // is taken to be the name contained in the event.
- remoteLogger = repository.getLogger(e.getLoggerName());
-
- //event.logger = remoteLogger;
- // apply the logger-level filter
- if (
- e.getLevel().isGreaterOrEqual(
- remoteLogger.getEffectiveLevel())) {
- // finally log the event as if was generated locally
- remoteLogger.callAppenders(e);
- }
- }
- }
- }
- }
- } catch (java.io.EOFException e) {
- getLogger().info("Caught java.io.EOFException closing connection.");
- listenerException = e;
- } catch (java.net.SocketException e) {
- getLogger().info(
- "Caught java.net.SocketException closing connection.");
- listenerException = e;
- } catch (IOException e) {
- getLogger().info("Caught java.io.IOException: " + e);
- getLogger().info("Closing connection.");
- listenerException = e;
- } catch (Exception e) {
- getLogger().error("Unexpected exception. Closing connection.", e);
- listenerException = e;
- }
- }
-
- // close the socket
- try {
- if (is != null) {
- is.close();
- }
- } catch (Exception e) {
- //logger.info("Could not close connection.", e);
- }
-
- // send event to listener, if configured
- if (listener != null) {
- listener.socketClosedEvent(listenerException);
- }
- }
-}
+///*
+// * Licensed to the Apache Software Foundation (ASF) under one or more
+// * contributor license agreements. See the NOTICE file distributed with
+// * this work for additional information regarding copyright ownership.
+// * The ASF licenses this file to You under the Apache License, Version 2.0
+// * (the "License"); you may not use this file except in compliance with
+// * the License. You may obtain a copy of the License at
+// *
+// * http://www.apache.org/licenses/LICENSE-2.0
+// *
+// * Unless required by applicable law or agreed to in writing, software
+// * distributed under the License is distributed on an "AS IS" BASIS,
+// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// * See the License for the specific language governing permissions and
+// * limitations under the License.
+// */
+//
+//package org.apache.log4j.net;
+//
+//import org.apache.log4j.Logger;
+//import org.apache.log4j.helpers.Constants;
+//import org.apache.log4j.plugins.Receiver;
+//import org.apache.log4j.spi.ComponentBase;
+//import org.apache.log4j.spi.Decoder;
+//import org.apache.log4j.spi.LoggerRepository;
+//import org.apache.log4j.spi.LoggingEvent;
+//
+//import java.io.IOException;
+//import java.io.InputStream;
+//import java.net.Socket;
+//import java.util.List;
+//
+//
+///**
+// * Read {@link LoggingEvent} objects sent from a remote client using XML over
+// * Sockets (TCP). These logging events are logged according to local
+// * policy, as if they were generated locally.
+// * <p>
+// * <p>For example, the socket node might decide to log events to a
+// * local file and also resent them to a second socket node.
+// *
+// * @author Scott Deboy <sdeboy@apache.org>;
+// * @since 0.8.4
+// */
+//public class XMLSocketNode extends ComponentBase implements Runnable {
+// Socket socket;
+// Receiver receiver;
+// Decoder decoder;
+// SocketNodeEventListener listener;
+//
+// /**
+// * Constructor for socket and logger repository.
+// */
+// public XMLSocketNode(
+// String decoder, Socket socket, LoggerRepository hierarchy) {
+// this.repository = hierarchy;
+// try {
+// Class c = Class.forName(decoder);
+// Object o = c.newInstance();
+//
+// if (o instanceof Decoder) {
+// this.decoder = (Decoder) o;
+// }
+// } catch (ClassNotFoundException cnfe) {
+// getLogger().warn("Unable to find decoder", cnfe);
+// } catch (IllegalAccessException | InstantiationException iae) {
+// getLogger().warn("Unable to construct decoder", iae);
+// }
+//
+// this.socket = socket;
+// }
+//
+// /**
+// * Constructor for socket and reciever.
+// */
+// public XMLSocketNode(String decoder, Socket socket, Receiver receiver) {
+// try {
+// Class c = Class.forName(decoder);
+// Object o = c.newInstance();
+//
+// if (o instanceof Decoder) {
+// this.decoder = (Decoder) o;
+// }
+// } catch (ClassNotFoundException cnfe) {
+// getLogger().warn("Unable to find decoder", cnfe);
+// } catch (IllegalAccessException | InstantiationException iae) {
+// getLogger().warn("Unable to construct decoder", iae);
+// }
+//
+// this.socket = socket;
+// this.receiver = receiver;
+// }
+//
+// /**
+// * Set the event listener on this node.
+// */
+// public void setListener(SocketNodeEventListener _listener) {
+// listener = _listener;
+// }
+//
+// public void run() {
+// Logger remoteLogger;
+// Exception listenerException = null;
+// InputStream is;
+//
+// if ((this.receiver == null) || (this.decoder == null)) {
+// listenerException =
+// new Exception(
+// "No receiver or decoder provided. Cannot process xml socket events");
+// getLogger().error(
+// "Exception constructing XML Socket Receiver", listenerException);
+// }
+//
+// try {
+// is = socket.getInputStream();
+// } catch (Exception e) {
+// is = null;
+// listenerException = e;
+// getLogger().error("Exception opening InputStream to " + socket, e);
+// }
+//
+// if (is != null) {
+// String hostName = socket.getInetAddress().getHostName();
+// String remoteInfo = hostName + ":" + socket.getPort();
+//
+// try {
+// //read data from the socket
+// //it's up to the individual decoder to handle incomplete event data
+// while (true) {
+// byte[] b = new byte[1024];
+// int length = is.read(b);
+// if (length == -1) {
+// getLogger().info(
+// "no bytes read from stream - closing connection.");
+// break;
+// }
+// List<LoggingEvent> v = decoder.decodeEvents(new String(b, 0, length));
+//
+// if (v != null) {
+//
+// for (Object aV : v) {
+// LoggingEvent e = (LoggingEvent) aV;
+// e.setProperty(Constants.HOSTNAME_KEY, hostName);
+//
+// // store the known remote info in an event property
+// e.setProperty("log4j.remoteSourceInfo", remoteInfo);
+//
+// // if configured with a receiver, tell it to post the event
+// if (receiver != null) {
+// receiver.doPost(e);
+//
+// // else post it via the hierarchy
+// } else {
+// // get a logger from the hierarchy. The name of the logger
+// // is taken to be the name contained in the event.
+// remoteLogger = repository.getLogger(e.getLoggerName());
+//
+// //event.logger = remoteLogger;
+// // apply the logger-level filter
+// if (
+// e.getLevel().isGreaterOrEqual(
+// remoteLogger.getEffectiveLevel())) {
+// // finally log the event as if was generated locally
+// remoteLogger.callAppenders(e);
+// }
+// }
+// }
+// }
+// }
+// } catch (java.io.EOFException e) {
+// getLogger().info("Caught java.io.EOFException closing connection.");
+// listenerException = e;
+// } catch (java.net.SocketException e) {
+// getLogger().info(
+// "Caught java.net.SocketException closing connection.");
+// listenerException = e;
+// } catch (IOException e) {
+// getLogger().info("Caught java.io.IOException: " + e);
+// getLogger().info("Closing connection.");
+// listenerException = e;
+// } catch (Exception e) {
+// getLogger().error("Unexpected exception. Closing connection.", e);
+// listenerException = e;
+// }
+// }
+//
+// // close the socket
+// try {
+// if (is != null) {
+// is.close();
+// }
+// } catch (Exception e) {
+// //logger.info("Could not close connection.", e);
+// }
+//
+// // send event to listener, if configured
+// if (listener != null) {
+// listener.socketClosedEvent(listenerException);
+// }
+// }
+//}
diff --git a/src/main/java/org/apache/log4j/net/XMLSocketReceiver.java b/src/main/java/org/apache/log4j/net/XMLSocketReceiver.java
index eadea44..fe2edd3 100644
--- a/src/main/java/org/apache/log4j/net/XMLSocketReceiver.java
+++ b/src/main/java/org/apache/log4j/net/XMLSocketReceiver.java
@@ -17,6 +17,7 @@
package org.apache.log4j.net;
+import java.io.InputStream;
import org.apache.log4j.plugins.Pauseable;
import org.apache.log4j.plugins.Plugin;
import org.apache.log4j.plugins.Receiver;
@@ -27,6 +28,11 @@
import java.net.Socket;
import java.util.List;
import java.util.Vector;
+import org.apache.log4j.chainsaw.ChainsawReceiverSkeleton;
+import org.apache.log4j.chainsaw.logevents.ChainsawLoggingEvent;
+import org.apache.log4j.spi.Decoder;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
/**
@@ -49,8 +55,7 @@
* @author Mark Womack
* @author Scott Deboy <sdeboy@apache.org>
*/
-public class XMLSocketReceiver extends Receiver implements Runnable, PortBased, Pauseable {
- private boolean paused;
+public class XMLSocketReceiver extends ChainsawReceiverSkeleton implements Runnable, PortBased {
//default to log4j xml decoder
protected String decoder = "org.apache.log4j.xml.XMLDecoder";
private ServerSocket serverSocket;
@@ -60,6 +65,9 @@
protected int port = DEFAULT_PORT;
private boolean advertiseViaMulticastDNS;
private ZeroConfSupport zeroConf;
+ private boolean active = false;
+
+ private static final Logger logger = LogManager.getLogger();
/**
* The MulticastDNS zone advertised by an XMLSocketReceiver
@@ -74,15 +82,6 @@
public XMLSocketReceiver() {
}
- public XMLSocketReceiver(int _port) {
- port = _port;
- }
-
- public XMLSocketReceiver(int _port, LoggerRepository _repository) {
- port = _port;
- repository = _repository;
- }
-
/**
* Get the port to receive logging events on.
*/
@@ -108,49 +107,6 @@
decoder = _decoder;
}
- public boolean isPaused() {
- return paused;
- }
-
- public void setPaused(boolean b) {
- paused = b;
- }
-
- /**
- * Returns true if the receiver is the same class and they are
- * configured for the same properties, and super class also considers
- * them to be equivalent. This is used by PluginRegistry when determining
- * if the a similarly configured receiver is being started.
- *
- * @param testPlugin The plugin to test equivalency against.
- * @return boolean True if the testPlugin is equivalent to this plugin.
- */
- public boolean isEquivalent(Plugin testPlugin) {
- if ((testPlugin != null) && testPlugin instanceof XMLSocketReceiver) {
- XMLSocketReceiver sReceiver = (XMLSocketReceiver) testPlugin;
-
- return (port == sReceiver.getPort() && super.isEquivalent(testPlugin));
- }
-
- return false;
- }
-
- public int hashCode() {
-
- int result = 37 * (repository != null ? repository.hashCode() : 0);
- result = result * 37 + port;
- return (result * 37 + (getName() != null ? getName().hashCode() : 0));
- }
-
- /**
- * Sets the flag to indicate if receiver is active or not.
- *
- * @param b new value
- */
- protected synchronized void setActive(final boolean b) {
- active = b;
- }
-
/**
* Starts the XMLSocketReceiver with the current options.
*/
@@ -181,6 +137,7 @@
* Called when the receiver should be stopped. Closes the
* server socket and all of the open sockets.
*/
+ @Override
public synchronized void shutdown() {
// mark this as no longer running
active = false;
@@ -199,14 +156,11 @@
private synchronized void doShutdown() {
active = false;
- getLogger().debug("{} doShutdown called", getName());
+ logger.debug("{} doShutdown called", getName());
// close the server socket
closeServerSocket();
- // close all of the accepted sockets
- closeAllAcceptedSockets();
-
if (advertiseViaMulticastDNS) {
zeroConf.unadvertise();
}
@@ -216,7 +170,7 @@
* Closes the server socket, if created.
*/
private void closeServerSocket() {
- getLogger().debug("{} closing server socket", getName());
+ logger.debug("{} closing server socket", getName());
try {
if (serverSocket != null) {
@@ -230,39 +184,22 @@
}
/**
- * Closes all the connected sockets in the List.
- */
- private synchronized void closeAllAcceptedSockets() {
- for (Object aSocketList : socketList) {
- try {
- ((Socket) aSocketList).close();
- } catch (Exception e) {
- // ignore for now
- }
- }
-
- // clear member variables
- socketList.clear();
- }
-
- /**
* Loop, accepting new socket connections.
*/
public void run() {
/**
* Ensure we start fresh.
*/
- getLogger().debug("performing socket cleanup prior to entering loop for {}", name);
+ logger.debug("performing socket cleanup prior to entering loop for {}", name);
closeServerSocket();
- closeAllAcceptedSockets();
- getLogger().debug("socket cleanup complete for {}", name);
+ logger.debug("socket cleanup complete for {}", name);
active = true;
// start the server socket
try {
serverSocket = new ServerSocket(port);
} catch (Exception e) {
- getLogger().error(
+ logger.error(
"error starting XMLSocketReceiver (" + this.getName()
+ "), receiver did not start", e);
active = false;
@@ -274,26 +211,22 @@
Socket socket = null;
try {
- getLogger().debug("in run-about to enter while isactiveloop");
+ logger.debug("in run-about to enter while isactiveloop");
active = true;
while (!rThread.isInterrupted()) {
// if we have a socket, start watching it
- if (socket != null) {
- getLogger().debug("socket not null - creating and starting socketnode");
- socketList.add(socket);
-
- XMLSocketNode node = new XMLSocketNode(decoder, socket, this);
- node.setLoggerRepository(this.repository);
- new Thread(node).start();
+ if (socket != null ) {
+ logger.debug("socket not null - parsing data");
+ parseIncomingData(socket);
}
- getLogger().debug("waiting to accept socket");
+ logger.debug("waiting to accept socket");
// wait for a socket to open, then loop to start it
socket = serverSocket.accept();
- getLogger().debug("accepted socket");
+ logger.debug("accepted socket");
}
// socket not watched because we a no longer running
@@ -302,19 +235,79 @@
socket.close();
}
} catch (Exception e) {
- getLogger().warn(
+ logger.warn(
"socket server disconnected, stopping");
}
}
- /* (non-Javadoc)
- * @see org.apache.log4j.plugins.Receiver#doPost(org.apache.log4j.spi.LoggingEvent)
- */
- public void doPost(LoggingEvent event) {
- if (!isPaused()) {
- super.doPost(event);
+ @Override
+ public void start() {
+ logger.debug("Starting receiver");
+ if (!isActive()) {
+ rThread = new Thread(this);
+ rThread.setDaemon(true);
+ rThread.start();
+
+ if (advertiseViaMulticastDNS) {
+ zeroConf = new ZeroConfSupport(ZONE, port, getName());
+ zeroConf.advertise();
+ }
+
+ active = true;
}
}
+ @Override
+ public boolean isActive() {
+ return active;
+ }
+ private void parseIncomingData(Socket sock){
+ InputStream is;
+ Decoder d = null;
+
+ try{
+ d = (Decoder) Class.forName(decoder).getDeclaredConstructor().newInstance();
+ } catch (Exception e) {
+ logger.error("Unable to load correct decoder", e);
+ return;
+ }
+
+ try {
+ is = sock.getInputStream();
+ } catch (Exception e) {
+ is = null;
+ logger.error("Exception opening InputStream to " + sock, e);
+ return;
+ }
+
+ while (is != null) {
+ try{
+ byte[] b = new byte[1024];
+ int length = is.read(b);
+ if (length == -1) {
+ logger.info(
+ "no bytes read from stream - closing connection.");
+ break;
+ }
+ List<ChainsawLoggingEvent> v = d.decodeEvents(new String(b, 0, length));
+
+ for( ChainsawLoggingEvent evt : v ){
+ append(evt);
+ }
+ }catch(Exception ex){
+ logger.error(ex);
+ break;
+ }
+ }
+
+ // close the socket
+ try {
+ if (is != null) {
+ is.close();
+ }
+ } catch (Exception e) {
+ //logger.info("Could not close connection.", e);
+ }
+ }
}
diff --git a/src/main/java/org/apache/log4j/spi/Decoder.java b/src/main/java/org/apache/log4j/spi/Decoder.java
index 6965105..5d3cb15 100644
--- a/src/main/java/org/apache/log4j/spi/Decoder.java
+++ b/src/main/java/org/apache/log4j/spi/Decoder.java
@@ -22,6 +22,7 @@
import java.net.URL;
import java.util.Map;
import java.util.Vector;
+import org.apache.log4j.chainsaw.logevents.ChainsawLoggingEvent;
/**
@@ -37,7 +38,7 @@
* @param document document to decode.
* @return list of LoggingEvent instances.
*/
- Vector<LoggingEvent> decodeEvents(String document);
+ Vector<ChainsawLoggingEvent> decodeEvents(String document);
/**
* Decode event from string.
@@ -45,7 +46,7 @@
* @param event string representation of event
* @return event
*/
- LoggingEvent decode(String event);
+ ChainsawLoggingEvent decode(String event);
/**
* Decode event from document retreived from URL.
@@ -54,7 +55,7 @@
* @return list of LoggingEvent instances.
* @throws IOException if IO error resolving document.
*/
- Vector<LoggingEvent> decode(URL url) throws IOException;
+ Vector<ChainsawLoggingEvent> decode(URL url) throws IOException;
/**
* Sets additional properties.
diff --git a/src/main/java/org/apache/log4j/varia/LogFilePatternReceiver.java b/src/main/java/org/apache/log4j/varia/LogFilePatternReceiver.java
index a777fba..773c644 100644
--- a/src/main/java/org/apache/log4j/varia/LogFilePatternReceiver.java
+++ b/src/main/java/org/apache/log4j/varia/LogFilePatternReceiver.java
@@ -17,25 +17,28 @@
package org.apache.log4j.varia;
-import org.apache.log4j.Level;
-import org.apache.log4j.Logger;
import org.apache.log4j.helpers.Constants;
import org.apache.log4j.plugins.Receiver;
import org.apache.log4j.rule.ExpressionRule;
import org.apache.log4j.rule.Rule;
-import org.apache.log4j.spi.LocationInfo;
-import org.apache.log4j.spi.LoggingEvent;
import org.apache.log4j.spi.ThrowableInformation;
import java.io.*;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.SimpleDateFormat;
+import java.time.Instant;
import java.util.*;
import java.util.regex.MatchResult;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
+import org.apache.log4j.chainsaw.ChainsawReceiverSkeleton;
+import org.apache.log4j.chainsaw.logevents.ChainsawLoggingEvent;
+import org.apache.log4j.chainsaw.logevents.ChainsawLoggingEventBuilder;
+import org.apache.log4j.chainsaw.logevents.Level;
+import org.apache.log4j.chainsaw.logevents.LocationInfo;
+import org.apache.logging.log4j.LogManager;
/**
* LogFilePatternReceiver can parse and tail log files, converting entries into
@@ -127,7 +130,7 @@
*
* @author Scott Deboy
*/
-public class LogFilePatternReceiver extends Receiver {
+public class LogFilePatternReceiver extends ChainsawReceiverSkeleton {
private final List<String> keywords = new ArrayList<>();
private static final String PROP_START = "PROP(";
@@ -197,6 +200,12 @@
//default to one line - this number is incremented for each (NL) found in the logFormat
private int lineCount = 1;
+ protected boolean active = false;
+
+ private ChainsawLoggingEventBuilder build = new ChainsawLoggingEventBuilder();
+
+ private static final org.apache.logging.log4j.Logger logger = LogManager.getLogger();
+
public LogFilePatternReceiver() {
keywords.add(TIMESTAMP);
keywords.add(LOGGER);
@@ -475,11 +484,11 @@
*
* @return event
*/
- private LoggingEvent buildEvent() {
+ private ChainsawLoggingEvent buildEvent() {
if (currentMap.size() == 0) {
if (additionalLines.size() > 0) {
for (Object additionalLine : additionalLines) {
- getLogger().debug("found non-matching line: " + additionalLine);
+ logger.debug("found non-matching line: " + additionalLine);
}
}
additionalLines.clear();
@@ -494,7 +503,7 @@
currentMap.put(MESSAGE, buildMessage((String) currentMap.get(MESSAGE),
exceptionLine));
}
- LoggingEvent event = convertToEvent(currentMap, exception);
+ ChainsawLoggingEvent event = convertToEvent(currentMap, exception);
currentMap.clear();
additionalLines.clear();
return event;
@@ -531,10 +540,10 @@
exceptionMatcher = exceptionPattern.matcher(input);
if (eventMatcher.matches()) {
//build an event from the previous match (held in current map)
- LoggingEvent event = buildEvent();
+ ChainsawLoggingEvent event = buildEvent();
if (event != null) {
if (passesExpression(event)) {
- doPost(event);
+ append(event);
}
}
currentMap.putAll(processEvent(eventMatcher.toMatchResult()));
@@ -551,10 +560,10 @@
String lastTime = (String) currentMap.get(TIMESTAMP);
//build an event from the previous match (held in current map)
if (currentMap.size() > 0) {
- LoggingEvent event = buildEvent();
+ ChainsawLoggingEvent event = buildEvent();
if (event != null) {
if (passesExpression(event)) {
- doPost(event);
+ append(event);
}
}
}
@@ -569,10 +578,10 @@
}
//process last event if one exists
- LoggingEvent event = buildEvent();
+ ChainsawLoggingEvent event = buildEvent();
if (event != null) {
if (passesExpression(event)) {
- doPost(event);
+ append(event);
}
}
}
@@ -587,7 +596,7 @@
* @param event
* @return true if expression isn't set, or the result of the evaluation otherwise
*/
- private boolean passesExpression(LoggingEvent event) {
+ private boolean passesExpression(ChainsawLoggingEvent event) {
if (event != null) {
if (expressionRule != null) {
// return (expressionRule.evaluate(event, null));
@@ -683,7 +692,7 @@
expressionRule = ExpressionRule.getRule(filterExpression);
}
} catch (Exception e) {
- getLogger().warn("Invalid filter expression: " + filterExpression, e);
+ logger.warn("Invalid filter expression: " + filterExpression, e);
}
List<String> buildingKeywords = new ArrayList<>();
@@ -782,7 +791,7 @@
}
regexp = newPattern;
- getLogger().debug("regexp is " + regexp);
+ logger.debug("regexp is " + regexp);
}
private void updateCustomLevelDefinitionMap() {
@@ -792,7 +801,7 @@
customLevelDefinitionMap.clear();
while (entryTokenizer.hasMoreTokens()) {
StringTokenizer innerTokenizer = new StringTokenizer(entryTokenizer.nextToken(), "=");
- customLevelDefinitionMap.put(innerTokenizer.nextToken(), Level.toLevel(innerTokenizer.nextToken()));
+// customLevelDefinitionMap.put(innerTokenizer.nextToken(), Level.toLevel(innerTokenizer.nextToken()));
}
}
}
@@ -836,7 +845,7 @@
int propLength = oldString.length();
int startPos = inputString.indexOf(oldString);
if (startPos == -1) {
- getLogger().info("string: " + oldString + " not found in input: " + inputString + " - returning input");
+ logger.info("string: " + oldString + " not found in input: " + inputString + " - returning input");
return inputString;
}
if (startPos == 0) {
@@ -891,7 +900,7 @@
* @param exception
* @return logging event
*/
- private LoggingEvent convertToEvent(Map fieldMap, String[] exception) {
+ private ChainsawLoggingEvent convertToEvent(Map fieldMap, String[] exception) {
if (fieldMap == null) {
return null;
}
@@ -904,11 +913,11 @@
exception = emptyException;
}
- Logger logger;
+ String logger;
long timeStamp = 0L;
String level;
String threadName;
- Object message;
+ String message;
String ndc;
String className;
String methodName;
@@ -916,7 +925,7 @@
String lineNumber;
Hashtable properties = new Hashtable();
- logger = Logger.getLogger((String) fieldMap.remove(LOGGER));
+ logger = (String) fieldMap.remove(LOGGER);
if ((dateFormat != null) && fieldMap.containsKey(TIMESTAMP)) {
try {
@@ -931,31 +940,31 @@
timeStamp = System.currentTimeMillis();
}
- message = fieldMap.remove(MESSAGE);
+ message = (String)fieldMap.remove(MESSAGE);
if (message == null) {
message = "";
}
level = (String) fieldMap.remove(LEVEL);
- Level levelImpl;
- if (level == null) {
- levelImpl = Level.DEBUG;
- } else {
- //first try to resolve against custom level definition map, then fall back to regular levels
- levelImpl = customLevelDefinitionMap.get(level);
- if (levelImpl == null) {
- levelImpl = Level.toLevel(level.trim());
- if (!level.equals(levelImpl.toString())) {
- //check custom level map
- if (levelImpl == null) {
- levelImpl = Level.DEBUG;
- getLogger().debug("found unexpected level: " + level + ", logger: " + logger.getName() + ", msg: " + message);
- //make sure the text that couldn't match a level is added to the message
- message = level + " " + message;
- }
- }
- }
- }
+// Level levelImpl;
+// if (level == null) {
+// levelImpl = Level.DEBUG;
+// } else {
+// //first try to resolve against custom level definition map, then fall back to regular levels
+// levelImpl = customLevelDefinitionMap.get(level);
+// if (levelImpl == null) {
+// levelImpl = Level.toLevel(level.trim());
+// if (!level.equals(levelImpl.toString())) {
+// //check custom level map
+// if (levelImpl == null) {
+// levelImpl = Level.DEBUG;
+// logger.debug("found unexpected level: " + level + ", logger: " + logger.getName() + ", msg: " + message);
+// //make sure the text that couldn't match a level is added to the message
+// message = level + " " + message;
+// }
+// }
+// }
+// }
threadName = (String) fieldMap.remove(THREAD);
@@ -979,24 +988,25 @@
//all remaining entries in fieldmap are properties
properties.putAll(fieldMap);
- LocationInfo info;
+ LocationInfo info = null;
if ((eventFileName != null) || (className != null) || (methodName != null)
|| (lineNumber != null)) {
- info = new LocationInfo(eventFileName, className, methodName, lineNumber);
- } else {
- info = LocationInfo.NA_LOCATION_INFO;
+ info = new LocationInfo(eventFileName, className, methodName,
+ Integer.parseInt(lineNumber));
}
- LoggingEvent event = new LoggingEvent(null,
- logger, timeStamp, levelImpl, message,
- threadName,
- new ThrowableInformation(exception),
- ndc,
- info,
- properties);
+ build.clear();
+ build.setLogger(logger)
+ .setTimestamp(Instant.ofEpochMilli(timeStamp))
+ .setLevelFromString(level)
+ .setMessage(message)
+ .setThreadName(threadName)
+ .setLocationInfo(info)
+ .setNDC(ndc)
+ .setMDC(properties);
- return event;
+ return build.create();
}
// public static void main(String[] args) {
@@ -1018,8 +1028,9 @@
/**
* Close the reader.
*/
+ @Override
public void shutdown() {
- getLogger().info(getPath() + " shutdown");
+ logger.info(getPath() + " shutdown");
active = false;
try {
if (reader != null) {
@@ -1034,18 +1045,19 @@
/**
* Read and process the log file.
*/
- public void activateOptions() {
- getLogger().info("activateOptions");
+ @Override
+ public void start() {
+ logger.info("activateOptions");
active = true;
Runnable runnable = new Runnable() {
public void run() {
initialize();
while (reader == null) {
- getLogger().info("attempting to load file: " + getFileURL());
+ logger.info("attempting to load file: " + getFileURL());
try {
reader = new InputStreamReader(new URL(getFileURL()).openStream(), "UTF-8");
} catch (FileNotFoundException fnfe) {
- getLogger().info("file not available - will try again");
+ logger.info("file not available - will try again");
synchronized (this) {
try {
wait(MISSING_FILE_RETRY_MILLIS);
@@ -1053,7 +1065,7 @@
}
}
} catch (IOException ioe) {
- getLogger().warn("unable to load file", ioe);
+ logger.warn("unable to load file", ioe);
return;
}
}
@@ -1069,15 +1081,15 @@
} catch (InterruptedException ie) {
}
if (tailing) {
- getLogger().debug("tailing file");
+ logger.debug("tailing file");
}
} while (tailing);
} catch (IOException ioe) {
//io exception - probably shut down
- getLogger().info("stream closed");
+ logger.info("stream closed");
}
- getLogger().debug("processing " + path + " complete");
+ logger.debug("processing " + path + " complete");
shutdown();
}
};
diff --git a/src/main/java/org/apache/log4j/varia/LogFilePatternReceiverFactory.java b/src/main/java/org/apache/log4j/varia/LogFilePatternReceiverFactory.java
new file mode 100644
index 0000000..60af991
--- /dev/null
+++ b/src/main/java/org/apache/log4j/varia/LogFilePatternReceiverFactory.java
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.log4j.varia;
+
+import java.beans.IntrospectionException;
+import java.beans.PropertyDescriptor;
+import org.apache.log4j.chainsaw.ChainsawReceiver;
+import org.apache.log4j.chainsaw.ChainsawReceiverFactory;
+
+/**
+ *
+ */
+public class LogFilePatternReceiverFactory implements ChainsawReceiverFactory {
+
+ @Override
+ public ChainsawReceiver create() {
+ return new LogFilePatternReceiver();
+ }
+
+ @Override
+ public PropertyDescriptor[] getPropertyDescriptors() throws IntrospectionException {
+ return new PropertyDescriptor[]{
+ new PropertyDescriptor("name", LogFilePatternReceiver.class),
+ new PropertyDescriptor("fileURL", LogFilePatternReceiver.class),
+ new PropertyDescriptor("appendNonMatches", LogFilePatternReceiver.class),
+ new PropertyDescriptor("filterExpression", LogFilePatternReceiver.class),
+ new PropertyDescriptor("tailing", LogFilePatternReceiver.class),
+ new PropertyDescriptor("logFormat", LogFilePatternReceiver.class),
+ new PropertyDescriptor("group", LogFilePatternReceiver.class),
+ new PropertyDescriptor("timestampFormat", LogFilePatternReceiver.class),
+ new PropertyDescriptor("waitMillis", LogFilePatternReceiver.class),
+ };
+ }
+
+ @Override
+ public String getReceiverName() {
+ return "LogFilePatternReceiver";
+ }
+}
diff --git a/src/main/java/org/apache/log4j/xml/LogFileXMLReceiver.java b/src/main/java/org/apache/log4j/xml/LogFileXMLReceiver.java
index 12a814d..8011c9d 100644
--- a/src/main/java/org/apache/log4j/xml/LogFileXMLReceiver.java
+++ b/src/main/java/org/apache/log4j/xml/LogFileXMLReceiver.java
@@ -28,6 +28,10 @@
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Collection;
+import org.apache.log4j.chainsaw.ChainsawReceiverSkeleton;
+import org.apache.log4j.chainsaw.logevents.ChainsawLoggingEvent;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
/**
* LogFileXMLReceiver will read an xml-formated log file and make the events in the log file
@@ -55,7 +59,7 @@
* @since 1.3
*/
-public class LogFileXMLReceiver extends Receiver {
+public class LogFileXMLReceiver extends ChainsawReceiverSkeleton {
private String fileURL;
private Rule expressionRule;
private String filterExpression;
@@ -69,6 +73,8 @@
private String path;
private boolean useCurrentThread;
+ private static final Logger logger = LogManager.getLogger();
+
/**
* Accessor
*
@@ -143,10 +149,10 @@
this.filterExpression = filterExpression;
}
- private boolean passesExpression(LoggingEvent event) {
+ private boolean passesExpression(ChainsawLoggingEvent event) {
if (event != null) {
if (expressionRule != null) {
-// return (expressionRule.evaluate(event, null));
+ return (expressionRule.evaluate(event, null));
}
}
return true;
@@ -174,67 +180,10 @@
}
}
- /**
- * Process the file
- */
- public void activateOptions() {
- Runnable runnable = () -> {
- try {
- URL url = new URL(fileURL);
- host = url.getHost();
- if (host != null && host.equals("")) {
- host = FILE_KEY;
- }
- path = url.getPath();
- } catch (MalformedURLException e1) {
- // TODO Auto-generated catch block
- e1.printStackTrace();
- }
-
- try {
- if (filterExpression != null) {
- expressionRule = ExpressionRule.getRule(filterExpression);
- }
- } catch (Exception e) {
- getLogger().warn("Invalid filter expression: " + filterExpression, e);
- }
-
- Class c;
- try {
- c = Class.forName(decoder);
- Object o = c.newInstance();
- if (o instanceof Decoder) {
- decoderInstance = (Decoder) o;
- }
- } catch (ClassNotFoundException | IllegalAccessException | InstantiationException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
-
- try {
- reader = new InputStreamReader(new URL(getFileURL()).openStream());
- process(reader);
- } catch (FileNotFoundException fnfe) {
- getLogger().info("file not available");
- } catch (IOException ioe) {
- getLogger().warn("unable to load file", ioe);
- return;
- }
- };
- if (useCurrentThread) {
- runnable.run();
- } else {
- Thread thread = new Thread(runnable, "LogFileXMLReceiver-" + getName());
-
- thread.start();
-
- }
- }
-
private void process(Reader unbufferedReader) throws IOException {
BufferedReader bufferedReader = new BufferedReader(unbufferedReader);
char[] content = new char[10000];
- getLogger().debug("processing starting: " + fileURL);
+ logger.debug("processing starting: " + fileURL);
int length;
do {
System.out.println("in do loop-about to process");
@@ -250,18 +199,17 @@
}
}
} while (tailing);
- getLogger().debug("processing complete: " + fileURL);
+ logger.debug("processing complete: " + fileURL);
shutdown();
}
- private void processEvents(Collection<LoggingEvent> c) {
+ private void processEvents(Collection<ChainsawLoggingEvent> c) {
if (c == null) {
return;
}
- for (Object aC : c) {
- LoggingEvent evt = (LoggingEvent) aC;
+ for (ChainsawLoggingEvent evt : c) {
if (passesExpression(evt)) {
if (evt.getProperty(Constants.HOSTNAME_KEY) != null) {
evt.setProperty(Constants.HOSTNAME_KEY, host);
@@ -269,7 +217,7 @@
if (evt.getProperty(Constants.APPLICATION_KEY) != null) {
evt.setProperty(Constants.APPLICATION_KEY, path);
}
- doPost(evt);
+ append(evt);
}
}
}
@@ -294,4 +242,59 @@
this.useCurrentThread = useCurrentThread;
}
+ @Override
+ public void start() {
+ Runnable runnable = () -> {
+ try {
+ URL url = new URL(fileURL);
+ host = url.getHost();
+ if (host != null && host.equals("")) {
+ host = FILE_KEY;
+ }
+ path = url.getPath();
+ } catch (MalformedURLException e1) {
+ // TODO Auto-generated catch block
+ e1.printStackTrace();
+ }
+
+ try {
+ if (filterExpression != null) {
+ expressionRule = ExpressionRule.getRule(filterExpression);
+ }
+ } catch (Exception e) {
+ logger.warn("Invalid filter expression: " + filterExpression, e);
+ }
+
+ Class c;
+ try {
+ c = Class.forName(decoder);
+ Object o = c.newInstance();
+ if (o instanceof Decoder) {
+ decoderInstance = (Decoder) o;
+ }
+ } catch (ClassNotFoundException | IllegalAccessException | InstantiationException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+
+ try {
+ reader = new InputStreamReader(new URL(getFileURL()).openStream());
+ process(reader);
+ } catch (FileNotFoundException fnfe) {
+ logger.info("file not available");
+ } catch (IOException ioe) {
+ logger.warn("unable to load file", ioe);
+ return;
+ }
+ };
+ if (useCurrentThread) {
+ runnable.run();
+ } else {
+ Thread thread = new Thread(runnable, "LogFileXMLReceiver-" + getName());
+
+ thread.start();
+
+ }
+ }
+
}
diff --git a/src/main/java/org/apache/log4j/xml/UtilLoggingXMLDecoder.java b/src/main/java/org/apache/log4j/xml/UtilLoggingXMLDecoder.java
index 3190b1a..519583d 100644
--- a/src/main/java/org/apache/log4j/xml/UtilLoggingXMLDecoder.java
+++ b/src/main/java/org/apache/log4j/xml/UtilLoggingXMLDecoder.java
@@ -17,12 +17,8 @@
package org.apache.log4j.xml;
-import org.apache.log4j.Level;
-import org.apache.log4j.Logger;
import org.apache.log4j.helpers.UtilLoggingLevel;
import org.apache.log4j.spi.Decoder;
-import org.apache.log4j.spi.LocationInfo;
-import org.apache.log4j.spi.LoggingEvent;
import org.apache.log4j.spi.ThrowableInformation;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
@@ -36,8 +32,12 @@
import java.awt.*;
import java.io.*;
import java.net.URL;
+import java.time.Instant;
import java.util.*;
import java.util.zip.ZipInputStream;
+import org.apache.log4j.chainsaw.logevents.ChainsawLoggingEvent;
+import org.apache.log4j.chainsaw.logevents.ChainsawLoggingEventBuilder;
+import org.apache.log4j.chainsaw.logevents.LocationInfo;
/**
@@ -80,6 +80,8 @@
*/
private Component owner = null;
+ private ChainsawLoggingEventBuilder builder = new ChainsawLoggingEventBuilder();
+
private static final String ENCODING = "UTF-8";
/**
@@ -173,7 +175,7 @@
* @return Vector of LoggingEvents
* @throws IOException if IO error during processing.
*/
- public Vector<LoggingEvent> decode(final URL url) throws IOException {
+ public Vector<ChainsawLoggingEvent> decode(final URL url) throws IOException {
LineNumberReader reader;
boolean isZipFile = url.getPath().toLowerCase().endsWith(".zip");
InputStream inputStream;
@@ -192,10 +194,10 @@
} else {
reader = new LineNumberReader(new InputStreamReader(inputStream, ENCODING));
}
- Vector<LoggingEvent> v = new Vector<>();
+ Vector<ChainsawLoggingEvent> v = new Vector<>();
String line;
- Vector<LoggingEvent> events;
+ Vector<ChainsawLoggingEvent> events;
try {
while ((line = reader.readLine()) != null) {
StringBuilder buffer = new StringBuilder(line);
@@ -227,7 +229,7 @@
* @param document to decode events from
* @return Vector of LoggingEvents
*/
- public Vector<LoggingEvent> decodeEvents(final String document) {
+ public Vector<ChainsawLoggingEvent> decodeEvents(final String document) {
if (document != null) {
@@ -279,14 +281,14 @@
* @param data XML fragment
* @return a single LoggingEvent or null
*/
- public LoggingEvent decode(final String data) {
+ public ChainsawLoggingEvent decode(final String data) {
Document document = parse(data);
if (document == null) {
return null;
}
- Vector<LoggingEvent> events = decodeEvents(document);
+ Vector<ChainsawLoggingEvent> events = decodeEvents(document);
if (events.size() > 0) {
return events.firstElement();
@@ -301,8 +303,8 @@
* @param document XML document
* @return Vector of LoggingEvents
*/
- private Vector<LoggingEvent> decodeEvents(final Document document) {
- Vector<LoggingEvent> events = new Vector<>();
+ private Vector<ChainsawLoggingEvent> decodeEvents(final Document document) {
+ Vector<ChainsawLoggingEvent> events = new Vector<>();
NodeList eventList = document.getElementsByTagName("record");
@@ -310,11 +312,11 @@
eventIndex++) {
Node eventNode = eventList.item(eventIndex);
- Logger logger = null;
+ String logger = null;
long timeStamp = 0L;
- Level level = null;
+ String level = null;
String threadName = null;
- Object message = null;
+ String message = null;
String ndc = null;
String[] exception = null;
String className = null;
@@ -336,7 +338,7 @@
String tagName = list.item(y).getNodeName();
if (tagName.equalsIgnoreCase("logger")) {
- logger = Logger.getLogger(getCData(list.item(y)));
+ logger = getCData(list.item(y));
}
if (tagName.equalsIgnoreCase("millis")) {
@@ -344,7 +346,7 @@
}
if (tagName.equalsIgnoreCase("level")) {
- level = UtilLoggingLevel.toLevel(getCData(list.item(y)));
+ level = getCData(list.item(y));
}
if (tagName.equalsIgnoreCase("thread")) {
@@ -415,9 +417,10 @@
|| (className != null)
|| (methodName != null)
|| (lineNumber != null)) {
- info = new LocationInfo(fileName, className, methodName, lineNumber);
+ info = new LocationInfo(fileName, className, methodName,
+ Integer.parseInt(lineNumber));
} else {
- info = LocationInfo.NA_LOCATION_INFO;
+ info = null;
}
ThrowableInformation throwableInfo = null;
@@ -425,15 +428,18 @@
throwableInfo = new ThrowableInformation(exception);
}
- LoggingEvent loggingEvent = new LoggingEvent(null,
- logger, timeStamp, level, message,
- threadName,
- throwableInfo,
- ndc,
- info,
- properties);
+ builder.clear();
+ builder.setLogger(logger)
+ .setTimestamp(Instant.ofEpochMilli(timeStamp))
+ .setLevelFromString(level)
+ .setMessage(message)
+ .setThreadName(threadName)
+ .setMDC(properties)
+ .setNDC(ndc)
+ .setLocationInfo(info);
- events.add(loggingEvent);
+
+ events.add(builder.create());
}
return events;
diff --git a/src/main/java/org/apache/log4j/xml/XMLDecoder.java b/src/main/java/org/apache/log4j/xml/XMLDecoder.java
index e2d034d..a747d75 100644
--- a/src/main/java/org/apache/log4j/xml/XMLDecoder.java
+++ b/src/main/java/org/apache/log4j/xml/XMLDecoder.java
@@ -17,11 +17,7 @@
package org.apache.log4j.xml;
-import org.apache.log4j.Level;
-import org.apache.log4j.Logger;
import org.apache.log4j.spi.Decoder;
-import org.apache.log4j.spi.LocationInfo;
-import org.apache.log4j.spi.LoggingEvent;
import org.apache.log4j.spi.ThrowableInformation;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
@@ -35,11 +31,16 @@
import java.awt.*;
import java.io.*;
import java.net.URL;
+import java.time.Instant;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;
import java.util.Vector;
import java.util.zip.ZipInputStream;
+import org.apache.log4j.chainsaw.logevents.ChainsawLoggingEvent;
+import org.apache.log4j.chainsaw.logevents.ChainsawLoggingEventBuilder;
+import org.apache.log4j.chainsaw.logevents.Level;
+import org.apache.log4j.chainsaw.logevents.LocationInfo;
/**
@@ -97,6 +98,8 @@
*/
private Component owner = null;
+ private ChainsawLoggingEventBuilder builder = new ChainsawLoggingEventBuilder();
+
/**
* Create new instance.
*
@@ -175,7 +178,7 @@
* @return Vector of LoggingEvents
* @throws IOException if IO error during processing.
*/
- public Vector<LoggingEvent> decode(final URL url) throws IOException {
+ public Vector<ChainsawLoggingEvent> decode(final URL url) throws IOException {
LineNumberReader reader;
boolean isZipFile = url.getPath().toLowerCase().endsWith(".zip");
InputStream inputStream;
@@ -195,10 +198,10 @@
reader = new LineNumberReader(new InputStreamReader(inputStream, ENCODING));
}
- Vector<LoggingEvent> v = new Vector<>();
+ Vector<ChainsawLoggingEvent> v = new Vector<>();
String line;
- Vector<LoggingEvent> events;
+ Vector<ChainsawLoggingEvent> events;
try {
while ((line = reader.readLine()) != null) {
StringBuilder buffer = new StringBuilder(line);
@@ -230,7 +233,7 @@
* @param document to decode events from
* @return Vector of LoggingEvents
*/
- public Vector<LoggingEvent> decodeEvents(final String document) {
+ public Vector<ChainsawLoggingEvent> decodeEvents(final String document) {
if (document != null) {
if (document.trim().equals("")) {
return null;
@@ -279,14 +282,14 @@
* @param data XML fragment
* @return a single LoggingEvent or null
*/
- public LoggingEvent decode(final String data) {
+ public ChainsawLoggingEvent decode(final String data) {
Document document = parse(data);
if (document == null) {
return null;
}
- Vector<LoggingEvent> events = decodeEvents(document);
+ Vector<ChainsawLoggingEvent> events = decodeEvents(document);
if (events.size() > 0) {
return events.firstElement();
@@ -301,14 +304,14 @@
* @param document XML document
* @return Vector of LoggingEvents
*/
- private Vector<LoggingEvent> decodeEvents(final Document document) {
- Vector<LoggingEvent> events = new Vector<>();
+ private Vector<ChainsawLoggingEvent> decodeEvents(final Document document) {
+ Vector<ChainsawLoggingEvent> events = new Vector<>();
- Logger logger;
+ String logger;
long timeStamp;
- Level level;
+ String level;
String threadName;
- Object message = null;
+ String message = null;
String ndc = null;
String[] exception = null;
String className = null;
@@ -329,9 +332,9 @@
if (eventNode.getNodeType() != Node.ELEMENT_NODE) {
continue;
}
- logger = Logger.getLogger(eventNode.getAttributes().getNamedItem("logger").getNodeValue());
+ logger = eventNode.getAttributes().getNamedItem("logger").getNodeValue();
timeStamp = Long.parseLong(eventNode.getAttributes().getNamedItem("timestamp").getNodeValue());
- level = Level.toLevel(eventNode.getAttributes().getNamedItem("level").getNodeValue());
+ level = eventNode.getAttributes().getNamedItem("level").getNodeValue();
threadName = eventNode.getAttributes().getNamedItem("thread").getNodeValue();
NodeList list = eventNode.getChildNodes();
@@ -431,25 +434,28 @@
|| (className != null)
|| (methodName != null)
|| (lineNumber != null)) {
- info = new LocationInfo(fileName, className, methodName, lineNumber);
+ info = new LocationInfo(fileName, className, methodName,
+ Integer.parseInt(lineNumber));
} else {
- info = LocationInfo.NA_LOCATION_INFO;
+ info = null;
}
ThrowableInformation throwableInfo = null;
if (exception != null) {
throwableInfo = new ThrowableInformation(exception);
}
- LoggingEvent loggingEvent = new LoggingEvent(null,
- logger, timeStamp, level, message,
- threadName,
- throwableInfo,
- ndc,
- info,
- properties);
+ builder.clear();
+ builder.setLogger(logger)
+ .setTimestamp(Instant.ofEpochMilli(timeStamp))
+ .setLevelFromString(level)
+ .setMessage(message)
+ .setThreadName(threadName)
+ .setMDC(properties)
+ .setNDC(ndc)
+ .setLocationInfo(info);
- events.add(loggingEvent);
+ events.add(builder.create());
message = null;
ndc = null;
diff --git a/src/main/resources/META-INF/services/org.apache.log4j.chainsaw.ChainsawReceiverFactory b/src/main/resources/META-INF/services/org.apache.log4j.chainsaw.ChainsawReceiverFactory
index 3ce8aa8..ea467ac 100644
--- a/src/main/resources/META-INF/services/org.apache.log4j.chainsaw.ChainsawReceiverFactory
+++ b/src/main/resources/META-INF/services/org.apache.log4j.chainsaw.ChainsawReceiverFactory
@@ -1 +1,5 @@
+org.apache.log4j.net.MulticastReceiverFactory
+org.apache.log4j.net.UDPReceiverFactory
+org.apache.log4j.net.XMLReceiverFactory
+org.apache.log4j.varia.LogFilePatternReceiverFactory
org.apache.log4j.net.JsonReceiverFactory
diff --git a/src/test/java/org/apache/log4j/xml/XMLDecoderTest.java b/src/test/java/org/apache/log4j/xml/XMLDecoderTest.java
index 59cba7f..d053723 100644
--- a/src/test/java/org/apache/log4j/xml/XMLDecoderTest.java
+++ b/src/test/java/org/apache/log4j/xml/XMLDecoderTest.java
@@ -24,6 +24,7 @@
import java.nio.CharBuffer;
import java.util.Vector;
import java.net.URL;
+import org.apache.log4j.chainsaw.logevents.ChainsawLoggingEvent;
/**
* Tests for XMLDecoder.
@@ -58,28 +59,28 @@
public void testDecodeEventsString1() throws Exception {
String xmlStr = getStringFromResource("xmlLayout.1.xml", 10000);
XMLDecoder decoder = new XMLDecoder();
- Vector<org.apache.log4j.spi.LoggingEvent> events = decoder.decodeEvents(xmlStr);
+ Vector<ChainsawLoggingEvent> events = decoder.decodeEvents(xmlStr);
assertEquals(17, events.size());
}
public void testDecodeEventsString2() throws Exception {
String xmlStr = getStringFromResource("xsltLayout.1.xml", 10000);
XMLDecoder decoder = new XMLDecoder();
- Vector<org.apache.log4j.spi.LoggingEvent> events = decoder.decodeEvents(xmlStr);
+ Vector<ChainsawLoggingEvent> events = decoder.decodeEvents(xmlStr);
assertEquals(15, events.size());
}
public void testDecodeEventsURL1() throws Exception {
URL resource = XMLDecoderTest.class.getResource("xmlLayout.1.xml");
XMLDecoder decoder = new XMLDecoder();
- Vector<org.apache.log4j.spi.LoggingEvent> events = decoder.decode(resource);
+ Vector<ChainsawLoggingEvent> events = decoder.decode(resource);
assertEquals(17, events.size());
}
public void testDecodeEventsURL2() throws Exception {
URL resource = XMLDecoderTest.class.getResource("xsltLayout.1.xml");
XMLDecoder decoder = new XMLDecoder();
- Vector<org.apache.log4j.spi.LoggingEvent> events = decoder.decode(resource);
+ Vector<ChainsawLoggingEvent> events = decoder.decode(resource);
assertEquals(15, events.size());
}