问题描述
我不知道如何在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.0
,myLog.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.
- 删除关机挂钩代码. LogManager将在关机时为您关闭任何已附加文件处理程序.
- 将
logger
更改为静态最终引用,以便不可能进行垃圾收集.这样可以确保您的设置得到保留. - 由于您使用的是JavaEE,因此请使用 javax.annotation. PostConstruct 和 javax.annotation.PreDestroy 用于管理记录器设置的注释.
- 如果手动关闭FileHandler,请确保调用 Logger :: remove(Handler),以便可以对处理程序进行垃圾收集.您当前的代码仅关闭处理程序.
- Remove the shutdown hook code. The LogManager will close any attached file handler for you on shutdown.
- Change
logger
to a static final reference so it is impossible to garbage collect. This ensures your settings are maintained. - Since you are using JavaEE use the javax.annotation.PostConstruct and javax.annotation.PreDestroy annotations to manage your logger settings.
- 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的最佳方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!