Best way for closing FileHandler on REST API's

久未见 提交于 2019-12-13 02:59:28

问题


I don't know how to handle my FileHandler on API REST

I have a REST API installed at Weblogic, I'm using Java Logging and when my app starts, inits the logger, and open the FileHandler. Like i never close the FileHandler the .lck file that is created stays at my logs folder. I really don't care the presence of that file, but when i redeploy the app, like the FileHandler is still open, my app starts a new log file (ex: myLog.log.0, myLog.log.1). I have read that JVM itself should be closing FileHandler but that is not happening. I have tried to addShutodownHook for closing FileHandler, but that code is not working, if I redeploy the app, it still stays open.

@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.
            }
        });
    }

My initLog() method just calls the next 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);
}

And that's all, then I just call my endpoints and use my logger.

My question is, should I open and close my FileHandler each time a endpoint is called? Or is there a better way for doing this?


回答1:


My question is, should I open and close my FileHandler each time a endpoint is called? Or is there a better way for doing this?

No need to open and close every time the endpoint is called.

  1. Remove the shutdown hook code. The LogManager will close any attached file handler for you on shutdown.
  2. Change logger to a static final reference so it is impossible to garbage collect. This ensures your settings are maintained.
  3. Since you are using JavaEE use the javax.annotation.PostConstruct and javax.annotation.PreDestroy annotations to manage your logger settings.
  4. If you close a FileHandler manually, make sure you call Logger::remove(Handler) so that handler can be garbage collected. You current code only closes the 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);
    }


来源:https://stackoverflow.com/questions/58711944/best-way-for-closing-filehandler-on-rest-apis

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!