/* * The contents of this file are subject to the terms of the Common Development and * Distribution License (the License). You may not use this file except in compliance with the * License. * * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the * specific language governing permission and limitations under the License. * * When distributing Covered Software, include this CDDL Header Notice in each file and include * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL * Header, with the fields enclosed by brackets [] replaced by your own identifying * information: "Portions Copyright [year] [name of copyright owner]". * * Copyright 2014-2015 ForgeRock AS. */ package org.opends.server.loggers.slf4j; import static org.opends.messages.ExternalMessages.INFO_EXTERNAL_LIB_MESSAGE; import org.forgerock.i18n.LocalizableMessage; import org.forgerock.i18n.slf4j.LocalizedMarker; import org.opends.messages.Severity; import org.opends.server.loggers.DebugLogger; import org.opends.server.loggers.DebugTracer; import org.opends.server.loggers.ErrorLogger; import org.opends.server.loggers.LoggingCategoryNames; import org.slf4j.Logger; import org.slf4j.Marker; import org.slf4j.helpers.MessageFormatter; /** * OpenDJ implementation of a SLF4J Logger. *
* Log calls at trace level are redirected to {@code DebugLogger}, while calls * at other levels are redirected to {@code ErrorLogger}. *
* Trace-level calls do no expect a Marker argument. The marker argument is ignored if provided. *
* Example of expected trace-level call:
* logger.trace("This is an error message");
*
* * Non trace-level calls expect a Marker argument that is an instance of * {@code LocalizedMarker}. This is the standard way for OpenDJ code. *
* Example of expected non trace-level call: * LocalizableMessage message = ... * logger.error(new LocalizedMarker(message), message.toString(locale), t); **
* Note that these methods are never called directly from OpenDJ. * Instead, OpenDJ code instantiates a LocalizedLogger * which then delegates to the underlying SLF4J logger. *
* For third party libraries (e.g commons-audit, grizzly), * messages with trace and debug level will end in the debug logger. * Messages with other levels will end in the error logger. */ final class OpenDJLoggerAdapter implements Logger { /** Name of logger, used as the category. */ private final String name; /** The tracer associated to this logger. */ private final DebugTracer tracer; /** * Creates a new logger with the provided name. * * @param name * The name of logger. */ public OpenDJLoggerAdapter(final String name) { // Tracer always use the provided name // which should be a classname this.tracer = DebugLogger.getTracer(name); // Name is simplified if possible this.name = LoggingCategoryNames.getCategoryName(name); } @Override public String getName() { return name; } /** Format a message containing '{}' as arguments placeholder. */ private String formatMessage(String message, Object...args) { if (args == null || args.length == 0) { return message; } return MessageFormatter.arrayFormat(message, args).getMessage(); } /** Trace with message only. */ private void publishInDebugLogger(String msg) { tracer.trace(msg); } /** Trace with message and exception. */ private void publishInDebugLogger(String message, Throwable t) { tracer.traceException(message, t); } /** * Log a message to {@code ErrorLogger} with the provided severity. *
* If this method is called from OpenDJ libraries, * extracting {code LocalizableMessage} from the provided {code Marker marker} argument, * otherwise log the provided {@param message}. * * @param marker * The marker, expected to be an instance of * {@code LocalizedMarker} class, from which message to log is * extracted. * @param message * The message to log if this logger is called by external libraries. * @param severity * The severity to use when logging message. * @param throwable * Exception to log. May be {@code null}. */ private void publish(Marker marker, String message, Severity severity, Throwable throwable) { if (marker instanceof LocalizedMarker) { // OpenDJ logs with all severity levels but trace. publishInErrorLogger(((LocalizedMarker) marker).getMessage(), severity, throwable); } else if (severity == Severity.DEBUG) { // Third party messages with debug level go to the debug logger. publishInDebugLogger(message, throwable); } else { // Other Third party messages. publishInErrorLogger(message, severity, throwable); } } /** * Log a message to {@code ErrorLogger} with the provided message and severity. *
* This should be avoided, but when using an external library there can be calls * with a String. * * @param message * The message as string. * @param severity * The severity to use when logging message. * @param throwable * Exception to log. May be {@code null}. */ private void publishInErrorLogger(String message, Severity severity, Throwable throwable) { // Use a LocalizedMessage template instead of raw() to avoid null message resource name and ID in logs. publishInErrorLogger(INFO_EXTERNAL_LIB_MESSAGE.get(message), severity, throwable); } private void publishInErrorLogger(LocalizableMessage localizableMessage, Severity severity, Throwable throwable) { ErrorLogger.log(name, severity, localizableMessage, throwable); } @Override public boolean isTraceEnabled() { return DebugLogger.debugEnabled() && tracer.enabled(); } @Override public void trace(String msg) { if (isTraceEnabled()) { publishInDebugLogger(msg); } } @Override public void trace(Marker marker, String msg) { if (isTraceEnabled()) { publishInDebugLogger(msg); } } @Override public void trace(String msg, Throwable t) { if (isTraceEnabled()) { publishInDebugLogger(msg, t); } } @Override public void trace(Marker marker, String msg, Throwable t) { if (isTraceEnabled()) { publishInDebugLogger(msg, t); } } @Override public boolean isDebugEnabled() { return ErrorLogger.isEnabledFor(name, Severity.INFORMATION); } @Override public void debug(Marker marker, String msg) { if (isDebugEnabled()) { publish(marker, msg, Severity.INFORMATION, null); } } @Override public void debug(Marker marker, String msg, Throwable t) { if (isDebugEnabled()) { publish(marker, msg, Severity.INFORMATION, t); } } @Override public boolean isInfoEnabled() { return ErrorLogger.isEnabledFor(name, Severity.NOTICE); } @Override public void info(Marker marker, String msg) { if (isInfoEnabled()) { publish(marker, msg, Severity.NOTICE, null); } } @Override public void info(Marker marker, String msg, Throwable t) { if (isInfoEnabled()) { publish(marker, msg, Severity.NOTICE, t); } } @Override public boolean isWarnEnabled() { return ErrorLogger.isEnabledFor(name, Severity.WARNING); } @Override public void warn(Marker marker, String msg) { if (isWarnEnabled()) { publish(marker, msg, Severity.WARNING, null); } } @Override public void warn(Marker marker, String msg, Throwable t) { if (isWarnEnabled()) { publish(marker, msg, Severity.WARNING, t); } } @Override public boolean isErrorEnabled() { return ErrorLogger.isEnabledFor(name, Severity.ERROR); } @Override public void error(Marker marker, String msg) { if (isErrorEnabled()) { publish(marker, msg, Severity.ERROR, null); } } @Override public void error(Marker marker, String msg, Throwable t) { if (isErrorEnabled()) { publish(marker, msg, Severity.ERROR, t); } } @Override public boolean isTraceEnabled(Marker marker) { return isTraceEnabled(); } @Override public boolean isDebugEnabled(Marker marker) { return isDebugEnabled(); } @Override public boolean isInfoEnabled(Marker marker) { return isInfoEnabled(); } @Override public boolean isWarnEnabled(Marker marker) { return isWarnEnabled(); } @Override public boolean isErrorEnabled(Marker marker) { return isErrorEnabled(); } @Override public void trace(String message, Object arg) { if (isTraceEnabled()) { publishInDebugLogger(formatMessage(message, arg)); } } @Override public void trace(String message, Object arg1, Object arg2) { if (isTraceEnabled()) { publishInDebugLogger(formatMessage(message, arg1, arg2)); } } @Override public void trace(String message, Object... argArray) { if (isTraceEnabled()) { publishInDebugLogger(formatMessage(message, argArray)); } } @Override public void trace(Marker marker, String message, Object arg) { if (isTraceEnabled()) { publishInDebugLogger(formatMessage(message, arg)); } } @Override public void trace(Marker marker, String message, Object arg1, Object arg2) { if (isTraceEnabled()) { publishInDebugLogger(formatMessage(message, arg1, arg2)); } } @Override public void trace(Marker marker, String message, Object... argArray) { if (isTraceEnabled()) { publishInDebugLogger(formatMessage(message, argArray)); } } // Methods below should only by used by third-party libraries. // Such third-party libraries include, but are not limited to: commons-audit, grizzly, etc. @Override public void debug(String msg, Throwable t) { if (isDebugEnabled()) { publishInDebugLogger(formatMessage(msg, (Object[]) null), t); } } @Override public void debug(String msg) { if (isDebugEnabled()) { publishInDebugLogger(formatMessage(msg, (Object[]) null), null); } } @Override public void debug(String message, Object arg) { if (isDebugEnabled()) { publishInDebugLogger(formatMessage(message, arg), null); } } @Override public void debug(String message, Object arg1, Object arg2) { if (isDebugEnabled()) { publishInDebugLogger(formatMessage(message, arg1, arg2), null); } } @Override public void debug(String message, Object... argArray) { if (isDebugEnabled()) { publishInDebugLogger(formatMessage(message, argArray), null); } } @Override public void debug(Marker marker, String message, Object arg) { if (isDebugEnabled()) { publishInDebugLogger(formatMessage(message, arg), null); } } @Override public void debug(Marker marker, String message, Object arg1, Object arg2) { if (isDebugEnabled()) { publishInDebugLogger(formatMessage(message, arg1, arg2), null); } } @Override public void debug(Marker marker, String message, Object... arguments) { if (isDebugEnabled()) { publishInDebugLogger(formatMessage(message, arguments), null); } } @Override public void info(String msg, Throwable t) { if (isInfoEnabled()) { publishInErrorLogger(formatMessage(msg, (Object[]) null), Severity.INFORMATION, t); } } @Override public void info(String msg) { if (isInfoEnabled()) { publishInErrorLogger(formatMessage(msg, (Object[]) null), Severity.INFORMATION, null); } } @Override public void info(String message, Object arg) { if (isInfoEnabled()) { publishInErrorLogger(formatMessage(message, arg), Severity.INFORMATION, null); } } @Override public void info(String message, Object arg1, Object arg2) { if (isInfoEnabled()) { publishInErrorLogger(formatMessage(message, arg1, arg2), Severity.INFORMATION, null); } } @Override public void info(String message, Object... argArray) { if (isInfoEnabled()) { publishInErrorLogger(formatMessage(message, argArray), Severity.INFORMATION, null); } } @Override public void info(Marker marker, String message, Object arg) { if (isInfoEnabled()) { publishInErrorLogger(formatMessage(message, arg), Severity.INFORMATION, null); } } @Override public void info(Marker marker, String message, Object arg1, Object arg2) { if (isInfoEnabled()) { publishInErrorLogger(formatMessage(message, arg1, arg2), Severity.INFORMATION, null); } } @Override public void info(Marker marker, String message, Object... arguments) { if (isInfoEnabled()) { publishInErrorLogger(formatMessage(message, arguments), Severity.INFORMATION, null); } } @Override public void warn(String msg, Throwable t) { if (isWarnEnabled()) { publishInErrorLogger(formatMessage(msg, (Object[]) null), Severity.WARNING, t); } } @Override public void warn(String msg) { if (isWarnEnabled()) { publishInErrorLogger(formatMessage(msg, (Object[]) null), Severity.WARNING, null); } } @Override public void warn(String message, Object arg) { if (isWarnEnabled()) { publishInErrorLogger(formatMessage(message, arg), Severity.WARNING, null); } } @Override public void warn(String message, Object arg1, Object arg2) { if (isWarnEnabled()) { publishInErrorLogger(formatMessage(message, arg1, arg2), Severity.WARNING, null); } } @Override public void warn(String message, Object... argArray) { if (isWarnEnabled()) { publishInErrorLogger(formatMessage(message, argArray), Severity.WARNING, null); } } @Override public void warn(Marker marker, String message, Object arg) { if (isWarnEnabled()) { publishInErrorLogger(formatMessage(message, arg), Severity.WARNING, null); } } @Override public void warn(Marker marker, String message, Object arg1, Object arg2) { if (isWarnEnabled()) { publishInErrorLogger(formatMessage(message, arg1, arg2), Severity.WARNING, null); } } @Override public void warn(Marker marker, String message, Object... arguments) { if (isWarnEnabled()) { publishInErrorLogger(formatMessage(message, arguments), Severity.WARNING, null); } } @Override public void error(String msg, Throwable t) { if (isErrorEnabled()) { publishInErrorLogger(formatMessage(msg, (Object[]) null), Severity.ERROR, t); } } @Override public void error(String msg) { if (isErrorEnabled()) { publishInErrorLogger(formatMessage(msg, Severity.ERROR, null), Severity.ERROR, null); } } @Override public void error(String message, Object arg) { if (isErrorEnabled()) { publishInErrorLogger(formatMessage(message, arg), Severity.ERROR, null); } } @Override public void error(String message, Object arg1, Object arg2) { if (isErrorEnabled()) { publishInErrorLogger(formatMessage(message, arg1, arg2), Severity.ERROR, null); } } @Override public void error(String message, Object... arguments) { if (isErrorEnabled()) { publishInErrorLogger(formatMessage(message, arguments), Severity.ERROR, null); } } @Override public void error(Marker marker, String message, Object arg) { if (isErrorEnabled()) { publishInErrorLogger(formatMessage(message, arg), Severity.ERROR, null); } } @Override public void error(Marker marker, String message, Object arg1, Object arg2) { if (isErrorEnabled()) { publishInErrorLogger(formatMessage(message, arg1, arg2), Severity.ERROR, null); } } @Override public void error(Marker marker, String message, Object... arguments) { if (isErrorEnabled()) { publishInErrorLogger(formatMessage(message, arguments), Severity.ERROR, null); } } }