How to configure java.util.logging on Android?

android logger app
custom logger class in android
log e java
android wtf log
android console logs
how to create log file in android application
android event log example
android studio device log

I want to use java.util.logging on Android. I want to configure the logging system with logging.properties. But how can I tell Android using the specific configure file? For example, I placed the logging.properties in the classpath root of the application. How Android knows the location of logging.properties.

Thanks

This is now an FAQ for one of my projects, hopefully more people will find this here: java.util.logging works fine on Android. Please don't use anything else in your code, logging frameworks are like a pest in the Java world.

What is broken is the default logging handler shipped with Android, it ignores any log messages with level finer than INFO. You don't see DEBUG etc. messages.

The reason is the call to Log.isLoggable() in AndroidHandler.java:

https://github.com/android/platform_frameworks_base/blob/master/core/java/com/android/internal/logging/AndroidHandler.java

Here is how you fix it:

import android.util.Log;
import java.util.logging.*;

/**
 * Make JUL work on Android.
 */
public class AndroidLoggingHandler extends Handler {

    public static void reset(Handler rootHandler) {
        Logger rootLogger = LogManager.getLogManager().getLogger("");
        Handler[] handlers = rootLogger.getHandlers();
        for (Handler handler : handlers) {
            rootLogger.removeHandler(handler);
        }
        rootLogger.addHandler(rootHandler);
    }

    @Override
    public void close() {
    }

    @Override
    public void flush() {
    }

    @Override
    public void publish(LogRecord record) {
        if (!super.isLoggable(record))
            return;

        String name = record.getLoggerName();
        int maxLength = 30;
        String tag = name.length() > maxLength ? name.substring(name.length() - maxLength) : name;

        try {
            int level = getAndroidLevel(record.getLevel());
            Log.println(level, tag, record.getMessage());
            if (record.getThrown() != null) {
                Log.println(level, tag, Log.getStackTraceString(record.getThrown()));
            }
        } catch (RuntimeException e) {
            Log.e("AndroidLoggingHandler", "Error logging message.", e);
        }
    }

    static int getAndroidLevel(Level level) {
        int value = level.intValue();

        if (value >= Level.SEVERE.intValue()) {
            return Log.ERROR;
        } else if (value >= Level.WARNING.intValue()) {
            return Log.WARN;
        } else if (value >= Level.INFO.intValue()) {
            return Log.INFO;
        } else {
            return Log.DEBUG;
        }
    }
}

In the main activity/initialization code of your application:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    AndroidLoggingHandler.reset(new AndroidLoggingHandler());
    java.util.logging.Logger.getLogger("my.category").setLevel(Level.FINEST);
...

TL;DR: Yes, you could use some magic properties, or adb shell command, or even learn how the stupid built-in logging handler's DalvikLogging.loggerNameToTag converts category names to tags (which you would have to do for those magic properties and shell commands), but why bother? Isn't logging painful enough?

java.util.logging, Static control enables field service staff to set up a particular configuration and then re-launch the application with the new logging settings. Questions: I want to use java.util.logging on Android. I want to configure the logging system with logging.properties. But how can I tell Android using the specific configure file? For example, I placed the logging.properties in the classpath root of the application. How Android knows the location of logging.properties.

Generally one uses android.util.Log for logging on Android. There are some key advantages to using that logger, such as being able to use adb logcat to view logging output sent to those logs.

You can try put logging.properties in assets/ or res/raw/. If Android doesn't pick those up there, then one can use java.util.logging.LogManager.readConfiguration(java.io.InputStream) to force load it. (You can use the Resources and AssetManager classes to get the file as an InputStream).

Logger, https://developer.android.com › reference › java › util › logging › LogMa You can use a Java class to configure the Java Logging API. You do so by specifying the name of the class in the JVM parameter java.util.logging.config.class. It is the constructor of that class that should load the configuration and apply it to the Logger 's in the hierarchy.

At least on Android 4.3, with unchanged Handler, if you use

adb shell setprop log.tag.YOURTAG DEBUG

You can see messages logged with up to Level.FINE in logcat. I haven't figured out a way to log higher levels, but that's sufficient for me.

LogManager, util.logging.config.file" system property can be used to specify a properties file (in java.util.Properties format). The initial logging configuration  To use java.util.logging as the slf4j backend, you must have slf4j-jdk14-mumle.jar from the slf4j distribution on your classpath, and do the magic listed in the javadoc to enable it. If not you will have a runtime error saying there is no slf4j implementation active.

Here is modified answer of Christian Bauer

If somewhere in any third party lib you will see something like this:

   final public class AnyClass {        
        private static final Logger logger = Logger.getLogger(AnyClass.class.getName());
         ...
            if (logger.isLoggable(Level.FINE)) {
                logger.fine("any log event");
            }
         ...
     }

Add to your code this after creating first instance of AnyClass.class:

SetupLogger.setup(Arrays.asList(
                new Pair<>(AnyClass.class.getName(), Level.FINEST),//AnyClass.class.getName() is because instance `logger` has his name
                new Pair<>(AnyOther.class.getName(), Level.FINEST)
        ));

SetupLogger .class

public class SetupLogger {

    static public void setup(List<Pair<String, Level>> loggerNames) {
        // suppress the logging output to the console
        AndroidLoggingHandler rootHandler = new AndroidLoggingHandler();
        AndroidLoggingHandler.reset(rootHandler );
        for (Pair<String, Level> pair : loggerNames) {
            Logger logger = Logger.getLogger(pair.first);
            logger.setLevel(pair.second);
        }
    }
}

Level, java.util.logging.Level. The Level class defines a set of standard logging levels that can be used to control logging output. The logging Level  The Android development tools provide the BuildConfig.DEBUG flag for this purpose. This flag will be automatically set to false if you export the Android application for deployment. During development it will be set to true , therefore allowing you to see your logging statements during development.

Handler, java.lang.Object. ↳, java.util.logging.Handler Check if this Handler would actually log a given LogRecord. abstract void, publish(LogRecord  java.util.logging keeps you from having to tote one more jar file around with your application, and it works well with a good Formatter. In general, at the top of every class , you should have: private static final Logger LOGGER = Logger.getLogger( ClassName.class.getName() );

Java Logging API - Tutorial, java.util.logging.LogManager is the class that reads the logging configuration, create and maintains the logger instances. We can use this class to set our own  I am having lots of logging statements to debug for example. Log.v(TAG, "Message here"); Log.w(TAG, " WARNING HERE"); while deploying this application on device phone i want to turn off the verbose

Logger in Java - Java Logging Example, However, you can specify your own configuration file by setting the java.util.​logging.config.file property when running a Java program. This lets you create and  Teams. Q&A for Work. Stack Overflow for Teams is a private, secure spot for you and your coworkers to find and share information.

Java Logging Basics |, Best Java code snippets using java.util.logging. Removes the standard Android log handler due to an issue with not logging * entries lower than INFO level 

Comments
  • By Android lifecycle, the best place to invoke this handler is onCreate() from a subclass of Application, and declare this class on manifest file. Because if for some reason the main Activity doesn't appear (from a share, service, etc) the code still run.
  • @Renascienza no, you can't. Because at start of Application you will set level Level.FINEST , but when at first time you will call instance of MyClass private static final Logger logger it will have level == Level.INFO
  • Thank you very much. This approach does well. Now I have to struggle to write log to sdcard.
  • @tangjie not sure what your final goal is, but I would consider buffering logs in your app and then send them to a server where you actually have access to
  • It works but for me log messages with levels finer than INFO were not shown with adb logcat (slf4j 1.7.21).