java.util.logging.Logger: приращение расширения файла после «тайм-аута» - PullRequest
0 голосов
/ 07 ноября 2018

Я использую java.util.logging.Logger и завернул его в синглтон. Таким образом, я могу получить к нему хороший доступ ко всей моей программе (также в потоках).

import java.util.logging.*;
import java.io.*;

public class LogTest 
{
   public static void init () throws Exception
   {
      LogManager.getLogManager().reset ();
   }

   public static Logger get () throws Exception
   {
     Logger l = LogManager.getLogManager ().getLogger ("test");
     if (l == null)
     {
        l = Logger.getLogger ("test");
        FileHandler fh = new FileHandler ("test.log", 100000, 1, true);
        l.addHandler (fh);
        l.setLevel (Level.parse ("INFO"));
     }
     return l;
   }
}

Я думаю, это намного лучше, чем глобальные или мимолетные ссылки.

Я вызываю LogTest.init () в самом начале моей главной страницы. Затем я вызываю LogTest.get () везде, где мне нужно для регистрации. Даже если это нить.

LogTest.get().info ("blabla");

Это работает хорошо. Но я понял, что через 1-2 минуты, когда я не печатал несколько строк в лог-файле, расширение файла увеличивается на 1.

test.log -> test.log.1 .... test.log.1 -> test.log.2

Я ожидаю, что ТОЛЬКО, если размер файла превышает максимальный (100 КБ FileHandler)

Есть идеи, если это проблема, связанная с потоками или FileHandler? Почему это поведение? Я не ожидал бы, что изменение файла журнала.

Ответы [ 2 ]

0 голосов
/ 07 ноября 2018

Причина, по которой это происходит, кроется, вероятно, здесь:

https://docs.oracle.com/javase/7/docs/api/java/util/logging/LogManager.html#getLogger(java.lang.String)

Также важно отметить, что Logger, связанный с именем String, может быть подвергнут сборке мусора в любое время, если нет строгой ссылки на Logger. Вызывающая сторона этого метода должна проверить возвращаемое значение для нуля, чтобы правильно обработать случай, когда Logger был собран мусором.

Поскольку вы не обращаетесь к регистратору в течение одной или нескольких минут и в вашем коде нет ссылки на объект регистратора, он, вероятно, собирает мусор, а когда вы позже вызываете getLogger(), он, вероятно, возвращает ноль.

Если бы у вас был правильный синглтон в качестве указателя @Mark, он не был бы сборщиком мусора.

0 голосов
/ 07 ноября 2018

Не связанный с вашим вопросом, ваш код - это скорее класс со статическими методами, чем одиночный.

С Когда синглтон не синглтон :

Singleton - это полезный шаблон проектирования, позволяющий использовать только один экземпляр вашего класса, но распространенные ошибки могут случайно допустить необходимо создать более одного экземпляра.

С вашим кодом вы все равно можете вызывать new LogTest() столько раз, сколько хотите, что позволяет создавать более one экземпляра.


Ваш код в виде синглтона будет выглядеть примерно так:

public class LogTest {

    private static LogTest theInstance;

    private LogTest() {
        LogManager.getLogManager().reset();
    }

    public static synchronized LogTest getInstance() {
        if(theInstance == null) {
            theInstance = new LogTest();
        }
        return theInstance;
    }

    public Logger getLogger() throws Exception {
        Logger l = LogManager.getLogManager().getLogger("test");
        if (l == null) {
            l = Logger.getLogger("test");
            FileHandler fh = new FileHandler("test.log", 100000, 1, true);
            l.addHandler(fh);
            l.setLevel(Level.parse("INFO"));
        }
        return l;
    }
}

Когда вы хотите его использовать:

LogTest.getInstance().getLogger().log(...);
...