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不匹配,且上述也不可以识别大小写,真怀疑设计者是如何想的
本文来自博客园,作者:life_start,转载请注明原文链接:https://www.cnblogs.com/yangh2016/p/17221433.html