Лучший способ закрыть FileHandler на REST API - PullRequest
0 голосов
/ 05 ноября 2019

Я не знаю, как обращаться с моим FileHandler на API REST

У меня установлен REST API на Weblogic, я использую Java Logging, и когда мое приложение запускается, запускает регистратор и открываетFileHandler. Как будто я никогда не закрываю FileHandler, созданный файл .lck остается в моей папке журналов. Меня действительно не волнует наличие этого файла, но когда я повторно внедряю приложение, как будто FileHandler все еще открыт, мое приложение запускает новый файл журнала (например: myLog.log.0, myLog.log.1). Я читал, что сама JVM должна закрывать FileHandler, но этого не происходит. Я пытался addShutodownHook закрыть FileHandler, но этот код не работает, если я повторно разверну приложение, оно все еще остается открытым.

@ApplicationPath("api")
public class GenericApplication extends Application {
    public GenericApplication() {
        initSwagger();
        initLog();

        Runtime.getRuntime().addShutdownHook(new Thread() {
            @Override
            public void run() {
                CtgLogger.fileJson.close();
                // fileJson is my FileHandler, i made it public static to call him here.
            }
        });
    }

Мой initLog() метод просто вызывает следующий CtgLogger.setup()...

public static void setup() throws IOException {
    Logger logger = Logger.getLogger(Logger.GLOBAL_LOGGER_NAME);
    String level = PropertiesUtil.get("ctg.log.level");
    logger.setLevel(LEVEL_MAP.get(level));

    String filePath = PropertiesUtil.get("ctg.log.path");
    String fileSize = PropertiesUtil.get("ctg.log.max.size");
    String fileCount = PropertiesUtil.get("ctg.log.max.count");
    if (StringUtils.isNotEmpty(fileSize) && StringUtils.isNotEmpty(fileSize) &&
        NumberUtils.isNumber(fileSize) && NumberUtils.isNumber(fileCount)) {
        fileJson = new FileHandler(filePath != null ? filePath : DEFAULT_LOG_NAME,
            Integer.parseInt(fileSize), Integer.parseInt(fileCount), true);
    } else {
        fileJson = new FileHandler(filePath != null ? filePath : DEFAULT_LOG_NAME);
    }
    jsonFormatter = new JsonCustomFormatter();
    fileJson.setFormatter(jsonFormatter);
    for (Handler h: logger.getHandlers())
        h.close();
    logger.addHandler(fileJson);
}

И это все, тогда я просто вызываю свои конечные точки и использую свой регистратор.

Мой вопрос заключается в том, должен ли я открывать и закрывать свой FileHandler при каждом вызове конечной точки? Или есть лучший способ сделать это?

1 Ответ

1 голос
/ 05 ноября 2019

У меня вопрос: должен ли я открывать и закрывать свой FileHandler при каждом вызове конечной точки? Или есть лучший способ сделать это?

Нет необходимости открывать и закрывать каждый раз, когда вызывается конечная точка.

  1. Удалите код ловушки отключения. При завершении работы LogManager закроет для вас любой прикрепленный обработчик файла.
  2. Измените logger на статическую конечную ссылку, чтобы невозможно собрать мусор . Это гарантирует сохранение ваших настроек.
  3. Поскольку вы используете JavaEE, используйте аннотации javax.annotation.PostConstruct и javax.annotation.PreDestroy для управления настройками регистратора.
  4. Если вы закрываете FileHandler вручную, убедитесь, что вы вызываете Logger :: remove (Handler) , чтобы обработчик мог собирать мусор. Ваш текущий код только закрывает обработчик.
    private final Logger logger = Logger.getLogger(Logger.GLOBAL_LOGGER_NAME);
    private volatile FileHandler fileJson;

    public void preDestroy() {
       Handler h = this.fileJson;
       this.fileJson = null;
       if (h != null) {
           h.close();
       }
       logger.removeHandler(h);  
    }

    @PostConstruct 
    public void setup() throws IOException {
        if (fileJson != null) {
            preDestroy();
        }

        String level = PropertiesUtil.get("ctg.log.level");
        logger.setLevel(LEVEL_MAP.get(level));

        String filePath = PropertiesUtil.get("ctg.log.path");
        String fileSize = PropertiesUtil.get("ctg.log.max.size");
        String fileCount = PropertiesUtil.get("ctg.log.max.count");
        if (StringUtils.isNotEmpty(fileSize) && StringUtils.isNotEmpty(fileSize) &&
        NumberUtils.isNumber(fileSize) && NumberUtils.isNumber(fileCount)) {
            fileJson = new FileHandler(filePath != null ? filePath : DEFAULT_LOG_NAME,
                Integer.parseInt(fileSize), Integer.parseInt(fileCount), true);
        } else {
               fileJson = new FileHandler(filePath != null ? filePath : DEFAULT_LOG_NAME);
        }
        jsonFormatter = new JsonCustomFormatter();
        fileJson.setFormatter(jsonFormatter);
        for (Handler h: logger.getHandlers()) {
            h.close();
            logger.removeHander(h);
        }
        logger.addHandler(fileJson);
    }
...