I have been told by one of my senior that write log statements for two levels , debug and info is wrong , what is wrong with this approach ?
if(LOGGER.isDebugEnabled()){
LOGGER.info("REST SERVICE LOG :QUERY GENERATED FOR ADVANCED SEARCH IS : \n" +queryBuffer );
}
if(LOGGER.isEnabledFor(Level.INFO)){
LOGGER.info("REST SERVICE LOG :QUERY GENERATED FOR ADVANCED SEARCH IS : \n" +queryBuffer );
}
Any suggestions on this please ?
In your example: (Assuming your LOGGER is using one of the standard java logging frameworks)
If LOGGER is configured for TRACE or DEBUG, then the same information will be logged twice.
"REST SERVICE LOG :QUERY GENERATED FOR ADVANCED SEARCH IS :
<query buffer>"
"REST SERVICE LOG :QUERY GENERATED FOR ADVANCED SEARCH IS :
<query buffer>"
That seems wasteful.
If LOGGER is configured for INFO, then the information will be logged once.
"REST SERVICE LOG :QUERY GENERATED FOR ADVANCED SEARCH IS :
<query buffer>"
If LOGGER is configured for a level like ERROR or FATAL, then no information will be logged.
What is your goal for logging here?
Related
I am trying to enable logging for the below class in Confluence:
https://bitbucket.org/mryall/confluence-siteminder-authenticator/src/142de32b6be86321c9791df5dfced607314ed17d/src/main/java/com/atlassian/confluence/authenticator/siteminder/SiteMinderAuthenticator.java?at=default&fileviewer=file-view-default&_ga=2.161258619.735769127.1516003521-2111736425.1515526840
E.g. I know this line:
#SuppressWarnings("unchecked")
public Principal getUser(final HttpServletRequest request, HttpServletResponse response) {
log.info("Starting SiteMinder Authentication for: {}", request.getRequestURI());
Principal loggedInUser = getUserFromSession(request);
if (loggedInUser != null) {
log.debug("{} is already logged in.", loggedInUser.getName());
return loggedInUser;
}
is executed but nothing is written to catalina.out. In log4j.properties I have:
log4j.rootLogger=DEBUG, confluencelog, errorlog
log4j.appender.confluencelog=com.atlassian.confluence.logging.ConfluenceHomeLogAppender
Any ideas why nothing is printed to catalina.out from the above class?
Confluence manual says:
In order to unify logging across different application servers, Confluence uses the atlassian-confluence.log as its primary log, not the application server log.
Once the initial startup sequence is complete, all logging will be to <confluence-home>/logs/atlassian-confluence.log. For example: c:/confluence/data/logs/atlassian-confluence.log.
So look for your entries from that file, not catalina.out.
Your rootLogger level is WARN. It doesn't print lower level logs like INFO, DEBUG
You can set it to DEBUG which covers INFO level.
log4j.rootLogger=DEBUG, confluencelog, errorlog
But it will print a lot including these two.
>log.info("Starting SiteMinder Authentication for: {}", request.getRequestURI());,
>log.debug("{} is already logged in.", loggedInUser.getName());
The best solution is to set package log level to DEBUG. You can add a line into your log4j.properties
log4j.logger.com.atlassian.confluence.authenticator.siteminder=DEBUG, confluencelog
In SLF4J (Logging) how levels are different in characteristic. i.e. How ERROR message is different than DEBUG message.
import org.apache.log4j.Logger;
public class LogClass {
private static org.apache.log4j.Logger log = Logger.getLogger(LogClass.class);
public static void main(String[] args) {
log.trace("Trace Message!")
log.debug("Debug Message!");
log.info("Info Message!");
log.warn("Warn Message!");
log.error("Error Message!");
log.fatal("Fatal Message!");
}
}
The Output is same regardless of Level, is there any difference in implementation:
Debug Message!
Info Message!
Warn Message!
Error Message!
Fatal Message!
If these levels are producing the same kind of messages then why the implementation didn't have only one method with parameter as level.
Something like:
log("Level","msg");
Starting from the bottom, there's no real benefit to have a log(level, msg) method if you already have all the different methods for all the possible levels. Only if you'd need to log the same message in different levels, but that's a bad practice, since that message should clearly fall into one specific category. And you can always choose how much logging you get out by specifying the level globally or at the package/class.
The message are exactly the same on each level, the only difference is if that message is gonna make to the logging output or not, based on your configuration, and what purpose do you give to each level.
The key purpose to name them levels is to enable you to debug at various levels. Say for example,
INFO level can used to log high level information on the progress of the application during execution.
DEBUG level logged is meant to be even deeper than just high level information. At DEBUG level, you can have more information logged that can include information of what is happening at a module level or component level.
TRACE level is even more granular. You can log message like entering and exiting a method and what information is being returned by each method.
ERROR level is to purely meant to log only errors and exception
You need to be mindful of what kind of message can be logged into their respective level.
To answer your question, these levels can be controlled in log4j.properties or log4j.xml. You can specify at what level the application can debug. If everything goes well in application, I would leave it at INFO level. If something goes wrong and I wanted to dig in deepeur in terms of debugging, I would try to turn on at DEBUG level or TRACE level.
Also, understand that when you run the debugging at DEBUG level, even the INFO level logs will be printed. If you turn on the debugged at TRACE level, even the DEBUG and INFO level logs will be printed. If you turn on debugging at INFO level, only INFO level logs will be printed.
I hope you got some clarify.
Because it is easier to use for you as a user. As the implementation, it might have that very code.
We have a webserver and multiple users log in to it. We generally put log level to ERROR or INFO level. But sometimes, for debugging purpose, we need to see logs. There is one way to set it at runtime, but this process is not so good in case of loads of traffic. Important logs will be missed and also we don't know for how much time we need to keep it that way. I have written a wrapper in log4j v1.2, which just ignores the level check if userid belongs to some TestUsersList. So, it opens all logs for a particular user[a thread] only. A snippet is below-
public void trace(Object message) {
Object diagValue = MDC.get(LoggerConstants.IS_ANALYZER_NUMBER);
if (valueToMatch.equals(diagValue)) { // Some condition to check test number
forcedLog(FQCN, Level.TRACE, message, null);
return;
}
if (repository.isDisabled(Level.TRACE_INT))
return;
if (Level.TRACE.isGreaterOrEqual(this.getEffectiveLevel()))
forcedLog(FQCN, Level.TRACE, message, null);
}
But now I have moved to log4j2, I don't want to write this wrapper again. Is there any inbuilt functionality which log4j2 provides for this?
This can be done with filters. Add a logger to the configuration that logs all the messages you want, then add a ThreadContextMapFilter that has a KeyValuePair for each user you want to log.
Then put the user ids in the Thread Context within the code.
Google App Engine Java uses java.util.logging to create logging messages. I want to modify the log messages, that are displayed in Developers Console - Monitoring - Logs. The idea is to add some additional output like username without putting it in each log message manually:
log.info("user action");
should result in an logging output like
user "testuser": user action
Therefore I created an own Formatter:
public class TestFormatter extends Formatter {
#Override
public String format(LogRecord record) {
// find out username..
return "user " + username + ": " + record.getMessage();
}
}
Setting this as formatter for the ConsoleHandler in the logging.properties has not effekt:
java.util.logging.ConsoleHandler.formatter = com.example.guestbook.TestFormatter
When deploying it in on the local machine, and trying to add it programmatically like this:
Logger rootLogger = Logger.getLogger("");
Handler[] handlers = rootLogger.getHandlers();
log.info("Handler[] size: " + handlers.length);
for(Handler h : handlers) {
log.info(h.toString());
h.setFormatter(new TestFormatter());
}
I get 2 handler, one ConsoleHandler and one DevLogHandler. But setting the formatter results in the fact that no further logs are displayed. On GAE instead I get 0 handler.
When trying to acces Logger.getGlobal() instead of Logger.getLogger(""), I get 0 Handler on the local instance and a SecurityException: No permission to modify global on GAE. This exception already arises when trying to get the list of Handlers.
Now my question: Is there a way to modify the logs of developer console in such a way? If yes, how?
As I reply I got in the past from a Google ticket I opened for a similar question
I would discourage tampering with the Loggers/Handlers used
internally by GAE.
Besides that, the Global Logger cannot be customized, you can try to it with a Logger with a custom name
I want to debug a few of my application JDBC queries so I wanted to configure java.util.logging to dump the actual SELECT statements that were run against the database and the data bound to their parameters.
I already have java.util.logging configured to log other messages to file. The setup code is as folloing:
Handler fh = new FileHandler("file.log", true);
Logger logger = Logger.getLogger("");
fh.setFormatter(new GruposLogFormatter());
logger.addHandler(fh);
logger.setLevel(Level.ALL);
logger.info("==================================");
So, how can I configure java.util.logging to log JDBC queries to a file or sysout?
This answer barely touches the subject, but didn't help me.
If you are using Hibernate following configurations can be done to get the sql queries printed.
How to print a query string with parameter values when using Hibernate
You can use http://sourceforge.net/projects/p6spy/ also and intercept all queries and log them to a file