Logging in AppEngine - java

I've having issues getting logging set up properly on my development app server (launched from Eclipse). I have the correct logging.properties location in my appengine-web.xml, and the most global parameter is working:
.level=ALL
If I change that to INFO everything quiets down and all is good. But trying to add any sort of override for my packages appears to do nothing at all:
.level=ALL
com.company.level=INFO
(I am using my real package name, using the above as an example)
When I try to a full package path such as com.company.user.level or even a class name such as com.company.user.User.level I still get no change. I've also tried moving my entry above and below the .level statement with no luck. As a last resort I tried taking out .level altogether, but that resulted in no change to my custom class logging.
Between each change I fully stop and restart the development appserver to make sure the file is re-read. Again, if I change .level I see a change in logging level output, but nothing else works. I'm stumped? Any suggestions?
AppEngine SDK: 1.9.17 (1.9.18 is the latest as of this writing but there is nothing to indicate this would be fixed in the change logs).
Thanks!!
UPDATE (Solution)
Thanks to #farrellmr below!!
I was doing the following:
private static final Logger log = Logger.getLogger("MyClass"); // wrong
When I should have been doing:
private static final Logger log = Logger.getLogger(MyClass.class.getName()); // correct

You need to define your logger as -
package test;
private static final Logger LOGGER = Logger.getLogger(MyClass.class.getName());
Then you can define your package log configuration as -
test.level = INFO

Related

log4j ConsoleAppender printing to console twice even after setting Additivity to false

I have log4j appenders that print outputs to the console once when running the program in intellIj
but twice when running the program via executable .jar.
The actual logs that get written to the log file only appear once which is correct.
I define my logger/appenders programmatically in this code block
and after everything is done I call
rootLogger.setAdditivity(false);
but for some reason my classes still output twice to cmdline console when running as a .jar. I call loggers in each class by defining a log variable at the top like so:
public class SomeClass {
static Logger log = Logger.getLogger(SomeClass .class);
and this log variable is used everywhere in the "SomeClass" class.
I've tried setting additivity to false for all the package loggers as well before and after I set their levels...
Logger.getLogger("com.company").setAdditivity(false);
Logger.getLogger("com.company.project.database.Admin").setAdditivity(false);
...
but when I run the code that way it complains it cannot find the appenders for the class that I'm defining all the log4j stuff in, and nothing gets written to output/log.
I think you are on the right track with additivity, however additivity is a property of a child, telling log4j not to use the parents:
https://logging.apache.org/log4net/release/sdk/html/P_log4net_Repository_Hierarchy_Logger_Additivity.htm
You have set additivity to false for the ultimate parent logger, that will never do anything as root will not be a child of anything.
Try setting the additivity to false of each package logger and hopefully that will solve the issue.

How to use custom log4j.properties file for private logging?

I need to periodically append text messages to a text file and I'm wanting to piggyback on log4j to make life easy. So I've created a "mylog.properties" file with a DailyRollingFileAppender -- nothing unusual -- and I've put that file in my src/java/resources directory. So now I'm ready to create a logger from this file and start logging with it, something like this:
class MyClass {
private static final Logger myLog = getLoggerConfiguredFromPropertiesFile("mylog.properties");
public void logSomething(String message) {
myLog.info(message);
}
}
So what would be the logic for getLoggerConfiguredFromPropertiesFile?
Thanks,
Alvaro
Doing:
private static final Logger myLog = Logger.getLogger(MyClass.class)
should get the job done. log4j automatically looks for the closest log4j.properties to the class, and if you only have one in the project, it's that one. Also, call your file log4j.properties, not mylog.properties.
I came up with a workaround where I'm using the regular logger:
private static final Logger myLog = LoggerFactory.getLogger(MyClass.class);
And in the log4j.properties, I configure a custom DailyRollingFileAppender that works just for my class, as explained here.

How do I programmatically create a folder that is to hold a final static log file, in Java

I have a final static logger object, this is created when the main method is first executed. If the log file is not there it is created and then appended to (using the log4j API, appender). However I want to check that the machine that the application is run on has the directory created that the application is due to save into.
The problem is that this folder check/creation needs to happen before the log is created and the log is created on class instantiation. I s there a standard way to deal with this issue, I want to avoid re-placing all the logging statements so keeping the logger static is preferable?
You can use a static initializer to achieve this:
public class Foo {
static {
//check the directory
//initialize the logger
}
}
This static initalizer will run when the class is loaded. So there you can check if the directory exists before you actually create the logger.

Two logs for one class

I'm working on jdk 1.6 and I have a class that needs to log to 2 different log files using log4j. I have read many other answers, but I can't get mine to work the way I want it. This is my log4j properties.
log4j.debug=false
log4j.rootLogger=ERROR, appLog
log4j.logger.com.my.apps.idm.transactionalemail=DEBUG, appLog, infoLog
log4j.appender.appLog=org.apache.log4j.DailyRollingFileAppender
log4j.appender.appLog.File=/opt/apps/logs/${ni.cluster}/TransactionalEmail/1.0/TransactionalEmail.log
log4j.appender.appLog.DatePattern='.'yyyy-MM-dd
log4j.appender.appLog.layout=org.apache.log4j.PatternLayout
log4j.appender.appLog.layout.ConversionPattern=DATE: %d{DATE}%nPRIORITY: %p%nCATEGORY: %c%nTHREAD: %t%nNDC: %x%nMESSAGE:%m%n%n
log4j.appender.infoLog=org.apache.log4j.DailyRollingFileAppender
log4j.appender.infoLog.File=/opt/apps/logs/${ni.cluster}/TransactionalEmail/1.0/Info.log
log4j.appender.infoLog.DatePattern='.'yyyy-MM-dd
log4j.appender.infoLog.layout=org.apache.log4j.PatternLayout
log4j.appender.infoLog.layout.ConversionPattern=DATE: %d{DATE}%nPRIORITY: %p%nCATEGORY: %c%nTHREAD: %t%nNDC: %x%nMESSAGE:%m%n%n
And the way I want this to work is like this
public class MyClass{
private static final LOG = Logger.getLogger("appLog");
private static final INFO_LOG = Logger.getLogger("infoLog");
public void myMethod(){
INFO_LOG.debug("This is info");
LOG.debug("This is debug");
}
}
What happens when I run my app is that the Info.log has the same information as TransactionalEmail.log, and also, the line "This is a test" doesn't show up in either of the log files.
What am I doing wrong?
I would recommend against using multiple logger instances for classes. Utilize log4j's configuration to handle logging events as they are generated. You may want to look at the Routing File Appender to decide how log events are handled. From the link
The RoutingAppender evaluates LogEvents and then routes them to a subordinate Appender. The target Appender may be an appender previously configured and may be referenced by its name or the Appender can be dynamically created as needed. The RoutingAppender should be configured after any Appenders it references to allow it to shut down properly.

Change log level of project with single call?

I have configured the log level in properties to DEBUG and works fine, but i want to change the log level of whole project if some event occurs.Apparently my project has many classes and they use the logging like below
private static final Logger log = Logger.getLogger(CommandOperations.class);
I am able to change the log level individually for each class by calling log.setLevel(Level.INFO) but I rather want project wide change. How to do it?
Try Logger.getLogger("com.xx").setLevel(..); where com.xx is the package prefix to all your classes. Do not set levels for individual classes.
When you give com.xx it will be applicable to all subpackages also.
Have you tried using?
LogManager.getRootLogger().setLevel((Level)Level.DEBUG);

Categories