/** * Returns the {@code StatusLoggerAdminMBean} associated with the specified * context name, or {@code null}. * * @param contextName search key * @return StatusLoggerAdminMBean or null * @throws MalformedObjectNameException If an object name is malformed * @throws IOException If an I/O error occurred */ public StatusLoggerAdminMBean getStatusLoggerAdmin(final String contextName) throws MalformedObjectNameException, IOException { final String pattern = StatusLoggerAdminMBean.PATTERN; final String mbean = String.format(pattern, Server.escape(contextName)); final ObjectName search = new ObjectName(mbean); final Set<ObjectName> result = connection.queryNames(search, null); if (result.size() == 0) { return null; } if (result.size() > 1) { System.err.println("WARN: multiple status loggers found for " + contextName + ": " + result); } final StatusLoggerAdminMBean proxy = JMX.newMBeanProxy(connection, // result.iterator().next(), // StatusLoggerAdminMBean.class, true); // notificationBroadcaster return proxy; }
public ClientGui(final Client client) throws IOException, JMException { this.client = Objects.requireNonNull(client, "client"); createWidgets(); populateWidgets(); // register for Notifications if LoggerContext MBean was added/removed final ObjectName addRemoveNotifs = MBeanServerDelegate.DELEGATE_NAME; final NotificationFilterSupport filter = new NotificationFilterSupport(); filter.enableType(Server.DOMAIN); // only interested in Log4J2 MBeans client.getConnection().addNotificationListener(addRemoveNotifs, this, null, null); }
/** * Blocks until all Log4j tasks have completed execution after a shutdown request and all appenders have shut down, * or the timeout occurs, or the current thread is interrupted, whichever happens first. * <p> * Not all appenders will honor this, it is a hint and not an absolute guarantee that the this method not block longer. * Setting timeout too low increase the risk of losing outstanding log events not yet written to the final * destination. * <p> * Log4j can start threads to perform certain actions like file rollovers, calling this method with a positive timeout will * block until the rollover thread is done. * * @param timeout the maximum time to wait, or 0 which mean that each apppender uses its default timeout, and don't wait for background tasks * @param timeUnit * the time unit of the timeout argument * @return {@code true} if the logger context terminated and {@code false} if the timeout elapsed before * termination. * @since 2.7 */ @Override public boolean stop(final long timeout, final TimeUnit timeUnit) { LOGGER.debug("Stopping LoggerContext[name={}, {}]...", getName(), this); configLock.lock(); try { if (this.isStopped()) { return true; } this.setStopping(); try { Server.unregisterLoggerContext(getName()); // LOG4J2-406, LOG4J2-500 } catch (final LinkageError | Exception e) { // LOG4J2-1506 Hello Android, GAE LOGGER.error("Unable to unregister MBeans", e); } if (shutdownCallback != null) { shutdownCallback.cancel(); shutdownCallback = null; } final Configuration prev = configuration; configuration = NULL_CONFIGURATION; updateLoggers(); if (prev instanceof LifeCycle2) { ((LifeCycle2) prev).stop(timeout, timeUnit); } else { prev.stop(); } externalContext = null; LogManager.getFactory().removeContext(this); } finally { configLock.unlock(); this.setStopped(); } LOGGER.debug("Stopped LoggerContext[name={}, {}] with status {}", getName(), this, true); return true; }
/** * Sets the Configuration to be used. * * @param config The new Configuration. * @return The previous Configuration. */ private Configuration setConfiguration(final Configuration config) { if (config == null) { LOGGER.error("No configuration found for context '{}'.", contextName); // No change, return the current configuration. return this.configuration; } configLock.lock(); try { final Configuration prev = this.configuration; config.addListener(this); final ConcurrentMap<String, String> map = config.getComponent(Configuration.CONTEXT_PROPERTIES); try { // LOG4J2-719 network access may throw android.os.NetworkOnMainThreadException map.putIfAbsent("hostName", NetUtils.getLocalHostname()); } catch (final Exception ex) { LOGGER.debug("Ignoring {}, setting hostName to 'unknown'", ex.toString()); map.putIfAbsent("hostName", "unknown"); } map.putIfAbsent("contextName", contextName); config.start(); this.configuration = config; updateLoggers(); if (prev != null) { prev.removeListener(this); prev.stop(); } firePropertyChangeEvent(new PropertyChangeEvent(this, PROPERTY_CONFIG, prev, config)); try { Server.reregisterMBeansAfterReconfigure(); } catch (final LinkageError | Exception e) { // LOG4J2-716: Android has no java.lang.management LOGGER.error("Could not reconfigure JMX", e); } // AsyncLoggers update their nanoClock when the configuration changes Log4jLogEvent.setNanoClock(configuration.getNanoClock()); return prev; } finally { configLock.unlock(); } }
/** * Returns {@code true} if the specified {@code ObjectName} is for a * {@code LoggerContextAdminMBean}, {@code false} otherwise. * * @param mbeanName the {@code ObjectName} to check. * @return {@code true} if the specified {@code ObjectName} is for a * {@code LoggerContextAdminMBean}, {@code false} otherwise */ public boolean isLoggerContext(final ObjectName mbeanName) { return Server.DOMAIN.equals(mbeanName.getDomain()) // && mbeanName.getKeyPropertyList().containsKey("type") // && mbeanName.getKeyPropertyList().size() == 1; }