java.util.logging 将记录器分配给特定包

java.util.logging assign logger to a specific package

我实现了两个自定义处理程序来记录 DB 上的信息和一个额外的平面文件(DBHandler 和 MyFileHandler)。这个新的日志处理程序将由特定包上的单个 class 使用。 我只将两个新的记录器附加到一个特定的包中。 我的想法是在特定包上的 classes contaiend 的这两个处理程序(文件和数据库)之间切换,但目前使用当前配置我无法做到这一点,所以我要么在那里记录两个处理程序根本没有日志。 我尝试将数据库处理程序的日志级别设置为关闭,但它仍在数据库上正常记录。

配置文件下面是使用logging.properties

############################################################
#####   Global properties
############################################################

handlers= java.util.logging.FileHandler, java.util.logging.ConsoleHandler, com.test.logging.DBHandler, com.test.logging.MyFileHandler

.level = INFO

############################################################
# Handler specific properties.
# Describes specific configuration info for Handlers.
############################################################

    java.util.logging.FileHandler.level = ALL
    java.util.logging.FileHandler.pattern = %t/CLog%g.log
    java.util.logging.FileHandler.limit = 50000
    java.util.logging.FileHandler.count = 1
    java.util.logging.FileHandler.formatter = java.util.logging.SimpleFormatter

    java.util.logging.ConsoleHandler.level = ALL
    java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter

    com.test.logging.MyFileHandler.level = ALL
    com.test.logging.MyFileHandler.pattern = %t/custLog%g.log
    com.test.logging.MyFileHandler.limit = 50000
    com.test.logging.MyFileHandler.count = 1
    com.test.logging.MyFileHandler.formatter = java.util.logging.SimpleFormatter

    com.test.logging.DBHandler.level=OFF

    com.test.ccb.mon.handlers=com.test.logging.DBHandler, com.test.logging.MyFileHandler

使用记录器跟踪信息的class低于

package com.test.ccb.mon;
    public class Utils {

    public static final Logger logger = Logger.getLogger(Utils.class.getCanonicalName());

public void logging()
{

 //processing
   logger.info("message);

}

}

DBHandler class:

public class DBHandler extends Handler {

    @Override
    public void close() throws SecurityException {

    }

    @Override
    public void flush() {


    }

    @Override
    public void publish(LogRecord logRecord) {
        if (isLoggable(logRecord))
        {

            try {
                      //SQL call to insert onDB
            } catch (Exception e) {
                e.printStackTrace();
            } 
        }

    }

}

我的文件处理程序class:

public class MyFileHandler extends FileHandler{

        public MyileHandler() throws IOException, SecurityException {
            super();
        }

        @Override
        public void close() throws SecurityException {
            super.close();

        }

        @Override
        public void flush() {
            super.flush();

        }

        @Override
        public void publish(LogRecord record) {
            super.publish(record);
        }

    }

重现你的问题对我来说不是那么容易。使用与您类似的处理程序 classes,对配置文件的更改具有预期的效果。使用 DBHandler.level=OFF 设置,我缺少数据库处理程序输出:

Aug 11, 2015 1:47:26 PM com.test.ccb.mon.Utils logging
DBHandler.publish - handler level: OFF; log record level: INFO
INFO: message
MyFileHandler - message

Logging handlers:
###java.util.logging.FileHandler-ALL
###java.util.logging.ConsoleHandler-ALL
###com.test.logging.DBHandler-OFF
###com.test.logging.MyFileHandler-ALL

用于打印日志记录处理程序的调试代码现在也包含在 Utils class 的以下 main 方法中。你可以自己运行这种方法,看看这种读取配置文件的方式是否更适合你:

public static void main(final String[] arguments) throws IOException
{
    final String fileName = "logging.properties";
    final InputStream propertiesStream = Utils.class.getResourceAsStream(fileName);
    //final InputStream propertiesStream = new FileInputStream("path to file");
    LogManager.getLogManager().readConfiguration(propertiesStream);

    new Utils().logging();
    System.out.println();

    // No handlers for this logger directly, but four for its parent.
    System.out.println("Logging handlers:");
    for (final Handler handler : logger.getParent().getHandlers())
        System.out.println("###" + handler.getClass().getName()
                           + "-" + handler.getLevel());
}

您的 DBHandler class 的一个非常简单的版本可能如下所示(请注意 if (isLoggable(record))publish 方法中检查):

package com.test.logging;

import java.util.logging.*;

/**
 * Logging handler that stores logging in the database.
 */
public class DBHandler extends Handler {
    @Override
    public void publish(final LogRecord record) {
        System.out.println("DBHandler.publish - handler level: " + getLevel()
                           + "; log record level: " + record.getLevel());
        if (isLoggable(record))
            System.out.println(getClass().getSimpleName() + " - " + record.getMessage());
    }

    @Override
    public void flush() {
        // Empty.
    }

    @Override
    public void close() throws SecurityException {
        // Empty.
    }
}

Handler class 默认情况下不从 LogManager 读取任何属性。您必须在所有子classes 中编写该逻辑。

public class DBHandler extends Handler {

    public DBHandler() {
        LogManager m = LogManager.getLogManager();
        String p = getClass().getName();
        String v = m.getProperty(p + ".level");
        try {
            if (v != null) {
                super.setLevel(Level.parse(v));
            }
        } catch (RuntimeException re) {
            reportError(v, re, ErrorManager.OPEN_FAILURE);
        }
        //@todo create code to parse filter, formatter, encoding, etc.
    }

    @Override
    public void close() throws SecurityException {
    }

    @Override
    public void flush() {
    }

    @Override
    public void publish(LogRecord logRecord) {
        if (isLoggable(logRecord)) {
            try {
                //SQL call to insert onDB
            } catch (Exception e) {
                reportError("", e, ErrorManager.WRITE_FAILURE);
            }
        }
    }
}