本文介绍了在REST API上关闭FileHandler的最佳方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不知道如何在API REST上处理FileHandler

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

我在Weblogic上安装了REST API,正在使用Java日志记录,当我的应用程序启动时,将启动记录器,然后打开FileHandler.就像我从不关闭FileHandler一样,创建的.lck文件位于我的日志文件夹中.我真的不在乎该文件的存在,但是当我重新部署该应用程序时(如FileHandler仍处于打开状态),我的应用程序将启动一个新的日志文件(例如:myLog.log.0myLog.log.1).我已经读过JVM本身应该关闭FileHandler,但是那没有发生.我试图addShutodownHook关闭FileHandler,但是该代码无法正常工作,如果我重新部署该应用程序,它仍然保持打开状态.

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

我的initLog()方法仅调用下一个CtgLogger.setup() ...

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.

我的问题是,是否应该在每次调用端点时打开和关闭FileHandler?还是有更好的方法来做到这一点?

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. 删除关机挂钩代码. LogManager将在关机时为您关闭任何已附加文件处理程序.
  2. logger更改为静态最终引用,以便不可能进行垃圾收集.这样可以确保您的设置得到保留.
  3. 由于您使用的是JavaEE,因此请使用 javax.annotation. PostConstruct javax.annotation.PreDestroy 用于管理记录器设置的注释.
  4. 如果手动关闭FileHandler,请确保调用 Logger :: remove(Handler),以便可以对处理程序进行垃圾收集.您当前的代码仅关闭处理程序.
  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);
    }

这篇关于在REST API上关闭FileHandler的最佳方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-27 01:08