如何使用 java.util.logging.Logger 创建每天后自动生成的回滚日志?

How to create a Rollback log which generates automatically after each day using java.util.logging.Logger?

我正在使用以下代码根据我的要求创建自定义日志。

但是无法获得回滚功能,因为java.util.logging.Logger不支持它。

我可以实施哪些选项?

是否可以使用同一个库自动生成回滚日志?

代码:

private static class MyCustomFormatterforUpdate extends java.util.logging.Formatter {

    @Override
    public String format(LogRecord record) {
        StringBuffer sb = new StringBuffer();
        sb.append("update ApiStatistics set RespDateTime =");
        sb.append(record.getMessage());
        sb.append(";");
        sb.append("\n");
        return sb.toString();
    }

}

java.util.logging.Logger updatefile = java.util.logging.Logger.getLogger("Update Script");
boolean appendu = false;
FileHandler fhu;

{
    try {
        fhu = new FileHandler("src/main/resources/updatescript.log",appendu);
        updatefile.addHandler(fhu);
        fhu.setFormatter(new MyCustomFormatterforUpdate());
    } catch (IOException e) {
        e.printStackTrace();
    }
}

一个建议是请使用其他具有许多功能的日志记录框架 而不是 java.util.logging.Logger

有用的链接

  1. configure-log4j-for-creating-daily-rolling-log-files
  2. log4j-formatting-examples
  3. a-guide-to-logging-in-java

的基础上,您只需构建该答案中推断的代理实现。这个想法是安装一个代理处理程序,它允许您打开和关闭 FileHandler 对象。这启用了您需要的轮换。下面是工作示例,它将在日期更改时轮换。包含测试用例,默认情况下输出将出现在主文件夹中。

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.util.Calendar;
import java.util.logging.ErrorManager;
import java.util.logging.FileHandler;
import java.util.logging.Filter;
import java.util.logging.Formatter;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.LogManager;
import java.util.logging.LogRecord;
import java.util.logging.SimpleFormatter;
import java.util.logging.XMLFormatter;

public class DailyFileHandler extends Handler {
    
    public static void main(String[] args) throws IOException {
        DailyFileHandler dfh = new DailyFileHandler();
        try {
            dfh.setFormatter(new SimpleFormatter());
            LogRecord r1 = new LogRecord(Level.SEVERE, "test 1");
            LogRecord r2 = new LogRecord(Level.SEVERE, "test 2");
            r2.setMillis(r1.getMillis() + (24L * 60L * 60L * 1000L));
            dfh.publish(r1);
            dfh.publish(r2);
            
        } finally {
            dfh.close();
        }
    }
    
    private Calendar current = Calendar.getInstance();
    private FileHandler target;
    
    public DailyFileHandler() throws IOException {
        target = new FileHandler(pattern(), limit(), count(), false);
        init();
    }
    
    public DailyFileHandler(String pattern, int limit, int count)
            throws IOException {
        target = new FileHandler(pattern, limit, count, false);
        init();
    }
    
    private void init() {
        super.setLevel(level());
        super.setFormatter(formatter());
        super.setFilter(filter());
        try {
            super.setEncoding(encoding());
        } catch (UnsupportedEncodingException impossible) {
            throw new AssertionError(impossible);
        }
        initTarget();
    }
    
    private void initTarget() {
        target.setErrorManager(super.getErrorManager());
        target.setLevel(super.getLevel());
        target.setFormatter(super.getFormatter());
        target.setFilter(super.getFilter());
        try {
            target.setEncoding(super.getEncoding());
        } catch (UnsupportedEncodingException impossible) {
            throw new AssertionError(impossible);
        }
    }
    
    private void rotate() {
        String pattern = pattern();
        int count = count();
        int limit = limit();
        try {
            super.setErrorManager(target.getErrorManager());
            target.close();
            
            FileHandler rotate = new FileHandler(pattern, 0, count, false);
            rotate.setFormatter(new SimpleFormatter()); //empty tail.
            rotate.close();
            
            current = Calendar.getInstance();
            target = new FileHandler(pattern, limit, count, true);
            initTarget();
        } catch (RuntimeException | IOException e) {
            this.reportError("", e, ErrorManager.OPEN_FAILURE);
        }
    }
    
    private boolean shouldRotate(long millis) {
        Calendar cal = Calendar.getInstance();
        cal.setTimeInMillis(millis);
        return cal.get(Calendar.DAY_OF_YEAR) != current.get(Calendar.DAY_OF_YEAR);
    }

    @Override
    public synchronized void publish(LogRecord record) {
        if (shouldRotate(record.getMillis())) {
            rotate();
        }
        target.publish(record);
    }

    @Override
    public synchronized void close() throws SecurityException {
        target.close();
    }

    @Override
    public synchronized void setEncoding(String encoding) throws SecurityException, UnsupportedEncodingException {
        target.setEncoding(encoding);
        super.setEncoding(encoding);
    }

    @Override
    public synchronized boolean isLoggable(LogRecord record) {
        return target.isLoggable(record);
    }

    @Override
    public synchronized void flush() {
        target.flush();
    }

    @Override
    public synchronized void setFormatter(Formatter newFormatter) {
        target.setFormatter(newFormatter);
        super.setFormatter(newFormatter);
    }

    @Override
    public synchronized Formatter getFormatter() {
        return target.getFormatter();
    }

    @Override
    public synchronized String getEncoding() {
        return target.getEncoding();
    }

    @Override
    public synchronized void setFilter(Filter newFilter) throws SecurityException {
        target.setFilter(newFilter);
        super.setFilter(newFilter);
    }

    @Override
    public synchronized Filter getFilter() {
        return target.getFilter();
    }

    @Override
    public synchronized void setErrorManager(ErrorManager em) {
        target.setErrorManager(em);
        super.setErrorManager(em);
    }

    @Override
    public synchronized ErrorManager getErrorManager() {
        return target.getErrorManager();
    }

    @Override
    public synchronized void setLevel(Level newLevel) throws SecurityException {
        target.setLevel(newLevel);
        super.setLevel(newLevel);
    }

    @Override
    public synchronized Level getLevel() {
        return target.getLevel();
    }

    private String pattern() {
        LogManager m = LogManager.getLogManager();
        String p = getClass().getName();
        String pattern = m.getProperty(p + ".pattern");
        if (pattern == null) {
            pattern = "%h/java%u.log";
        }
        return pattern;
    }
    
    private int limit() {
        LogManager m = LogManager.getLogManager();
        String p = getClass().getName();
        String v = m.getProperty(p + ".limit");
        int limit = v == null ? Integer.MAX_VALUE : Integer.parseInt(v);
        return limit;
    }
    
    private int count() {
        LogManager m = LogManager.getLogManager();
        String p = getClass().getName();
        String v = m.getProperty(p + ".count");
        int limit = v == null ? 7 : Integer.parseInt(v);
        return limit;
    }
    
    private Level level() {
        LogManager m = LogManager.getLogManager();
        String p = getClass().getName();
        String v = m.getProperty(p + ".level");
        if (v != null) {
            try {
                return Level.parse(v);
            } catch (Exception e) {
                this.reportError(v, e, ErrorManager.OPEN_FAILURE);
            }
        }
        return Level.ALL;
    }
    
    private Formatter formatter() {
        LogManager m = LogManager.getLogManager();
        String p = getClass().getName();
        String v = m.getProperty(p + ".formatter");
        if (v != null) {
            try {
                return Formatter.class.cast(Class.forName(v).newInstance());
            } catch (Exception e) {
                this.reportError("", e, ErrorManager.OPEN_FAILURE);
            }
        }
        return new XMLFormatter();
    }
    
    private Filter filter() {
        LogManager m = LogManager.getLogManager();
        String p = getClass().getName();
        String v = m.getProperty(p + ".filter");
        if (v != null) {
            try {
                return Filter.class.cast(Class.forName(v).newInstance());
            } catch (Exception e) {
                this.reportError("", e, ErrorManager.OPEN_FAILURE);
            }
        }
        return null;
    }
    
    private String encoding() {
        LogManager m = LogManager.getLogManager();
        String p = getClass().getName();
        String v = m.getProperty(p + ".encoding");
        if (v != null) {
            try {
                return Charset.forName(v).name();
            } catch (Exception e) {
                this.reportError(v, e, ErrorManager.OPEN_FAILURE);
            }
        }
        return null;
    }
}