什么是正确的方法,从不同的方法关闭FileHandler

时间:2018-12-14 09:21:10

标签: java logging

目标

我目前正在使用内置的Java日志记录方法记录一些SNMP陷阱。

我的问题

问题是,我正在“记录”文件的构造函数中启动FileHandler。注意,日志记录本身是在构造函数之外的方法内部进行的。

因此,我不知道在日志发生后如何正确关闭FileHandler,因为记录器本身在构造函数中打开。 ->由此引起的错误是,我的日志记录生成了诸如“ log.txt”,log1.txt”,“ log2.txt”之类的文件...

我尝试过的事情

我试图在构造函数的底部关闭FileHandler……显然,这没有用。我也尝试从发生日志本身的方法中关闭它。这里的问题是,我无权访问该处理程序的实例。

记录器代码

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.logging.FileHandler;
import java.util.logging.Formatter;
import java.util.logging.Level;
import java.util.logging.LogRecord;
import java.util.logging.Logger;

public class Logging {
    private Logger log = Logger.getLogger(Logger.GLOBAL_LOGGER_NAME);

    public Logging() {
        Logger root = Logger.getLogger("");
        FileHandler txt = null;
        try {
            txt = new FileHandler("log.txt", true);
        }       
        catch(SecurityException | IOException e) {
            e.printStackTrace();
        }
        root.setLevel(Level.ALL);
        txt.setFormatter(new Formatter() {

            @Override
            public String format(LogRecord record) {
                String ret = "";
                /*
                if(record.getLevel().intValue() >= Level.WARNING.intValue()) {
                    ret += "Error: ";
                }
                */
                SimpleDateFormat df = new SimpleDateFormat("dd.MM.yyyy | HH:mm");
                Date d = new Date(record.getMillis());
                ret += df.format(d);

                ret += this.formatMessage(record);
                return ret;
            }
        });
        root.addHandler(txt);
    }

    public void addMessage(String message, String type) {
        if(type == "warning") {
            log.warning(message);
        }
    }
}

感谢您的帮助

2 个答案:

答案 0 :(得分:0)

尝试一下,您可以通过Examples for java.util.logging.FileHandler吗?

public synchronized static Logger getLogger(){
  if (null != logger) {
    return logger;
  }
  logger=Logger.getLogger("TokenVendingMachineLogger");
  FileHandler handler;
  try {
    handler=new FileHandler("MyLogFile.txt",true);
    SimpleFormatter formatter=new SimpleFormatter();
    handler.setFormatter(formatter);
    logger.addHandler(handler);
    logger.setLevel(Level.ALL);
  }
 catch (  SecurityException e) {
    System.err.println("Security exception while initialising logger : " + e.getMessage());
  }
catch (  IOException e) {
    System.err.println("IO exception while initialising logger : " + e.getMessage());
  }
  return logger;
}

答案 1 :(得分:0)

您不需要关闭FileHandler,如果您将它添加到Logger中,则LogManager会为您完成。

LogManager使用关闭钩子来关闭所有处理程序,这是来自openjdk的实现:

// This private class is used as a shutdown hook.
// It does a "reset" to close all open handlers.
private class Cleaner extends Thread {

    private Cleaner() {
        /* Set context class loader to null in order to avoid
         * keeping a strong reference to an application classloader.
         */
        this.setContextClassLoader(null);
    }

    @Override
    public void run() {
        // This is to ensure the LogManager.<clinit> is completed
        // before synchronized block. Otherwise deadlocks are possible.
        LogManager mgr = manager;

        // If the global handlers haven't been initialized yet, we
        // don't want to initialize them just so we can close them!
        synchronized (LogManager.this) {
            // Note that death is imminent.
            deathImminent = true;
            initializedGlobalHandlers = true;
        }

        // Do a reset to close all active handlers.
        reset();
    }
}

如果要在应用程序末尾管理文件关闭,也可以使用shutdown hook。