Подтвердить что ты не робот

Как настроить java.util.logging на Android?

Я хочу использовать java.util.logging на Android. Я хочу настроить систему ведения журнала с помощью logging.properties. Но как я могу сказать Android с помощью конкретного файла конфигурации? Например, я поместил logging.properties в корневой каталог пути приложения. Как Android знает местоположение logging.properties.

Спасибо

4b9b3361

Ответ 1

Это теперь FAQ для одного из моих проектов, надеюсь, что больше людей найдут это здесь: java.util.logging отлично работает на Android. Пожалуйста, не используйте что-либо еще в своем коде, фреймворки регистрации как вредитель в мире Java.

Что нарушено, это обработчик регистрации по умолчанию, поставляемый с Android, он игнорирует любые сообщения журнала с уровнем более тонким, чем INFO. Вы не видите сообщения DEBUG и т.д.

Причиной является вызов Log.isLoggable() в AndroidHandler.java:

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

Вот как вы его исправите:

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 >= 1000) {
            return Log.ERROR;
        } else if (value >= 900) {
            return Log.WARN;
        } else if (value >= 800) {
            return Log.INFO;
        } else {
            return Log.DEBUG;
        }
    }
}

В основном коде активности/инициализации вашего приложения:

@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: Да, вы можете использовать некоторые магические свойства или команду оболочки adb или даже узнать, как глупый встроенный обработчик ведения журнала DalvikLogging.loggerNameToTag преобразует имена категорий в теги (которые вы нужно было бы сделать для этих магических свойств и команд оболочки), но зачем беспокоиться? Достаточно ли достаточно регистрации?

Ответ 2

Обычно используется android.util.Log для входа на Android. Существуют некоторые ключевые преимущества использования этого регистратора, такие как возможность использования adb logcat для просмотра вывода журнала, отправленного в эти журналы.

Вы можете попробовать поставить logging.properties в assets/ или res/raw/. Если Android не выбирает их там, можно использовать java.util.logging.LogManager. readConfiguration(java.io.InputStream), чтобы принудительно загрузить его. (Вы можете использовать классы Ресурсы и AssetManager, чтобы получить файл как InputStream).

Ответ 3

По крайней мере, на Android 4.3 с неизменным обработчиком, если вы используете

adb shell setprop log.tag.YOURTAG DEBUG

Вы можете видеть сообщения, записанные до уровня Level.FINE в logcat. Я не выяснил способ регистрации более высоких уровней, но этого достаточно для меня.

Ответ 4

В случае, если один из вас хочет только перенаправить вывод java.util.logging из сторонних библиотек, это может быть достигнуто довольно легко с помощью SLF4J и jul-to -slf4j bridge. Это работает для операторов FINE и FINEST журнала BTW.

Здесь зависимость maven

<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>jul-to-slf4j</artifactId>
    <version>${slf4j.version}</version>
</dependency>

Чтобы загрузить его, поместите следующее в свой Application класс, Roboguice Модуль или где-то еще, где он будет выполнен до вашего первого журнал. (Настройка этого параметра в assets/logging.properties, похоже, не работает, к сожалению).

/*
 * add SLF4JBridgeHandler to j.u.l root logger, should be done once
 * during the initialization phase of your application
 */
SLF4JBridgeHandler.install();

Вы можете либо

  • настройте все свои операторы журнала из assets/logback.xml (используя logback-android). См. здесь для отображения уровней журнала.

  • или просто используйте SLF4J-android для пересылки операторов журнала в logcat. Для этого просто поставьте следующую зависимость для вашего пути к классам, не требуется дальнейшая конфигурация:

    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-android</artifactId>
        <version>${slf4j.version}</version>
    </dependency>
    

Я успешно реализовал это с помощью

<properties>
    <slf4j.version>1.7.6</slf4j.version>
</properties>

Примечание:

  • Внимательно прочитайте часть документа jul-to-slf4j, который относится к производительности!
  • Если вы используете LogcatAppender, имейте в виду, что сообщения журнала JUL (кроме тех, у которых уровень более тонкий, чем INFO) маршрутизируются на logcat с помощью android. Поэтому не забудьте применить соответствующие фильтры, чтобы избежать дублирования.