Программная проблема с журналированием Java - PullRequest
0 голосов
/ 03 марта 2019

У нас есть собственная утилита для интеграции между продуктами, использующими java.util.logging.У нас есть XML-файл конфигурации, который утилита считывает и программно устанавливает протоколирование при запуске (xml также имеет другие конфигурации для утилиты).Во время работы, если пользователь изменяет уровень ведения журнала, WatchService обнаруживает его и устанавливает уровень.Вот код, который выполняет ведение журнала:

        Level level = Level.parse(logConfig.getLogOutput().getLogOutputLevel());
        if(!isLoggingInitialized)
        {
                int maxSize = fileLog.getMaxFileSize() * 1000000;
                Logger maneClient = Logger.getLogger("com.raytheon.mane.client");

                String path = fileLog.getLogFileOutputPath();
                File f = new File(path);
                if(!Files.exists(f.toPath().getParent()))
                {
                    try
                    {
                        Files.createDirectories(f.toPath().getParent());
                    }
                    catch(IOException ioe)
                    {
                        throw new MANEClientException("Unable to create logging directory: " + ioe.getMessage(), ioe);
                    }
                }
                FileHandler fileHander = new FileHandler(fileLog.getLogFileOutputPath(), maxSize, fileLog.getMaxBackupIndex().intValue(), true);
                fileHander.setFormatter(new SimpleFormatter());
                fileHander.setLevel(level);
                maneClient.addHandler(fileHander);
                maneClient.setUseParentHandlers(false);

                isLoggingInitialized = true;
        }
        else
        {
                Logger maneClient = Logger.getLogger("com.raytheon.mane.client");
                Arrays.asList(maneClient.getHandlers()).forEach(h -> h.setLevel(level));
        }

(мы используем JAXB, который я не включил в анализ этих объектов)

В нашей среде разработки это ведение журнала работает должным образом.Если я запускаю приложение с помощью Level.OFF, создается файл журнала (включая .lck), но ничего не пишется.Как только я изменяю конфигурацию xml на FINE, я получаю ожидаемое ведение журнала.Так что это замечательно.

Однако в нашей тестовой лаборатории, если я установлю Level.OFF, а затем изменю его, регистрация не будет вестись, пока мы не остановим службу, запускающую приложение, и в этот момент все записи будут выглядеть как всето, что должно было произойти, сбрасывается в файл.
Если я запускаю приложение с помощью Level.FINE, оно регистрируется, затем переключается на Level.OFF, регистрация прекращается, но если я переключаюсь обратно на Level.FINE или Level.INFO,регистрация не происходит, пока служба не остановлена.

Единственное различие между средами, которое я вижу, - это ОС.Среда разработки работает на Open JDK 11 с Win 7 Prof. Сервер в тестовой среде работает на Open JDK 11 с Win Server 8 (да, я знаю. Мы проводим обновление в этом году).

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

Спасибо!

1 Ответ

0 голосов
/ 04 марта 2019

Если я запускаю приложение с помощью Level.OFF, файл журнала создается (включая .lck), но ничего не записывается.

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

Если я запускаю приложение с помощью Level.FINE, оно регистрируется, затем переключается на Level.OFF,ведение журнала останавливается, но если я переключаюсь обратно на Level.FINE или Level.INFO, регистрация не происходит до тех пор, пока служба не будет остановлена.

Убедитесь, что у вас есть сильная ссылка на "com.raytheon.mane.client "logger.В вашем коде вы используете только локальные ссылки метода.Вам нужна хотя бы одна статическая окончательная ссылка на этот регистратор, чтобы предотвратить сборку мусора .

Также Windows будет задерживать запись байтов на диск (синхронизация против сброса) .Поведение, которое вы описываете, будет соответствовать FileHandler.close выполняет синхронизацию при завершении работы.В настоящее время единственный способ заставить FileHandler выполнить синхронизацию - это закрыть или повернуть.Возможно, вы просто не записали в журнал достаточно данных для синхронизации Windows с диском?

...