I'm trying to set up a log4j2 SecureTcpSocketServer that will receive logs from a remote application (logging with log4j2). I've already prototyped this using the TcpSocketServer, which can be run from the command line by providing a port number and configuration file. The SecureTcpSocketServer however requires additional information to construct, such as a 'LogEventBridge' object and a 'SslConfiguration' object. I don't see how I could provide these objects to the command line so I decided to write a Java program to initialize and run the server. Here is my code:
public class log4j2SocketServer {
public static void main(String[] args) {
KeyStoreConfiguration keyStoreConf = null;
TrustStoreConfiguration trustStoreConf = null;
SecureTcpSocketServer<ObjectInputStream> myServer = null;
try {
keyStoreConf = new KeyStoreConfiguration("keystore.jks", "password", null, null);
} catch (StoreConfigurationException e) {
e.printStackTrace();
}
try {
trustStoreConf = new TrustStoreConfiguration("keystore.jks", "password", null, null);
} catch (StoreConfigurationException e) {
e.printStackTrace();
}
SslConfiguration sslConf = SslConfiguration.createSSLConfiguration("SSL", keyStoreConf, trustStoreConf);
try {
myServer = new SecureTcpSocketServer<ObjectInputStream>(5514,new ObjectInputStreamLogEventBridge(),sslConf);
} catch (IOException e) {
e.printStackTrace();
}
while(true){}
}
}
Using this code, the server seems to start up and listen on port 5514 (I used netstat to verify). On the client side, my log4j2 application seems to connect, but I don't see any of the logs coming through. Here is my client code:
Xml Configuration file:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="remoteLogging" packages="">
<Appenders>
<Socket name="socket" host="xx.xx.xx.xx" port="5514">
<SerializedLayout />
<SSL>
<KeyStore location="keystore.jks" password="password"/>
<TrustStore location="keystore.jks" password="password"/>
</SSL>
</Socket>
</Appenders>
<Loggers>
<Root level="error">
<AppenderRef ref="socket"/>
</Root>
</Loggers>
</Configuration>
Here is my Java code:
public class remoteLogging {
static final Logger log = LogManager.getLogger(remoteLogging.class.getName());
public static void main(String[] args) {
log.debug("Hello this is a debug message");
log.info("Hello this is an info message");
log.warn("Hello this is a warn message");
log.error("Hello this is a error message");
}
}
My primary concern is the way I wrote my server code. When I started writing the code, I figured all I'd need to do is instantiate a SecureTcpSocketServer. I did this, and then (obviously) the program ran, and then...ended, and garbage collected my server. So then I decided to put a infinite loop in right afterwards, to keep the server alive. I seriously doubt this is the proper way to do this, but I'm fairly new to coding and I'm not sure what the best approach is. My question is, is this implementation okay? I mean there's obviously something going wrong, since I'm not receiving logs...Is this loop causing problems? Or is there something else wrong that I haven't considered?
One more thing: I would expect my client application to run, connect to the server and send its logs, and then terminate. Right now, it seems to connect, but no logs seem to be sent, and then it just hangs until I manually terminate it. This makes me think the server-side infinite loop is interfering somehow?
Looking at the source for SecureTcpSocketServer and its superclass TcpSocketServer, I think just constructing an instance is not enough to start the server. You need to call its run() method to get it to start accepting connections.
In your log4j2SocketServer class, replace while(true){} with myServer.run();. This method will block until active is set to false or until the serverSocket is closed.
Related
I am working on a Java library with some services based on xmpp. For XMPP communication, I use Smack version 4.3.4. The development has so far been without problems and I have also created some test routines that can all be run without errors. After I migrated to a Maven project to generate a FatJar, I wanted to convert the executable test cases into JUnit tests. Unexpectedly, an error occurs, the reason of which I cannot explain. As I said, the code can be run outside of JUnit without any problems.
Below is the simplified test code (establishing a connection to the xmpp server):
#Test
public void connect()
{
Builder builder = XMPPTCPConnectionConfiguration.builder();
builder.setSecurityMode(SecurityMode.disabled);
builder.setUsernameAndPassword("iec61850client", "iec61850client");
builder.setPort(5222);
builder.setSendPresence(true);
try
{
builder.setXmppDomain("127.0.0.1");
builder.setHostAddress(InetAddress.getByName("127.0.0.1"));
}
catch (Exception e)
{
e.printStackTrace();
}
XMPPTCPConnectionConfiguration config = builder.build();
XMPPTCPConnection c = new XMPPTCPConnection(config);
c.setReplyTimeout(5000);
try
{
c.connect().login();
}
catch (Exception e)
{
e.printStackTrace();
}
}
And here is the error message I get:
Exception in thread "Smack Reader (0)" java.lang.AssertionError
at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader.parsePackets(XMPPTCPConnection.java:1154)
at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader.access$1000(XMPPTCPConnection.java:1092)
at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader$1.run(XMPPTCPConnection.java:1112)
In Smack it boils down to this 'assert' instruction:
assert (config.getXMPPServiceDomain().equals(reportedServerDomain));
Any idea what the problem might be or similar problems? I'm grateful for any help!
Thanks a lot,
Markus
If you look at the source code you will find that reportedServerDomain is extracted from the server's stream open tag. In this case the xmpp domain reported by the server does not match the one that is configured. This should usually not happen, but I assume it is related to the way you run the unit tests. Or more precisely, related to the remote server or mocked server that is used in the tests. If you enable smack's debug output, you will see the stream open tag and the 'from' attribute and its value. Compare this with the configured XMPP service domain in the ConnectionConfiguration.
I'm trying to send the logs from a basic java maven project to fluent-bit configured on a remote machine. Fluent-bit would then write them to a file. This is my basic java configuration.
Java
private final static Logger logger = LoggerFactory.getLogger(App.class);
public static void main(String[] args) {
for (int i = 0; ; i++) {
logger.debug("Warn msg");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// do nothing now
}
}
}
And the logback.xml
<appender name="fluentd" class="ch.qos.logback.more.appenders.DataFluentAppender">
<remoteHost>xx.xxx.xxx.xxx</remoteHost>
<port>7777</port>
<encoder>
<pattern>%message%n</pattern>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="fluentd" />
</root>
Fluent-bit configuration :
td-agent-bit.conf
[INPUT]
Name tcp
Listen xx.xxx.xxx.xxx
Port 7777
Parsers_File /etc/td-agent-bit/parsers.conf
Parser custom_parser
[OUTPUT]
Name file
Match *
Path /home/td-agent-bit/output.txt
parsers.conf
[PARSER]
Name custom_parser
Format regex
Regex .*
I keep getting the following exception when the app runs
[2018/09/27 08:29:13] [trace] [in_tcp] read()=74 pre_len=370 now_len=444
[2018/09/27 08:29:13] [debug] [in_serial] invalid JSON message, skipping
But when I try testing the configuration via the command line it works
echo '{"key 1": 10, "key 2": "YYY"}' | nc xx.xxx.xxx.xxx 7777
I don't get any exception and the output file has all permissions. Also the remote machine is a photon-os based system.
Any ideas would be much appreciated.
So after some research and a ticket I opened here, I found out that I was using the wrong plugin.
All java configurations were correct. Just needed to make the following change to the td-agent-bit.conf
[INPUT]
Name forward
Listen xx.xxx.xxx.xxx
Port 7777
We need to use the forward plugin instead of the tcp plugin. This plugin would listen to any incoming messages on the 7777 port and redirect it to the file.
Note that TCP Input plugin only accept JSON maps as records and not msgpack as forward protocol does.
I'm currently learning Java by developing a tool for creating and filling out multiple-choice-forms client-side and saving aswell as evaluating them server-side. I used a code skeleton from a RMI Tutorial for the network-part and it was working fine until just now. Both the client and the server application are in the same package but run as seperate applications. For easier developing they're both running on the same system right now, although this will change when things are done.
So let's cut to the chase with some code and what exactly goes wrong:
Server.java
Server() throws RemoteException {
super();
}
public static void main(String[] args) {
try {
LocateRegistry.createRegistry(Registry.REGISTRY_PORT);
}
catch (RemoteException ex) {
System.out.println("SERVER: " + ex.getMessage());
}
try {
Naming.rebind("Server", new Server()); <---
}
catch(MalformedURLException ex) {
System.out.println("SERVER: " + ex.getMessage());
}
catch(RemoteException ex) {
System.out.println("SERVER: " + ex.getMessage());
}
}
[...] methods that are called by the client via ServerInterface
The <--- marks where the Client-GUI is started.
Client.java
private static Gui_loadSets gui_loadSets = new Gui_loadSets();
public static void main(String[] args) {
loadGuiLoadSets();
}
This is where the first GUI is turned visible; the one to choose a form to load from. This GUI is loaded by starting the server EVEN IF I COMMENT THIS OUT. So the Server doesn't really load the Client-App, but instead somehow magically accesses it's GUI and showing it for no reason.
I already tried "stepping into" the line before the GUI is loaded, but I end up in an infinite loop eventually, so I really have no idea what is going an.
This is my first question here, so please forgive me if I missed out anything obvious.
Thanks for your help in advance. If you need any more code I'd be happy to supply, but most of the remaining code is all about the multiple-choice-forms.
Naming.rebind() needs a URL, not just a service name. It should be
Naming.rebind("rmi://localhost/Server", new Server());
But I'm puzzled by your comment on this line. The --> doesn't 'mark where the Client-GUI is started', it marks the line where the remote object is constructed, exported, and bound into the Registry. The client GUI is at the client.
Thanks for your effort, I got it working now.
A very basic class the server was creating an object from was referring to a method provided by the client. So apparently this caused the problem. I must've forgotten about it, since it was in there since the beginning but somehow just now started to turn out to be a visible problem.
I'm sorry for any inconvenience my bad design has caused you. :)
Also, how do I mark this problem as solved without being frowned upon? Do people attach importance to getting the accepted-answer-button? I can't do this on comments I believe.
I'm trying to use gwt-log on my gwt application but I can't get any log message from this library( I don't know where should I found them) I have added these configuration to my gwt.xml file
<inherits name="com.allen_sauer.gwt.log.gwt-log-DEBUG" />
<extend-property name="log_level" values="DEBUG"/>
<set-property name="log_level" value="DEBUG"/>
<set-property name="log_DivLogger" value="DISABLED" />
and I have modified my entry point class as follows:
public void onModuleLoad() {
Log.setUncaughtExceptionHandler();
DeferredCommand.addCommand(new Command() {
public void execute() {
onModuleLoad2();
}
});
}
private void onModuleLoad2() {
if (!Log.isLoggingEnabled()) {
Window.alert("Logging is disabled. No log messages will appears.");
}
Log.trace("This is a 'TRACE' test message");
Log.debug("This is a 'DEBUG' test message");
Log.info("This is a 'INFO' test message");
Log.warn("This is a 'WARN' test message");
Log.error("This is a 'ERROR' test message");
Log.fatal("This is a 'FATAL' test message");
}
and I can get these messages printed on console but the problem is that I can't get any other message printed either in server side or in client side,So is there something I'm missing?
Thanks
You should be able to see them in the development console (Jetty container wrap), in hosted mode. You can find a log of all HTTP traffic + gwt logs for a specific "host".
I'm not exactly sure how you can forward them to write to an external destination for production mode, though you should be able.
Make sure you setup the required servlet in web.xml.
As a side note, if you are using GWT 2.1 or higher, you can start using the new Logging framework, which emulates Java's built-in logging framework.
I'm trying to call a web service with a Java client. The WSDL looks like this: http://pastebin.com/m13124ba
My client:
public class Client{
public static void main(java.lang.String args[]){
try{
CompileAndExecuteServiceInterfaceStub stub =
new CompileAndExecuteServiceInterfaceStub
("http://192.168.1.3:8080/axis2/services/CompileAndExecuteServiceInterface");
Compile comp = new Compile();
comp.setArgs0("Test");
comp.setArgs1("public class Test { public static void main(String[] args) { System.out.println(\"Hello\");}}");
String[] classpath = {};
comp.setArgs2(classpath);
stub.compile(comp);
} catch(Exception e){
e.printStackTrace();
}
}
}
When I run the client now the following error occurs:
org.apache.axis2.AxisFault: unknown
at org.apache.axis2.util.Utils.getInboundFaultFromMessageContext(Utils.java:517)
at org.apache.axis2.description.OutInAxisOperationClient.handleResponse(OutInAxisOperation.java:371)
at org.apache.axis2.description.OutInAxisOperationClient.send(OutInAxisOperation.java:417)
at org.apache.axis2.description.OutInAxisOperationClient.executeImpl(OutInAxisOperation.java:229)
at org.apache.axis2.client.OperationClient.execute(OperationClient.java:165)
at de.dax.compileandexecuteclient.CompileAndExecuteServiceInterfaceStub.compile(CompileAndExecuteServiceInterfaceStub.java:184)
at de.dax.compileandexecuteclient.Client.main(Client.java:17)</blockquote>
I tried out the business logic of the server on my local machine and there it works. The service creates files and folders. Are web services allowed to do that? I also wrote a simple "Hello World" web service and deployed it to the server. This worked fine.
When you get one of these "unknown" AxisFaults, definitely check the server log! The client-side stack trace most likely will not be detailed enough for you to track down the error.
I believe dax is indicating above that he found the NullPointerException in the more-detailed server side stack trace. It would look something like:
org.apache.axis2.AxisFault
at org.apache.axis2.AxisFault.makeFault(AxisFault.java:430)
[....]
Caused by: java.lang.NullPointerException
[....]
From the provided logs, I cannot determine what's wrong. Try to set the log-level of Axis2 to "debug" (see the two log-configurations in the root directory of your Axis2 installation) and check the details for the exact cause. Axis2 tends to be a bit sparse in propagating the errors coming from webservices.
The problem was that there was an NullPointerException in my service.