org.eclipse.persistence.logging.slf4j.SLF4JLogger Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of eclipselink Show documentation
Show all versions of eclipselink Show documentation
EclipseLink build based upon Git transaction f2b9fc5
/*
* Copyright (c) 2009, 2018 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0,
* or the Eclipse Distribution License v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
// Contributors:
// Jaro Kuruc - Initial API and implementation.
// Tomas Kraus - EclipseLink 2.7 integration.
package org.eclipse.persistence.logging.slf4j;
import java.security.AccessController;
import org.eclipse.persistence.config.PersistenceUnitProperties;
import org.eclipse.persistence.internal.security.PrivilegedAccessHelper;
import org.eclipse.persistence.internal.security.PrivilegedGetSystemProperty;
import org.eclipse.persistence.logging.AbstractSessionLog;
import org.eclipse.persistence.logging.LogCategory;
import org.eclipse.persistence.logging.LogLevel;
import org.eclipse.persistence.logging.SessionLogEntry;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* EclipseLink logger bridge over SLF4J.
*/
public class SLF4JLogger extends AbstractSessionLog {
/** Logger callback interface. */
private static interface LoggerCall {
void log(final Logger logger, final String msg, final Throwable t);
void log(final Logger logger, final String message);
}
/** {@code TRACE} level log. */
private static final class LogTrace implements LoggerCall {
@Override
public void log(final Logger logger, final String msg, final Throwable t) {
logger.trace(msg, t);
}
@Override
public void log(final Logger logger, final String message) {
logger.trace(message);
}
}
/** {@code DEBUG} level log. */
private static final class LogDebug implements LoggerCall {
@Override
public void log(final Logger logger, final String msg, final Throwable t) {
logger.debug(msg, t);
}
@Override
public void log(final Logger logger, final String message) {
logger.debug(message);
}
}
/** {@code INFO} level log. */
private static final class LogInfo implements LoggerCall {
@Override
public void log(final Logger logger, final String msg, final Throwable t) {
logger.info(msg, t);
}
@Override
public void log(final Logger logger, final String message) {
logger.info(message);
}
}
/** {@code WARN} level log. */
private static final class LogWarn implements LoggerCall {
@Override
public void log(final Logger logger, final String msg, final Throwable t) {
logger.warn(msg, t);
}
@Override
public void log(final Logger logger, final String message) {
logger.warn(message);
}
}
/** {@code ERROR} level log. */
private static final class LogError implements LoggerCall {
@Override
public void log(final Logger logger, final String msg, final Throwable t) {
logger.error(msg, t);
}
@Override
public void log(final Logger logger, final String message) {
logger.error(message);
}
}
/** Do not log anything. */
private static final class LogNop implements LoggerCall {
@Override
public void log(final Logger logger, final String msg, final Throwable t) {
}
@Override
public void log(final Logger logger, final String message) {
}
}
/** The default session name in case there is session name is missing. */
public static final String ECLIPSELINK_NAMESPACE = "org.eclipse.persistence";
/** SLF4J logger calls mapping for EclipseLink logging levels. */
private static final LoggerCall[] loggerCall = new LoggerCall[LogLevel.length];
/** Loggers lookup array. */
private static final Logger[] categoryLoggers = new Logger[LogCategory.length];
static {
// Initialize loggers lookup array.
for (int i = 0; i < LogCategory.length; i++) {
categoryLoggers[i] = null;
}
// Initialize SLF4J logger calls mapping for EclipseLink logging levels.
loggerCall[LogLevel.ALL.getId()] = loggerCall[LogLevel.FINEST.getId()] = new LogTrace();
loggerCall[LogLevel.FINER.getId()] = loggerCall[LogLevel.FINE.getId()] = new LogDebug();
loggerCall[LogLevel.CONFIG.getId()] = loggerCall[LogLevel.INFO.getId()] = new LogInfo();
loggerCall[LogLevel.WARNING.getId()] = new LogWarn();
loggerCall[LogLevel.SEVERE.getId()] = new LogError();
loggerCall[LogLevel.OFF.getId()] = new LogNop();
}
/**
* Retrieve Logger for the given category.
* @param category EclipseLink logging category
* @return Logger for the given logging category.
*/
private static Logger getLogger(final LogCategory category) {
final Logger logger = categoryLoggers[category.getId()];
if (logger != null) {
return logger;
}
return categoryLoggers[category.getId()] = LoggerFactory.getLogger(category.getNameSpace());
}
/** Logging levels for individual logging categories. */
private final LogLevel[] logLevels;
/**
* Creates an instance of EclipseLink logger bridge over SLF4J
*/
public SLF4JLogger() {
super();
// Set default logging levels for all logging categories.
final byte defaultLevel = LogLevel.toValue(level).getId();
logLevels = new LogLevel[LogCategory.length];
for (LogCategory category : LogCategory.values()) {
final int i = category.getId();
switch(category) {
case ALL:
logLevels[i] = LogLevel.toValue(defaultLevel);
break;
default:
final String property = PersistenceUnitProperties.CATEGORY_LOGGING_LEVEL_ + category.getName();
final String logLevelStr = PrivilegedAccessHelper.shouldUsePrivilegedAccess()
? AccessController.doPrivileged(new PrivilegedGetSystemProperty(property))
: System.getProperty(property);
logLevels[i] = LogLevel.toValue(
logLevelStr != null ? translateStringToLoggingLevel(logLevelStr) : defaultLevel);
}
}
}
/**
* Get the logging level for the default logging category.
* @return level Current logging level for default the default logging category.
*/
@Override
public int getLevel() {
return logLevels[LogCategory.ALL.getId()].getId();
}
/**
* Get the logging level for the specified logging category.
* @param categoryName The {@link String} representation of an EclipseLink logging category.
* @return level Current logging level for default the default logging category.
*/
@Override
public int getLevel(final String categoryName) {
final LogCategory category = LogCategory.toValue(categoryName);
if (category == null) {
throw new IllegalArgumentException("Unknown logging category name.");
}
return logLevels[category.getId()].getId();
}
/**
* Set the logging level for the default logging category.
* @param level The logging level to be set.
*/
@Override
public void setLevel(final int level) {
super.setLevel(level);
logLevels[LogCategory.ALL.getId()] = LogLevel.toValue(level);
// TODO: Handle logging levels on SLF4J side too.
}
/**
* Set the logging level for the specified logging category.
* @param level The logging level to be set.
* @param categoryName The {@link String} representation of an EclipseLink logging category.
*/
@Override
public void setLevel(final int level, final String categoryName) {
final LogCategory category = LogCategory.toValue(categoryName);
if (category == null) {
throw new IllegalArgumentException("Unknown logging category name.");
}
logLevels[category.getId()] = LogLevel.toValue(level);
// TODO: Handle logging levels on SLF4J side too.
}
/**
* Check if a message of the given level would actually be logged under logging level for the default logging
* category.
* @param level Message logging level.
* @return Value of {@code true} if the given message logging level will be logged or {@code false} otherwise.
*/
@Override
public boolean shouldLog(final int level) {
return logLevels[LogCategory.ALL.getId()].shouldLog((byte)level);
}
/**
* Check if a message of the given level would actually be logged under logging level for the specified logging
* category.
* @param level Message logging level.
* @param categoryName The {@link String} representation of an EclipseLink logging category.
* @return Value of {@code true} if the given message logging level will be logged or {@code false} otherwise.
*/
@Override
public boolean shouldLog(final int level, final String categoryName) {
final LogCategory category = LogCategory.toValue(categoryName);
if (category == null) {
throw new IllegalArgumentException("Unknown logging category name.");
}
return logLevels[category.getId()].shouldLog((byte)level);
}
/**
* {@inheritDoc}
*/
@Override
public void log(final SessionLogEntry logEntry) {
if (logEntry == null) {
return;
}
final LogCategory category = LogCategory.toValue(logEntry.getNameSpace());
if (category == null) {
throw new IllegalArgumentException("Unknown logging category name.");
}
final byte levelId = (byte)logEntry.getLevel();
if (logLevels[category.getId()].shouldLog(levelId)) {
final LogLevel level = LogLevel.toValue(levelId);
final Logger logger = getLogger(category);
if (logEntry.hasException()) {
if (shouldLogExceptionStackTrace()) {
// Message is rendered on EclipseLink side. SLF4J gets final String. Exception is passed too.
loggerCall[level.getId()].log(logger, formatMessage(logEntry), logEntry.getException());
} else {
// Exception message is rendered on EclipseLink side. SLF4J gets final String.
loggerCall[level.getId()].log(logger, logEntry.getException().toString());
}
} else {
// Message is rendered on EclipseLink side. SLF4J gets final String.
loggerCall[level.getId()].log(logger, formatMessage(logEntry));
}
}
}
}