/** * Log the message at the specified level with the specified exception if any. * * @param level The level to log at. * @param message The message to log. * @param e The exception, if any. */ private void log(Level level, String message, Exception e) { // millis and thread are filled by the constructor LogRecord record = new LogRecord(level, message); record.setLoggerName(logger.getName()); record.setThrown(e); record.setSourceClassName(logger.getName()); record.setSourceMethodName(getMethodName()); logger.log(record); }
/** Log the specified message after all provider for a given category have been registered. */ private static void log(final String method, final StringBuilder message) { final LogRecord record = new LogRecord(Level.CONFIG, message.toString()); record.setSourceClassName(FactoryRegistry.class.getName()); record.setSourceMethodName(method); record.setLoggerName(LOGGER.getName()); LOGGER.log(record); }
LogNode findNode(String name) { LogNode currentNode = this; if (logger.getName().equals(name)) { return this; } // 如果找不到该日志记录器,就找其子类的,比如x.y.z,发现找不到,就找x.y while (name != null) { final int dotIndex = name.indexOf('.'); final String nextName; if (dotIndex < 0) { nextName = name; name = null; } else { nextName = name.substring(0, dotIndex); name = name.substring(dotIndex + 1); } LogNode childNode = currentNode.children.get(nextName); if (childNode == null) { childNode = new LogNode(currentNode); currentNode.children.put(nextName, childNode); } currentNode = childNode; } return currentNode; }
/** * Add a named logger. This does nothing and returns false if a logger * with the same name is already registered. * <p> * The Logger factory methods call this method to register each * newly created Logger. * <p> * The application should retain its own reference to the Logger * object to avoid it being garbage collected. The LogManager * may only retain a weak reference. * * @param logger the new logger. * @return true if the argument logger was registered successfully, * false if a logger of that name already exists. * @exception NullPointerException if the logger name is null. */ public synchronized boolean addLogger(Logger logger) { String name = logger.getName(); if (name == null) { throw new NullPointerException(); } Logger old = (Logger) loggers.get(name); if (old != null) { // We already have a registered logger with the given name. return false; } // We're adding a new logger. // Note that we are creating a strong reference here that will // keep the Logger in existence indefinitely. loggers.put(name, logger); // Apply any initial level defined for the new logger. Level level = getLevelProperty(name+".level", null); if (level != null) { doSetLevel(logger, level); } // If any of the logger's parents have levels defined, // make sure they are instantiated. int ix = 1; for (;;) { int ix2 = name.indexOf(".", ix); if (ix2 < 0) { break; } String pname = name.substring(0,ix2); if (getProperty(pname+".level") != null) { // This pname has a level definition. Make sure it exists. Logger plogger = Logger.getLogger(pname); } ix = ix2+1; } // Find the new node and its parent. LogNode node = findNode(name); node.logger = logger; Logger parent = null; LogNode nodep = node.parent; while (nodep != null) { if (nodep.logger != null) { parent = nodep.logger; break; } nodep = nodep.parent; } if (parent != null) { doSetParent(logger, parent); } // Walk over the children and tell them we are their new parent. node.walkAndSetParent(logger); return true; }
/** * Finds the closest ancestor for a logger among the currently * registered ones. For example, if the currently registered * loggers have the names "", "foo", and "foo.bar", the result for * "foo.bar.baz" will be the logger whose name is "foo.bar". * * @param child a logger for whose name no logger has been * registered. * * @return the closest ancestor for <code>child</code>, * or <code>null</code> if <code>child</code> * is the root logger. * * @throws NullPointerException if <code>child</code> * is <code>null</code>. */ private synchronized Logger findAncestor(Logger child) { String childName = child.getName(); Logger best = rootLogger; int bestNameLength = 0; Logger cand; String candName; int candNameLength; if (child == rootLogger) return null; for (Iterator iter = loggers.keySet().iterator(); iter.hasNext();) { candName = (String) iter.next(); candNameLength = candName.length(); if ((candNameLength > bestNameLength) && childName.startsWith(candName) && (childName.charAt(candNameLength) == '.')) { cand = (Logger) ((WeakReference) loggers.get(candName)).get(); if ((cand == null) || (cand == child)) continue; bestNameLength = candName.length(); best = cand; } } return best; }
// actual initialization process from a given input stream private synchronized void readConfigurationImpl(InputStream ins) throws IOException { reset(); props.load(ins); // The RI treats the root logger as special. For compatibility, always // update the root logger's handlers. Logger root = loggers.get(""); if (root != null) { root.setManager(this); } // parse property "config" and apply setting String configs = props.getProperty("config"); if (configs != null) { StringTokenizer st = new StringTokenizer(configs, " "); while (st.hasMoreTokens()) { String configerName = st.nextToken(); getInstanceByClass(configerName); } } // set levels for logger Collection<Logger> allLoggers = loggers.values(); for (Logger logger : allLoggers) { String property = props.getProperty(logger.getName() + ".level"); if (property != null) { logger.setLevel(Level.parse(property)); } } listeners.firePropertyChange(null, null, null); }
/** * Logs a debug message for {@link #getServiceProvider} method. Note: we are not required to * insert the method name ({@code "GetServiceProvider"}) in the message because it is part of the * informations already stored by {@link LogRecord}, and formatted by the default {@link * java.util.logging.SimpleFormatter}. * * @param status {@code "ENTRY"}, {@code "RETURN"} or {@code "THROW"}, according {@link Logger} * conventions. * @param category The category given to the {@link #getServiceProvider} method. * @param key The key being examined, or {@code null}. * @param message Optional message, or {@code null} if none. * @param type Optional class to format after the message, or {@code null}. */ private static void debug( final String status, final Class<?> category, final Hints.Key key, final String message, final Class type) { final StringBuilder buffer = new StringBuilder(status); buffer .append(Utilities.spaces(Math.max(1, 7 - status.length()))) .append('(') .append(Classes.getShortName(category)); if (key != null) { buffer.append(", ").append(key); } buffer.append(')'); if (message != null) { buffer.append(": ").append(message); } if (type != null) { buffer.append(' ').append(Classes.getShortName(type)).append('.'); } final LogRecord record = new LogRecord(DEBUG_LEVEL, buffer.toString()); record.setSourceClassName(FactoryRegistry.class.getName()); record.setSourceMethodName("getServiceProvider"); record.setLoggerName(LOGGER.getName()); LOGGER.log(record); }
private void doLog(final Level level, final String str, final Throwable t) { try { final ModuleLogRecord rec = new ModuleLogRecord(level, str); rec.setLoggerName(logger.getName()); if (t != null) rec.setThrown(t); logger.log(rec); } catch (Throwable ignored) { } }
public TransportListener( final JbiTransportListener jtl, final ServerBootstrap partialBootstrap, final Logger logger, final ClassResolver cr) { this.jtl = jtl; this.logger = logger; // shared between all the connections of this listener final LoggingHandler debugs = new LoggingHandler(logger.getName() + ".dispatcher", LogLevel.TRACE); final ChannelHandler errors = new LastLoggingHandler(logger.getName() + ".errors"); final ObjectEncoder objectEncoder = new ObjectEncoder(); final ServerBootstrap _bootstrap = partialBootstrap .handler(new LoggingHandler(logger.getName() + ".listener")) .childHandler( new ChannelInitializer<Channel>() { @Override protected void initChannel(final @Nullable Channel ch) throws Exception { assert ch != null; final ChannelPipeline p = ch.pipeline(); p.addLast(HandlerConstants.LOG_DEBUG_HANDLER, debugs); p.addLast(objectEncoder); p.addLast(new ObjectDecoder(cr)); p.addLast( HandlerConstants.DOMAIN_HANDLER, new AuthenticatorSSLHandler( TransportListener.this, logger, new DomainHandlerBuilder<ConsumerDomain>() { @Override public ChannelHandler build(final ConsumerDomain domain) { return new DomainHandler(domain); } })); p.addLast(HandlerConstants.LOG_ERRORS_HANDLER, errors); } }); assert _bootstrap != null; bootstrap = _bootstrap; }
/** * Add a given logger into the hierarchical namespace. The {@code Logger.addLogger()} factory * methods call this method to add newly created Logger. This returns false if a logger with the * given name has existed in the namespace * * <p>Note that the {@code LogManager} may only retain weak references to registered loggers. In * order to prevent {@code Logger} objects from being unexpectedly garbage collected it is * necessary for <i>applications</i> to maintain references to them. * * @param logger the logger to be added. * @return true if the given logger is added into the namespace successfully, false if the given * logger exists in the namespace. */ public synchronized boolean addLogger(Logger logger) { String name = logger.getName(); if (loggers.get(name) != null) { return false; } addToFamilyTree(logger, name); loggers.put(name, logger); logger.setManager(this); return true; }
/** Computes the source method name for the log output. */ private String getMethodName() { StackTraceElement[] steArray = new Throwable().getStackTrace(); for (StackTraceElement stackTraceElement : steArray) { if (logger.getName().equals(stackTraceElement.getClassName())) { return stackTraceElement.getMethodName(); } } return null; }
public void testInjectsJustOneLogger() { AtomicReference<Logger> loggerRef = new AtomicReference<Logger>(); Injector injector = Guice.createInjector(new FooModule(loggerRef)); assertNull(loggerRef.get()); injector.getInstance(Integer.class); Logger lastLogger = loggerRef.getAndSet(null); assertNotNull(lastLogger); injector.getInstance(Integer.class); assertSame(lastLogger, loggerRef.get()); assertEquals(FooModule.class.getName(), lastLogger.getName()); }
public String getParentLoggerName(String loggerName) { Logger l = logManager.getLogger(loggerName); if (l == null) { return null; } Logger p = l.getParent(); if (p == null) { // root logger return EMPTY_STRING; } else { return p.getName(); } }
/* pp */ FQNLogger(final String fqnClassName, final String simpleClassName, final Level level) { this.impl = Logger.getLogger(fqnClassName); this.handler = new PlainLogConsoleHandler(new PlainLogFormatter(simpleClassName), Level.ALL); this.impl.setUseParentHandlers(false); this.impl.setLevel(level); this.impl.addHandler(this.handler); this.impl.log( Level.INFO, "Logging.new: " + impl.getName() + ": level " + level + ": obj 0x" + Integer.toHexString(impl.hashCode())); }
/** * Register the "RecodeNoData" image operation to the operation registry of the specified JAI * instance. */ public static void register(final JAI jai) { final OperationRegistry registry = jai.getOperationRegistry(); try { registry.registerDescriptor(new Descriptor()); registry.registerFactory( RenderedRegistryMode.MODE_NAME, OPERATION_NAME, "geotools.org", new CRIF()); } catch (IllegalArgumentException exception) { final LogRecord record = Loggings.format(Level.SEVERE, LoggingKeys.CANT_REGISTER_JAI_OPERATION_$1, OPERATION_NAME); record.setSourceMethodName("<classinit>"); record.setThrown(exception); record.setLoggerName(LOGGER.getName()); LOGGER.log(record); } }
/* * (non-Javadoc) * * @see java.util.logging.LoggingMXBean#getParentLoggerName(java.lang.String) */ public String getParentLoggerName(String loggerName) { String result = null; Logger logger = LogManager.getLogManager().getLogger(loggerName); if (logger != null) { // The named Logger exists. Now attempt to obtain its parent. Logger parent = logger.getParent(); if (parent != null) { // There is a parent result = parent.getName(); } else { // logger must be the root Logger result = ""; } } return result; }
/** Invoked when a factory can't be loaded. Log a warning, but do not stop the process. */ private static void loadingFailure( final Class<?> category, final Throwable error, final boolean showStackTrace) { final String name = Classes.getShortName(category); final StringBuilder cause = new StringBuilder(Classes.getShortClassName(error)); final String message = error.getLocalizedMessage(); if (message != null) { cause.append(": "); cause.append(message); } final LogRecord record = Loggings.format(Level.WARNING, LoggingKeys.CANT_LOAD_SERVICE_$2, name, cause.toString()); if (showStackTrace) { record.setThrown(error); } record.setSourceClassName(FactoryRegistry.class.getName()); record.setSourceMethodName("scanForPlugins"); record.setLoggerName(LOGGER.getName()); LOGGER.log(record); }
public static Date parse(String _date, String format) { Date date; DateFormat dateFmt; dateFmt = new SimpleDateFormat(format); try { date = dateFmt.parse(_date); } catch (ParseException e) { date = null; LOGGER.log( Level.SEVERE, "{0}.{1}() -> {2}", new Object[] {LOGGER.getName(), "parse", e.getMessage()}); } return date; }
private void addToFamilyTree(Logger logger, String name) { Logger parent = null; // find parent int lastSeparator; String parentName = name; while ((lastSeparator = parentName.lastIndexOf('.')) != -1) { parentName = parentName.substring(0, lastSeparator); parent = loggers.get(parentName); if (parent != null) { setParent(logger, parent); break; } else if (getProperty(parentName + ".level") != null || getProperty(parentName + ".handlers") != null) { parent = Logger.getLogger(parentName); setParent(logger, parent); break; } } if (parent == null && (parent = loggers.get("")) != null) { setParent(logger, parent); } // find children // TODO: performance can be improved here? String nameDot = name + '.'; Collection<Logger> allLoggers = loggers.values(); for (final Logger child : allLoggers) { Logger oldParent = child.getParent(); if (parent == oldParent && (name.length() == 0 || child.getName().startsWith(nameDot))) { final Logger thisLogger = logger; child.setParent(thisLogger); if (oldParent != null) { // -- remove from old parent as the parent has been changed oldParent.children.remove(child); } } } }
public void testDefaultLoggerProperties() throws Exception { // mock LogManager has no default logger assertNull(mockManager.getLogger("")); assertNull(mockManager.getLogger("global")); // non-mock LogManager has two default logger Logger global = manager.getLogger("global"); Logger root = manager.getLogger(""); assertSame(global, Logger.global); assertSame(root, global.getParent()); // root properties manager.readConfiguration(EnvironmentHelper.PropertiesToInputStream(props)); assertNull(root.getFilter()); assertEquals(2, root.getHandlers().length); assertEquals(Level.FINE, root.getLevel()); assertEquals("", root.getName()); assertSame(root.getParent(), null); assertNull(root.getResourceBundle()); assertNull(root.getResourceBundleName()); assertTrue(root.getUseParentHandlers()); }
/** * Returns the backing-store factory for HSQL syntax. If the cached tables are not available, they * will be created now from the SQL scripts bundled in this plugin. * * @param hints A map of hints, including the low-level factories to use for CRS creation. * @return The EPSG factory using HSQL syntax. * @throws SQLException if connection to the database failed. */ protected AbstractAuthorityFactory createBackingStore(final Hints hints) throws SQLException { final DataSource source = getDataSource(); final File directory = getDirectory(source); directory.mkdirs(); if (!dataExists(directory)) { FileLock lock = null; try { // get an exclusive lock lock = acquireLock(directory); // if after getting the lock the database is still incomplete let's work on it if (!dataExists(directory)) { /* * HSQL has created automatically an empty database. We need to populate it. * Executes the SQL scripts bundled in the JAR. In theory, each line contains * a full SQL statement. For this plugin however, we have compressed "INSERT * INTO" statements using Compactor class in this package. */ final Logger logger = Logging.getLogger(LOGGER); final LogRecord record = Loggings.format(Level.INFO, LoggingKeys.CREATING_CACHED_EPSG_DATABASE_$1, VERSION); record.setLoggerName(logger.getName()); logger.log(record); ZipInputStream zin = new ZipInputStream(ThreadedH2EpsgFactory.class.getResourceAsStream(ZIP_FILE)); ZipEntry ze = null; byte[] buf = new byte[1024]; int read = 0; while ((ze = zin.getNextEntry()) != null) { File file = new File(directory, ze.getName()); if (file.exists()) { file.delete(); } FileOutputStream fout = new FileOutputStream(file); while ((read = zin.read(buf)) > 0) { fout.write(buf, 0, read); } zin.closeEntry(); fout.close(); } zin.close(); // mark the successful creation File marker = new File(directory, MARKER_FILE); if (marker.exists()) { marker.delete(); } marker.createNewFile(); setReadOnly(directory); } } catch (IOException exception) { SQLException e = new SQLException(Errors.format(ErrorKeys.CANT_READ_$1, ZIP_FILE)); e.initCause(exception); // TODO: inline cause when we will be allowed to target Java 6. throw e; } finally { if (lock != null) { try { lock.release(); lock.channel().close(); new File(directory, LOCK_FILE).delete(); } catch (IOException e) { // does not matter, was just cleanup } } } } FactoryUsingAnsiSQL factory = new FactoryUsingAnsiSQL(hints, getDataSource().getConnection()); factory.setValidationQuery("CALL NOW()"); return factory; }
synchronized void update(Set<UpdatableNode> seenNodes) { try { long start = System.nanoTime(); CommandResult res = _port.runCommand(_mongo.getDB("admin"), _isMasterCmd); long end = System.nanoTime(); float newPingMS = (end - start) / 1000000F; if (!successfullyContacted) _pingTimeMS = newPingMS; else _pingTimeMS = _pingTimeMS + ((newPingMS - _pingTimeMS) / latencySmoothFactor); _rootLogger.log( Level.FINE, "Latency to " + _addr + " actual=" + newPingMS + " smoothed=" + _pingTimeMS); successfullyContacted = true; if (res == null) { throw new MongoInternalException("Invalid null value returned from isMaster"); } if (!_ok) { _logger.get().log(Level.INFO, "Server seen up: " + _addr); } _ok = true; _isMaster = res.getBoolean("ismaster", false); _isSecondary = res.getBoolean("secondary", false); _lastPrimarySignal.set(res.getString("primary")); if (res.containsField("hosts")) { for (Object x : (List) res.get("hosts")) { String host = x.toString(); UpdatableNode node = _addIfNotHere(host); if (node != null && seenNodes != null) seenNodes.add(node); } } if (res.containsField("passives")) { for (Object x : (List) res.get("passives")) { String host = x.toString(); UpdatableNode node = _addIfNotHere(host); if (node != null && seenNodes != null) seenNodes.add(node); } } // Tags were added in 2.0 but may not be present if (res.containsField("tags")) { DBObject tags = (DBObject) res.get("tags"); for (String key : tags.keySet()) { _tags.put(key, tags.get(key).toString()); } } // max size was added in 1.8 if (res.containsField("maxBsonObjectSize")) { _maxBsonObjectSize = (Integer) res.get("maxBsonObjectSize"); } else { _maxBsonObjectSize = Bytes.MAX_OBJECT_SIZE; } if (res.containsField("setName")) { String setName = res.get("setName").toString(); if (_setName.get() == null) { _setName.set(setName); _logger.set(Logger.getLogger(_rootLogger.getName() + "." + setName)); } else if (!_setName.get().equals(setName)) { _logger .get() .log(Level.SEVERE, "mismatch set name old: " + _setName.get() + " new: " + setName); } } } catch (Exception e) { if (_ok) { _logger.get().log(Level.WARNING, "Server seen down: " + _addr, e); } else if (Math.random() < 0.1) { _logger.get().log(Level.WARNING, "Server seen down: " + _addr, e); } _ok = false; } }
private SSLHandlerTest() { logger = Logger.getLogger(getClass().getName()); logger.info("Logger(" + logger.getName() + ") finest(" + logger.isLoggable(Level.FINEST) + ")"); }
/** * Add the specified logger to the classloader local configuration. * * @param logger The logger to be added */ @Override public synchronized boolean addLogger(final Logger logger) { final String loggerName = logger.getName(); ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); ClassLoaderLogManagerClassLoaderLogInfo info = getClassLoaderInfo(classLoader); if (info.getLoggers().containsKey(loggerName)) { return false; } info.getLoggers().put(loggerName, logger); // Apply initial level for new logger final String levelString = getProperty(loggerName + ".level"); if (levelString != null) { try { AccessController.doPrivileged( new PrivilegedAction<Void>() { @Override public Void run() { logger.setLevel(Level.parse(levelString.trim())); return null; } }); } catch (IllegalArgumentException e) { // Leave level set to null } } // Always instantiate parent loggers so that // we can control log categories even during runtime int dotIndex = loggerName.lastIndexOf('.'); if (dotIndex >= 0) { final String parentName = loggerName.substring(0, dotIndex); Logger.getLogger(parentName); } // Find associated node ClassLoaderLogManagerLogNode node = info.getRootNode().findNode(loggerName); node.setLogger(logger); // Set parent logger Logger parentLogger = node.findParentLogger(); if (parentLogger != null) { doSetParentLogger(logger, parentLogger); } // Tell children we are their new parent node.setParentLogger(logger); // Add associated handlers, if any are defined using the .handlers property. // In this case, handlers of the parent logger(s) will not be used String handlers = getProperty(loggerName + ".handlers"); if (handlers != null) { logger.setUseParentHandlers(false); StringTokenizer tok = new StringTokenizer(handlers, ","); while (tok.hasMoreTokens()) { String handlerName = (tok.nextToken().trim()); Handler handler = null; ClassLoader current = classLoader; while (current != null) { info = classLoaderLoggers.get(current); if (info != null) { handler = info.getHandlers().get(handlerName); if (handler != null) { break; } } current = current.getParent(); } if (handler != null) { logger.addHandler(handler); } } } // Parse useParentHandlers to set if the logger should delegate to its parent. // Unlike java.util.logging, the default is to not delegate if a list of handlers // has been specified for the logger. String useParentHandlersString = getProperty(loggerName + ".useParentHandlers"); if (Boolean.valueOf(useParentHandlersString).booleanValue()) { logger.setUseParentHandlers(true); } return true; }
@Override public String getName() { return impl.getName(); }
@Test public void testGetName() throws Exception { assertThat(logger.getName(), equalTo(LOGGER_NAME)); }
/** * Implementation of {@link #unexpectedException(Logger, Class, String, Throwable)}. * * @param logger Where to log the error, or {@code null}. * @param classe The fully qualified class name where the error occurred, or {@code null}. * @param method The method where the error occurred, or {@code null}. * @param error The error. * @param level The logging level. * @return {@code true} if the error has been logged, or {@code false} if the logger doesn't log * anything at the specified level. */ private static boolean unexpectedException( Logger logger, String classe, String method, final Throwable error, final Level level) { /* * Checks if loggable, inferring the logger from the classe name if needed. */ if (error == null) { return false; } if (logger == null && classe != null) { final int separator = classe.lastIndexOf('.'); final String paquet = (separator >= 1) ? classe.substring(0, separator - 1) : ""; logger = getLogger(paquet); } if (logger != null && !logger.isLoggable(level)) { return false; } /* * Loggeable, so complete the null argument from the stack trace if we can. */ if (logger == null || classe == null || method == null) { String paquet = (logger != null) ? logger.getName() : null; final StackTraceElement[] elements = error.getStackTrace(); for (int i = 0; i < elements.length; i++) { /* * Searchs for the first stack trace element with a classname matching the * expected one. We compare preferably against the name of the class given * in argument, or against the logger name (taken as the package name) otherwise. */ final StackTraceElement element = elements[i]; final String classname = element.getClassName(); if (classe != null) { if (!classname.equals(classe)) { continue; } } else if (paquet != null) { if (!classname.startsWith(paquet)) { continue; } final int length = paquet.length(); if (classname.length() > length) { // We expect '.' but we accept also '$' or end of string. final char separator = classname.charAt(length); if (Character.isJavaIdentifierPart(separator)) { continue; } } } /* * Now that we have a stack trace element from the expected class (or any * element if we don't know the class), make sure that we have the right method. */ final String methodName = element.getMethodName(); if (method != null && !methodName.equals(method)) { continue; } /* * Now computes every values that are null, and stop the loop. */ if (paquet == null) { final int separator = classname.lastIndexOf('.'); paquet = (separator >= 1) ? classname.substring(0, separator - 1) : ""; logger = getLogger(paquet); if (!logger.isLoggable(level)) { return false; } } if (classe == null) { classe = classname; } if (method == null) { method = methodName; } break; } /* * The logger may stay null if we have been unable to find a suitable * stack trace. Fallback on the global logger. * * TODO: Use GLOBAL_LOGGER_NAME constant when we will be allowed to target Java 6. */ if (logger == null) { logger = getLogger("global"); if (!logger.isLoggable(level)) { return false; } } } /* * Now prepare the log message. If we have been unable to figure out a source class and * method name, we will fallback on Java logging default mechanism, which may returns a * less relevant name than our attempt to use the logger name as the package name. */ final StringBuilder buffer = new StringBuilder(Classes.getShortClassName(error)); final String message = error.getLocalizedMessage(); if (message != null) { buffer.append(": ").append(message); } final LogRecord record = new LogRecord(level, buffer.toString()); if (classe != null) { record.setSourceClassName(classe); } if (method != null) { record.setSourceMethodName(method); } if (level.intValue() > 500) { record.setThrown(error); } record.setLoggerName(logger.getName()); logger.log(record); return true; }
/** * Add a named logger. This does nothing and returns false if a logger with the same name is * already registered. * * <p>The Logger factory methods call this method to register each newly created Logger. * * <p>The application should retain its own reference to the Logger object to avoid it being * garbage collected. The LogManager may only retain a weak reference. * * @param logger the new logger. * @return true if the argument logger was registered successfully, false if a logger of that name * already exists. * @exception NullPointerException if the logger name is null. */ public synchronized boolean addLogger(Logger logger) { final String name = logger.getName(); if (name == null) { throw new NullPointerException(); } // cleanup some Loggers that have been GC'ed drainLoggerRefQueueBounded(); LoggerWeakRef ref = namedLoggers.get(name); if (ref != null) { if (ref.get() == null) { // It's possible that the Logger was GC'ed after the // drainLoggerRefQueueBounded() call above so allow // a new one to be registered. namedLoggers.remove(name); } else { // We already have a registered logger with the given name. return false; } } // We're adding a new logger. // Note that we are creating a weak reference here. ref = new LoggerWeakRef(logger); namedLoggers.put(name, ref); // Apply any initial level defined for the new logger. Level level = getLevelProperty(name + ".level", null); if (level != null) { doSetLevel(logger, level); } // Do we have a per logger handler too? // Note: this will add a 200ms penalty loadLoggerHandlers(logger, name, name + ".handlers"); processParentHandlers(logger, name); // Find the new node and its parent. LogNode node = findNode(name); node.loggerRef = ref; Logger parent = null; LogNode nodep = node.parent; while (nodep != null) { LoggerWeakRef nodeRef = nodep.loggerRef; if (nodeRef != null) { parent = nodeRef.get(); if (parent != null) { break; } } nodep = nodep.parent; } if (parent != null) { doSetParent(logger, parent); } // Walk over the children and tell them we are their new parent. node.walkAndSetParent(logger); // new LogNode is ready so tell the LoggerWeakRef about it ref.setNode(node); return true; }
@Test public void testGlobalLoggerName() throws Exception { final Logger root = Logger.getLogger(Logger.GLOBAL_LOGGER_NAME); assertThat(root.getName(), equalTo(Logger.GLOBAL_LOGGER_NAME)); }
LoggerWeakRef(Logger logger) { super(logger, loggerRefQueue); name = logger.getName(); // save for namedLoggers cleanup }