I have an application which is a simple networked knock-knock joke app. I incorporated some Log4J (version 2) logging into it. Here is the server class:
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.Level;
import java.net.*;
import java.io.*;
public class MessageResponseServer extends Thread /* added in the T just now*/{ /* REPLACED */
private static final Logger logger = LogManager.getLogger("MessageResponseServer");
logger.info("MessageResponseServer.java : INFO message");
public static void main(String[] args) throws IOException {
logger.debug("MessageResponseServer.java : DEBUG message");
ServerSocket serverSocket = null;
try {
serverSocket = new ServerSocket(4444);
} catch (IOException e) {
System.err.println("Could not listen on port: 4444.");
logger.fatal("MessageResponseServer.java : FATAL message - Could not listen on port: 4444.");
System.exit(1);
}
Socket clientSocket = null;
try {
clientSocket = serverSocket.accept();
logger.debug("MessageResponseServer.java : , debug message");
} catch (IOException e) {
System.err.println("Accept failed.");
System.exit(1);
}
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
BufferedReader in = new BufferedReader(
new InputStreamReader(
clientSocket.getInputStream()));
String inputLine, outputLine;
MessageResponseProtocol mrp = new MessageResponseProtocol(); /* REPLACED */
outputLine = mrp.processInput(null);
out.println(outputLine);
while ((inputLine = in.readLine()) != null) {
outputLine = mrp.processInput(inputLine);
out.println(outputLine);
if (outputLine.equals("Bye."))
logger.debug("MessageResponseServer.java : , Exiting. DEBUG Message");
break;
}
out.close();
in.close();
clientSocket.close();
serverSocket.close();
}
}
And the following is XML file:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss} [%t] %-5level %logger{36} - %msg%n"/>
</Console>
<File name="MyFile" fileName="OutputLogFile.log" immediateFlush="false" append="true">
<PatternLayout pattern="%d{yyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</File>
</Appenders>
<Loggers>
<Root level="ALL">
<Appender-Ref ref="Console"/>
<Appender-Ref ref="MyFile"/>
</Root>
</Loggers>
</Configuration>
What I'd like to do is to figure out how to make the logging a bit more useful. Do you add in special if
statements to decide whether to log something(i.e if user enters "quit" I can make a specific log on that ).
Is there perhaps a way to include performance metrics into logging? This would be really useful for me. My goal is for the code to demonstrate something that may aid in making it exhibit fail-safe features later on(i.e , perhaps we might utilize the logs to restart the Client side if it was aborted ).
thanks
Log4j is used by developers to keep track of what happens in their software applications or online services. It's basically a huge journal of the activity of a system or application. This activity is called 'logging' and it's used by developers to keep an eye out for problems for users.
Log4j allows logged messages to contain format strings that reference external information through the Java Naming and Directory Interface (JNDI). This allows information to be remotely retrieved across a variety of protocols, including the Lightweight Directory Access Protocol (LDAP).
Firstly, your code does not compile. The first logger.info() call needs to be inside a static{} block, or moved into main(); And your while() loop is going to exit first time through - you need {} brackets around the debug and break statements.
But I need to state my prejudices :)
As to metrics, you can always roll your own - e.g. time how long a back-end call takes to complete and log at info level. I don't have specific suggestions for a helpful framework, but others may.
one idea central to many of the logging frameworks is that you do NOT decide what to do in the application, but in the configuration. so, basically, your application logs everything, and your config "filters" and sends the output to the right place (i.e. different files, the syslog, or even ignoring it completely)
in general, in a development environment, you want to log more, so you might set everything to "DEBUG", while on production, you set it to "INFO".
sometimes, it might be beneficial to do a pattern such as this:
if(log.isDebug()) {
log.debug("some formatting");
}
to avoid executing the formatting (in this case) and throwing it away immediately afterwards.
your pattern layout is also a bit problematic - for example, retrieving the line number is unreliable (it basically depends on the code being compiled with debug=true) and very expensive (it has to retrieve the stacktrace and extract the line information from it).
for actual execution time metrics, you may want to look elsewhere - an excellent library that provides counters and time measurements including max, min, average etc is metrics-core:
https://dropwizard.github.io/metrics/3.1.0/manual/core/
and if you're using spring, you may want to look at my aspect based on this library:
https://github.com/rmalchow/metrics
For your application, I think what you have done is enough. you don't need more.
Debug for debugging / Error for exception and Errors. May be add an info for the start and stop server.
Now, if you have had a larger application you should do this :
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With