ignite系列之13--默认日志级别level之大坑

 Ignite日志逻辑说明

默认日志配置文件

ignite配置中不指定配置文件

默认使用{IGNITE_HOME}/config/java.util.logging.properties 配置文件

默认配置示例如下:

.level=INFO

# Console handler logs all messages with importance level `INFO` and above
# into standard error stream (`System.err`).
#
java.util.logging.ConsoleHandler.formatter=org.apache.ignite.logger.java.JavaLoggerFormatter
java.util.logging.ConsoleHandler.level=INFO

#
# File handler logs all messages into files with pattern `ignite-%{id8}.%g.log`
# under `$IGNITE_HOME/work/log/` directory. The placeholder `%{id8}` is a truncated node ID.
#
org.apache.ignite.logger.java.JavaLoggerFileHandler.formatter=org.apache.ignite.logger.java.JavaLoggerFormatter
org.apache.ignite.logger.java.JavaLoggerFileHandler.pattern=%{app}-%{id8}.%g.log
org.apache.ignite.logger.java.JavaLoggerFileHandler.level=INFO
org.apache.ignite.logger.java.JavaLoggerFileHandler.limit=52428800
org.apache.ignite.logger.java.JavaLoggerFileHandler.count=20

上述limit单位时字节,上述是50M

日志文件位置

日志默认打印在目录:{IGNITE_HOME}/work/log 下,如果设置了workDirectory,则在workDirectory下

<bean class="org.apache.ignite.configuration.IgniteConfiguration">
    <property name="workDirectory" value="/path/to/work/directory"/>
    <!-- other properties -->
</bean>
日志文件示例如下,每次启动会有新的日志文件,同一个实例日志超过limit大小,会使用新的文件存储日志

代码层,默认使用的日志类

为:org.apache.ignite.logger.java.JavaLogger

配置文件加载逻辑为:

public static final String DFLT_CONFIG_PATH = "config/java.util.logging.properties";
   private void defaultConfiguration() {
        final URL cfgUrl = U.resolveIgniteUrl(DFLT_CONFIG_PATH);

        if (cfgUrl == null) {
            warning("Failed to resolve default logging config file: " + DFLT_CONFIG_PATH);

            return;
        }

        try (InputStream in = cfgUrl.openStream()) {
            LogManager.getLogManager().readConfiguration(in);
        }
        catch (IOException e) {
            error("Failed to read logging configuration: " + cfgUrl, e);
        }

        cfg = cfgUrl.getPath();
    }

日志配置文件加载逻辑为:

public void readConfiguration(InputStream ins) throws IOException, SecurityException {
        checkPermission();
        reset();

        // Load the properties
        props.load(ins);
        // Instantiate new configuration objects.
        String names[] = parseClassNames("config");

        for (int i = 0; i < names.length; i++) {
            String word = names[i];
            try {
                Class<?> clz = ClassLoader.getSystemClassLoader().loadClass(word);
                clz.newInstance();
            } catch (Exception ex) {
                System.err.println("Can't load config class \"" + word + "\"");
                System.err.println("" + ex);
                // ex.printStackTrace();
            }
        }

        // Set levels on any pre-existing loggers, based on the new properties.
        setLevelsOnExistingLoggers();

        // Notify any interested parties that our properties have changed.
        // We first take a copy of the listener map so that we aren't holding any
        // locks when calling the listeners.
        Map<Object,Integer> listeners = null;
        synchronized (listenerMap) {
            if (!listenerMap.isEmpty())
                listeners = new HashMap<>(listenerMap);
        }
        if (listeners != null) {
            assert Beans.isBeansPresent();
            Object ev = Beans.newPropertyChangeEvent(LogManager.class, null, null, null);
            for (Map.Entry<Object,Integer> entry : listeners.entrySet()) {
                Object listener = entry.getKey();
                int count = entry.getValue().intValue();
                for (int i = 0; i < count; i++) {
                    Beans.invokePropertyChange(listener, ev);
                }
            }
        }


        // Note that we need to reinitialize global handles when
        // they are first referenced.
        synchronized (this) {
            initializedGlobalHandlers = false;
        }
    }

正常会走到setLevelsOnExistingLoggers();方法

synchronized private void setLevelsOnExistingLoggers() {
        Enumeration<?> enum_ = props.propertyNames();
        while (enum_.hasMoreElements()) {
            String key = (String)enum_.nextElement();
            if (!key.endsWith(".level")) {
                // Not a level definition.
                continue;
            }
            int ix = key.length() - 6;
            String name = key.substring(0, ix);
            Level level = getLevelProperty(key, null);
            if (level == null) {
                System.err.println("Bad level value for property: " + key);
                continue;
            }
            for (LoggerContext cx : contexts()) {
                Logger l = cx.findLogger(name);
                if (l == null) {
                    continue;
                }
                l.setLevel(level);
            }
        }
    }

而这个比较坑的是支持的日志level如下:

    /**
     * OFF is a special level that can be used to turn off logging.
     * This level is initialized to <CODE>Integer.MAX_VALUE</CODE>.
     */
    public static final Level OFF = new Level("OFF",Integer.MAX_VALUE, defaultBundle);

    /**
     * SEVERE is a message level indicating a serious failure.
     * <p>
     * In general SEVERE messages should describe events that are
     * of considerable importance and which will prevent normal
     * program execution.   They should be reasonably intelligible
     * to end users and to system administrators.
     * This level is initialized to <CODE>1000</CODE>.
     */
    public static final Level SEVERE = new Level("SEVERE",1000, defaultBundle);

    /**
     * WARNING is a message level indicating a potential problem.
     * <p>
     * In general WARNING messages should describe events that will
     * be of interest to end users or system managers, or which
     * indicate potential problems.
     * This level is initialized to <CODE>900</CODE>.
     */
    public static final Level WARNING = new Level("WARNING", 900, defaultBundle);

    /**
     * INFO is a message level for informational messages.
     * <p>
     * Typically INFO messages will be written to the console
     * or its equivalent.  So the INFO level should only be
     * used for reasonably significant messages that will
     * make sense to end users and system administrators.
     * This level is initialized to <CODE>800</CODE>.
     */
    public static final Level INFO = new Level("INFO", 800, defaultBundle);

    /**
     * CONFIG is a message level for static configuration messages.
     * <p>
     * CONFIG messages are intended to provide a variety of static
     * configuration information, to assist in debugging problems
     * that may be associated with particular configurations.
     * For example, CONFIG message might include the CPU type,
     * the graphics depth, the GUI look-and-feel, etc.
     * This level is initialized to <CODE>700</CODE>.
     */
    public static final Level CONFIG = new Level("CONFIG", 700, defaultBundle);

    /**
     * FINE is a message level providing tracing information.
     * <p>
     * All of FINE, FINER, and FINEST are intended for relatively
     * detailed tracing.  The exact meaning of the three levels will
     * vary between subsystems, but in general, FINEST should be used
     * for the most voluminous detailed output, FINER for somewhat
     * less detailed output, and FINE for the  lowest volume (and
     * most important) messages.
     * <p>
     * In general the FINE level should be used for information
     * that will be broadly interesting to developers who do not have
     * a specialized interest in the specific subsystem.
     * <p>
     * FINE messages might include things like minor (recoverable)
     * failures.  Issues indicating potential performance problems
     * are also worth logging as FINE.
     * This level is initialized to <CODE>500</CODE>.
     */
    public static final Level FINE = new Level("FINE", 500, defaultBundle);

    /**
     * FINER indicates a fairly detailed tracing message.
     * By default logging calls for entering, returning, or throwing
     * an exception are traced at this level.
     * This level is initialized to <CODE>400</CODE>.
     */
    public static final Level FINER = new Level("FINER", 400, defaultBundle);

    /**
     * FINEST indicates a highly detailed tracing message.
     * This level is initialized to <CODE>300</CODE>.
     */
    public static final Level FINEST = new Level("FINEST", 300, defaultBundle);

    /**
     * ALL indicates that all messages should be logged.
     * This level is initialized to <CODE>Integer.MIN_VALUE</CODE>.
     */
    public static final Level ALL = new Level("ALL", Integer.MIN_VALUE, defaultBundle);

这些日志level和传统logj不匹配,且上述也不可以识别大小写,真怀疑设计者是如何想的



 

posted @ 2023-03-16 10:45  life_start  阅读(149)  评论(0编辑  收藏  举报