Закройте файлы журналов

Этот проект мне передали, поэтому я мало о нем знаю. Существует метод, в котором используется журнал (java.util.logging.Logger), и он создает два файла журнала:

Первый файл: fileName.log

Второй файл: fileName.log.lck

В Linux, когда я делаю lsof, я вижу эти два файла как открытые. Как мне закрыть эти два файла?

Причина, по которой я хочу закрыть эти файлы, заключается в том, что этот метод запускается несколько раз в день, и через пару недель количество открытых файлов достигает предела (около 1000), после чего наша система перестает работать. Когда мы перезапускаем наш процесс («Контроллер заданий», который ведет журнал), количество открытых файлов журнала становится равным 0, и он снова работает.

Это то, что было сделано для ведения журнала

private static Logger log = Logger.getLogger(MyClass.class.getPackage().getName());
try{
    log.logp(Level.SEVERE, "com.MyClass", "run", "It failed");
}

Это то, что я пытался сделать, чтобы закрыть файлы в блоке finally, но это не сработало.

finally{
    Handler[] handler =   log.getHandlers();
    for(Handler h: handler){
        h.close();
    }
}

person Susie    schedule 11.10.2012    source источник
comment
почему вы хотите закрыть эти файлы?   -  person jdevelop    schedule 12.10.2012
comment
Закрытие этих файлов, вероятно, вызовет у вас проблемы ..   -  person Brendan Long    schedule 12.10.2012
comment
Происходит то, что через пару недель, когда количество открытых файлов достигает определенного предела (я думаю, около 1000), наша система просто дает сбой. Поэтому, когда мы перезапускаем процесс (Контроллер заданий), количество открытых файлов возвращается к 0, и все работает. Вместо того, чтобы периодически перезапускать процесс вручную, мы хотим, чтобы наш код делал это.   -  person Susie    schedule 12.10.2012
comment
@BrendanLong, мой босс считает, что проблема вызвана количеством открытых файлов журналов. Как вы думаете, почему закрытие этих файлов вызовет проблемы?   -  person Susie    schedule 12.10.2012
comment
Каковы имена файлов? Есть по одному на каждый день? Я не знаю, почему приложение может держать так много открытых одновременно для типичного ведения журнала. Если посмотреть на спецификацию Java и исходный код OpenJDK, close () должен работать, но выдает ошибку, если вы попытаетесь снова что-то зарегистрировать позже.   -  person Steve    schedule 12.10.2012
comment
Не похоже, что закрытие двух файлов решит проблему превышения лимита открытых файлов. Или, как говорит Стив, эти два файла открываются и остаются открытыми каждый день?   -  person andrunix    schedule 12.10.2012
comment
Я не думаю, что здесь твоя проблема. В большинстве приложений одновременно может быть открыта только пара файлов журнала. Я бы поискал в вашем приложении другие случаи, когда вы не закрываете файлы (или даже не освобождаете их ссылки, поскольку файлы в конечном итоге должны быть очищены, даже если вы не забыли вызвать close()). Если вам действительно нужно открыть несколько файлов, можно увеличить лимит.   -  person Brendan Long    schedule 12.10.2012
comment
Фактическое имя файла журнала - JobController_runId_0.log и JobController_runId_0.log.lck ... (runId - некоторое число) несколько заданий выполняются каждый день, поэтому каждый раз, когда задание выполняется, оно создает файлы журнала.   -  person Susie    schedule 12.10.2012
comment
@BrendanLong Каждый раз, когда я запускаю задание (или процесс), создается два файла журнала, и количество файлов продолжает расти. Эти файлы журналов появляются, когда я делаю lsof   -  person Susie    schedule 12.10.2012
comment
@andrunix: в конце недели количество открытых файлов журнала достигает более 1000, и именно тогда происходит сбой системы.   -  person Susie    schedule 12.10.2012
comment
Так что же не сработало с вашим finally блоком? Кажется, это правильный способ сделать это. Вы получаете сообщение об ошибке или просто не закрываете файлы?   -  person Brendan Long    schedule 12.10.2012
comment
@BrendanLong Я не получаю ошибку, просто файлы не закрываются. Я подсчитываю количество открытых файлов до и после запуска процесса для подтверждения.   -  person Susie    schedule 12.10.2012
comment
Согласно ответам на этот вопрос JUL не очень хорошо справляется с обработкой нескольких выходных файлов. Возможно, стоит изучить Log4j или logback, чтобы увидеть, лучше ли они справляются с этим.   -  person Brendan Long    schedule 12.10.2012


Ответы (2)


Первое решение

Если вы не хотите изменять свой код, используйте: Как отправить java.util.logging в log4j? java.util.logging.Logger to Logback с помощью SLF4J?

Я использую log4j или вернуться обратно. Оба имеют приложение Rolling File (старые файлы удаляются) или приложение Date / Time File.

Второе решение

Для ведения журнала лучше всего использовать файл прокрутки.

String filePattern = " fileName%.log";
int limit = 1000 * 1000; // 1 Mb
int numLogFiles = 3;
FileHandler fh = new FileHandler(filePattern, limit, numLogFiles);

// Add to logger
Logger logger = Logger.getLogger(MyClass.class.getPackage().getName());
logger.addHandler(fh);

Не знаю, можно ли добавить глобальный обработчик файлов.

person Andrzej Jozwik    schedule 12.10.2012

Я просто использую:

LogManager.getLogManager().reset();

это отменит все ваши настройки журнала (путь к файлу журнала, шаблон имени файла, средство форматирования ...), но он перестанет использовать регистратор, закройте файл блокировки и освободите регистратор для

person Shaybc    schedule 09.04.2014
comment
Это очень простой способ! Спасибо! - person Nori; 26.10.2018