/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt * or http://forgerock.org/license/CDDLv1.0.html. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at legal-notices/CDDLv1_0.txt. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: * Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END * * * Copyright 2007-2009 Sun Microsystems, Inc. * Portions Copyright 2013-2015 ForgeRock AS */ package org.opends.server.loggers; import static org.opends.messages.ConfigMessages.*; import static org.opends.server.util.ServerConstants.*; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import org.opends.server.admin.ClassPropertyDefinition; import org.opends.server.admin.std.meta.DebugLogPublisherCfgDefn; import org.opends.server.admin.std.server.DebugLogPublisherCfg; /** * A logger for debug and trace logging. DebugLogger provides a debugging * management access point. It is used to configure the Tracers, as well as * to register a per-class tracer. * * Various stub debug methods are provided to log different types of debug * messages. However, these methods do not contain any actual implementation. * Tracer aspects are later weaved to catch alls to these stub methods and * do the work of logging the message. * * DebugLogger is self-initializing. */ public class DebugLogger extends AbstractLogger <DebugLogPublisher<DebugLogPublisherCfg>, DebugLogPublisherCfg> { /** The set of all DebugTracer instances. */ private static Map<String, DebugTracer> classTracers = new ConcurrentHashMap<>(); /** * Trace methods will use this static boolean to determine if debug is enabled * so to not incur the cost of calling debugPublishers.isEmpty(). */ static boolean enabled; private static final LoggerStorage <DebugLogPublisher<DebugLogPublisherCfg>, DebugLogPublisherCfg> loggerStorage = new LoggerStorage<>(); /** The singleton instance of this class. */ static final DebugLogger instance = new DebugLogger(); /** * The constructor for this class. */ private DebugLogger() { super((Class) DebugLogPublisher.class, ERR_CONFIG_LOGGER_INVALID_DEBUG_LOGGER_CLASS); } /** {@inheritDoc} */ @Override protected ClassPropertyDefinition getJavaClassPropertyDefinition() { return DebugLogPublisherCfgDefn.getInstance() .getJavaClassPropertyDefinition(); } /** {@inheritDoc} */ @Override protected Collection<DebugLogPublisher<DebugLogPublisherCfg>> getLogPublishers() { return loggerStorage.getLogPublishers(); } /** * Update all debug tracers with the settings in the registered * publishers. */ static void updateTracerSettings() { DebugLogPublisher<DebugLogPublisherCfg>[] publishers = loggerStorage.getLogPublishers().toArray(new DebugLogPublisher[0]); for(DebugTracer tracer : classTracers.values()) { tracer.updateSettings(publishers); } } /** * Indicates if debug logging is enabled. * * @return True if debug logging is enabled. False otherwise. */ public static boolean debugEnabled() { return enabled; } /** * Retrieve the singleton instance of this class. * * @return The singleton instance of this logger. */ public static DebugLogger getInstance() { return instance; } /** * Returns the registered Debug Tracer for a traced class. * * @param className The name of the class tracer to retrieve. * @return The tracer for the provided class or null if there are * no tracers registered. */ public static DebugTracer getTracer(final String className) { DebugTracer tracer = classTracers.get(className); if (tracer == null) { tracer = new DebugTracer(className, loggerStorage.getLogPublishers().toArray( new DebugLogPublisher[0])); classTracers.put(tracer.getTracedClassName(), tracer); } return tracer; } /** * Adds a text debug log publisher that will print all messages to the * provided writer, based on debug target(s) defined through system * properties. * <p> * It is expected that one or more system properties beginning with * {@code PROPERTY_DEBUG_TARGET} are set to define the properties of the debug * targets used by the publisher, otherwise no publisher is added. * * @param writer * The text writer where the message will be written to. * @return the publisher. It may be {@code null} if no publisher is added. */ @SuppressWarnings({ "unchecked", "rawtypes" }) public final TextDebugLogPublisher addPublisherIfRequired(TextWriter writer) { final List<String> debugTargets = getDebugTargetsFromSystemProperties(); TextDebugLogPublisher publisher = null; if (!debugTargets.isEmpty()) { publisher = TextDebugLogPublisher.getStartupTextDebugPublisher(debugTargets, writer); if (publisher != null) { addLogPublisher((DebugLogPublisher) publisher); } } return publisher; } private List<String> getDebugTargetsFromSystemProperties() { final List<String> targets = new ArrayList<>(); for (Map.Entry<Object, Object> entry : System.getProperties().entrySet()) { if (((String) entry.getKey()).startsWith(PROPERTY_DEBUG_TARGET)) { targets.add((String)entry.getValue()); } } return targets; } /** {@inheritDoc} */ @Override public final synchronized void addLogPublisher( DebugLogPublisher<DebugLogPublisherCfg> publisher) { loggerStorage.addLogPublisher(publisher); updateTracerSettings(); enabled = true; } /** {@inheritDoc} */ @Override public final synchronized boolean removeLogPublisher( DebugLogPublisher<DebugLogPublisherCfg> publisher) { boolean removed = loggerStorage.removeLogPublisher(publisher); updateTracerSettings(); enabled = !loggerStorage.getLogPublishers().isEmpty(); return removed; } /** {@inheritDoc} */ @Override public final synchronized void removeAllLogPublishers() { loggerStorage.removeAllLogPublishers(); updateTracerSettings(); enabled = false; } }