The problem is that the other code most likely uses a different logger. With java.util.logging you can configure the root-logger right when the application starts and the other loggers will inherit the configuration.
private static void configureRootLogger() {
try {
FileHandler fh = new FileHandler("MyLogFile.log");
fh.setFormatter(new SimpleFormatter());
Logger.getLogger("").addHandler(fh);
} catch (IOException e) {
// handle exception
}
}
Full example:
import java.io.IOException;
import java.util.logging.FileHandler;
import java.util.logging.Logger;
import java.util.logging.SimpleFormatter;
public class LogToFileExample {
private static final Logger logger = Logger.getLogger("MyLogA");
public static void main(String[] args) {
configureRootLogger();
logger.info("local test message");
final LogTester tester = new LogTester();
tester.logMessage();
}
private static void configureRootLogger() {
try {
FileHandler fh = new FileHandler("MyLogFile.log");
fh.setFormatter(new SimpleFormatter());
Logger.getLogger("").addHandler(fh);
} catch (IOException e) {
logger.warning("Could not add handler to log to file");
}
}
}
import java.util.logging.Logger;
public class LogTester {
private static final Logger logger = Logger.getLogger("MyLogB");
public void logMessage() {
logger.info("external log message");
}
}
Identical output in file and console:
May 28, 2021 9:44:50 AM org.testing.LogToFileExample main
INFO: local test message
May 28, 2021 9:44:50 AM org.testing.LogTester logMessage
INFO: external log message
Answer from Matt on Stack OverflowThe problem is that the other code most likely uses a different logger. With java.util.logging you can configure the root-logger right when the application starts and the other loggers will inherit the configuration.
private static void configureRootLogger() {
try {
FileHandler fh = new FileHandler("MyLogFile.log");
fh.setFormatter(new SimpleFormatter());
Logger.getLogger("").addHandler(fh);
} catch (IOException e) {
// handle exception
}
}
Full example:
import java.io.IOException;
import java.util.logging.FileHandler;
import java.util.logging.Logger;
import java.util.logging.SimpleFormatter;
public class LogToFileExample {
private static final Logger logger = Logger.getLogger("MyLogA");
public static void main(String[] args) {
configureRootLogger();
logger.info("local test message");
final LogTester tester = new LogTester();
tester.logMessage();
}
private static void configureRootLogger() {
try {
FileHandler fh = new FileHandler("MyLogFile.log");
fh.setFormatter(new SimpleFormatter());
Logger.getLogger("").addHandler(fh);
} catch (IOException e) {
logger.warning("Could not add handler to log to file");
}
}
}
import java.util.logging.Logger;
public class LogTester {
private static final Logger logger = Logger.getLogger("MyLogB");
public void logMessage() {
logger.info("external log message");
}
}
Identical output in file and console:
May 28, 2021 9:44:50 AM org.testing.LogToFileExample main
INFO: local test message
May 28, 2021 9:44:50 AM org.testing.LogTester logMessage
INFO: external log message
Instead of using the statement e.printStackTrace(), let try a statement like this logger.log(Level.ALL, e.getMessage(), e) in your catch blocks.
For example,
import java.util.logging.Level;
import java.util.logging.Logger;
...
catch (SecurityException e) {
logger.log(Level.ALL, e.getMessage(), e);
}
catch (IOException e) {
logger.log(Level.ALL, e.getMessage(), e);
}
You also can try Log4J
java - how to print log.info message in log file - Stack Overflow
A guide to logging in Java
docker-java: How to get container logs?
How can I turn off logging in SBT Test?
Videos
See this short introduction to log4j.
The issue is in using System.out to print debugging or diagnostic information. It is a bad practice because you cannot easily change log levels, turn it off, customize it, etc.
However if you are legitimately using System.out to print information to the user, then you can ignore this warning.
If you are using System.out|err.println(..) to print out user-information on console in your application's main()-method, you do nothing wrong. You can get rid of the message via inserting a comment "//NOPMD".
System.out.println("Fair use of System.out.println(..).");// NOPMD
There is a "Mark as reviewed"-Option in the PMD-Violations Outline for this purpose.
Of course you can trick PMD with following code snippet:
PrintStream out=System.out;
out.println("I am fooling PMD.");
Outside of your main()-Method use a Log-System like eg Log4j.
UPDATE:
You can also modify the PMD-Rule "SystemPrintln" to use the following XPath:
//MethodDeclaration[@MethodName!="main"]//Name[
starts-with(@Image, 'System.out.print')
or
starts-with(@Image, 'System.err.print')
] | //Initializer//Name[
starts-with(@Image, 'System.out.print')
or
starts-with(@Image, 'System.err.print')
]
This will ignore System.out.println etc in any method named 'main' in your code, but check for System.out.println in initializer code. I like this, because from my point of view, System.out.println is safe in method 'main(String args[])'. But use with caution, I have to check, where in the AST a System.out.println can occur also and have to adapt the XPath.