org.refcodes.logger.alt.slf4j.Slf4jRuntimeLogger Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of refcodes-logger-alt-slf4j Show documentation
Show all versions of refcodes-logger-alt-slf4j Show documentation
Artifact for slf4j (verion >= 2.0) based logging with the refoces logger framework.
// /////////////////////////////////////////////////////////////////////////////
// REFCODES.ORG
// /////////////////////////////////////////////////////////////////////////////
// This code is copyright (c) by Siegfried Steiner, Munich, Germany, distributed
// on an "AS IS" BASIS WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, and licen-
// sed under the following (see "http://en.wikipedia.org/wiki/Multi-licensing")
// licenses:
// -----------------------------------------------------------------------------
// GNU General Public License, v3.0 ("http://www.gnu.org/licenses/gpl-3.0.html")
// -----------------------------------------------------------------------------
// Apache License, v2.0 ("http://www.apache.org/licenses/TEXT-2.0")
// -----------------------------------------------------------------------------
// Please contact the copyright holding author(s) of the software artifacts in
// question for licensing issues not being covered by the above listed licenses,
// also regarding commercial licensing models or regarding the compatibility
// with other open source licenses.
// /////////////////////////////////////////////////////////////////////////////
package org.refcodes.logger.alt.slf4j;
import java.text.MessageFormat;
import org.refcodes.logger.LogPriority;
import org.refcodes.logger.RuntimeLogger;
import org.refcodes.logger.RuntimeLoggerAccessor;
import org.refcodes.logger.RuntimeLoggerImpl;
import org.refcodes.logger.RuntimeLoggerSingleton;
import org.refcodes.mixin.NameAccessor.NameProperty;
import org.refcodes.runtime.Execution;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Alternate implementation of the {@link RuntimeLogger} to log using SLF4J.
*/
public class Slf4jRuntimeLogger implements RuntimeLogger, NameProperty {
// /////////////////////////////////////////////////////////////////////////
// CONSTANTS:
// /////////////////////////////////////////////////////////////////////////
private static final String[] LOGGER_PACKAGE_PARTS = new String[] { ".log.", ".logger.", ".logging.", "org.refcodes.struct.", "org.refcodes.properties." };
// /////////////////////////////////////////////////////////////////////////
// VARIABLES:
// /////////////////////////////////////////////////////////////////////////
private transient Logger _logger = null;
private transient RuntimeLogger _runtimeLogger = null;
// /////////////////////////////////////////////////////////////////////////
// CONSTRUCTORS:
// /////////////////////////////////////////////////////////////////////////
/**
* In case the {@link Slf4jRuntimeLogger} (as created by the
* {@link Slf4jRuntimeLoggerFactorySingleton}) detects that SLF4J has bound
* a SLF4J RuntimeLoggerAdapterImpl
(see
* refcodes-logger-ext-slf4j
, the REFCODES.ORG SLF4J binding)
* (i.e. the REFCODES.ORG SLF4J binding), it directly delegates its method
* calls to the wrapped {@link RuntimeLogger} instead of marshaling a log
* request through the SLF4J RuntimeLoggerAdapterImpl
; as
* marshaling would mean consolidating of various detailed
* {@link LogPriority} levels to a single SLF4J log level.
*/
public Slf4jRuntimeLogger() {
final Class> theCallees[] = new Class>[] { Slf4jRuntimeLoggerFactory.class, RuntimeLoggerImpl.class, RuntimeLogger.class, RuntimeLoggerSingleton.class, Slf4jLogger.class };
StackTraceElement theCaller = Execution.toHeurisitcCallerStackTraceElement( theCallees );
theCaller = probeTillNoneLoggerElement( theCaller );
final String theClassName = theCaller.getClassName();
setName( theClassName );
}
/**
* In case the {@link Slf4jRuntimeLogger} (as created by the
* {@link Slf4jRuntimeLoggerFactorySingleton}) detects that SLF4J has bound
* a SLF4J RuntimeLoggerAdapterImpl
(see
* refcodes-logger-ext-slf4j
, the REFCODES.ORG SLF4J binding),
* it directly delegates its method calls to the wrapped
* {@link RuntimeLogger} instead of marshaling a log request through the
* SLF4J RuntimeLoggerAdapterImpl
as marshaling would mean
* consolidating of various detailed {@link LogPriority} levels to a single
* SLF4J log level.
*
* @param aLogger the logger to use SLF4J for logging.
*/
public Slf4jRuntimeLogger( Logger aLogger ) {
toRuntimeLogger( aLogger );
}
// /////////////////////////////////////////////////////////////////////////
// METHODS:
// /////////////////////////////////////////////////////////////////////////
/**
* {@inheritDoc}
*/
@Override
public void log( LogPriority aPriority, String aMessage ) {
if ( _runtimeLogger != null ) {
_runtimeLogger.log( aPriority, aMessage );
}
else {
switch ( aPriority ) {
case PANIC -> _logger.error( aMessage );
case ALERT -> _logger.error( aMessage );
case CRITICAL -> _logger.error( aMessage );
case ERROR -> _logger.error( aMessage );
case WARN -> _logger.warn( aMessage );
case NOTICE -> _logger.info( aMessage );
case INFO -> _logger.info( aMessage );
case DEBUG -> _logger.debug( aMessage );
case TRACE -> _logger.trace( aMessage );
case DISCARD -> {
}
case NONE -> _logger.info( aMessage );
default -> _logger.info( aMessage );
}
}
}
/**
* {@inheritDoc}
*/
@Override
public void log( LogPriority aPriority, String aMessage, Object... aArguments ) {
if ( _runtimeLogger != null ) {
_runtimeLogger.log( aPriority, aMessage, aArguments );
}
else {
switch ( aPriority ) {
case PANIC -> _logger.error( MessageFormat.format( aMessage, aArguments ) );
case ALERT -> _logger.error( MessageFormat.format( aMessage, aArguments ) );
case CRITICAL -> _logger.error( MessageFormat.format( aMessage, aArguments ) );
case ERROR -> _logger.error( MessageFormat.format( aMessage, aArguments ) );
case WARN -> _logger.warn( MessageFormat.format( aMessage, aArguments ) );
case NOTICE -> _logger.info( MessageFormat.format( aMessage, aArguments ) );
case INFO -> _logger.info( MessageFormat.format( aMessage, aArguments ) );
case DEBUG -> _logger.debug( MessageFormat.format( aMessage, aArguments ) );
case TRACE -> _logger.trace( MessageFormat.format( aMessage, aArguments ) );
case DISCARD -> {
}
case NONE -> _logger.info( MessageFormat.format( aMessage, aArguments ) );
default -> _logger.info( MessageFormat.format( aMessage, aArguments ) );
}
}
}
/**
* {@inheritDoc}
*/
@Override
public String getName() {
if ( _runtimeLogger != null ) {
return _runtimeLogger.getName();
}
else {
return _logger.getName();
}
}
/**
* {@inheritDoc}
*/
@Override
public void setName( String aName ) {
final Logger aLogger = LoggerFactory.getLogger( aName );
toRuntimeLogger( aLogger );
}
/**
* {@inheritDoc}
*/
@Override
public LogPriority getLogPriority() {
if ( _runtimeLogger != null ) {
return _runtimeLogger.getLogPriority();
}
else {
if ( _logger.isDebugEnabled() ) {
return LogPriority.DEBUG;
}
if ( _logger.isErrorEnabled() ) {
return LogPriority.ERROR;
}
if ( _logger.isInfoEnabled() ) {
return LogPriority.INFO;
}
if ( _logger.isTraceEnabled() ) {
return LogPriority.TRACE;
}
return _logger.isWarnEnabled() ? LogPriority.WARN : LogPriority.NONE;
}
}
/**
* {@inheritDoc}
*/
@Override
public void log( LogPriority aPriority, String aMessage, Throwable aThrowable ) {
if ( _runtimeLogger != null ) {
_runtimeLogger.log( aPriority, aMessage, aThrowable );
}
else {
switch ( aPriority ) {
case PANIC -> _logger.error( aMessage, aThrowable );
case ALERT -> _logger.error( aMessage, aThrowable );
case CRITICAL -> _logger.error( aMessage, aThrowable );
case ERROR -> _logger.error( aMessage, aThrowable );
case WARN -> _logger.warn( aMessage, aThrowable );
case NOTICE -> _logger.info( aMessage, aThrowable );
case INFO -> _logger.info( aMessage, aThrowable );
case DEBUG -> _logger.debug( aMessage, aThrowable );
case TRACE -> _logger.trace( aMessage, aThrowable );
case DISCARD -> {
}
case NONE -> _logger.info( aMessage, aThrowable );
default -> _logger.info( aMessage, aThrowable );
}
}
}
/**
* {@inheritDoc}
*/
@Override
public void log( LogPriority aPriority, String aMessage, Throwable aThrowable, Object... aArguments ) {
if ( _runtimeLogger != null ) {
_runtimeLogger.log( aPriority, aMessage, aThrowable, aArguments );
}
else {
switch ( aPriority ) {
case PANIC -> {
if ( _logger.isErrorEnabled() ) {
_logger.error( MessageFormat.format( aMessage, aArguments ), aThrowable );
}
}
case ALERT -> {
if ( _logger.isErrorEnabled() ) {
_logger.error( MessageFormat.format( aMessage, aArguments ), aThrowable );
}
}
case CRITICAL -> {
if ( _logger.isErrorEnabled() ) {
_logger.error( MessageFormat.format( aMessage, aArguments ), aThrowable );
}
}
case ERROR -> {
if ( _logger.isErrorEnabled() ) {
_logger.error( MessageFormat.format( aMessage, aArguments ), aThrowable );
}
}
case WARN -> {
if ( _logger.isWarnEnabled() ) {
_logger.warn( MessageFormat.format( aMessage, aArguments ), aThrowable );
}
}
case NOTICE -> {
if ( _logger.isInfoEnabled() ) {
_logger.info( MessageFormat.format( aMessage, aArguments ), aThrowable );
}
}
case INFO -> {
if ( _logger.isInfoEnabled() ) {
_logger.info( MessageFormat.format( aMessage, aArguments ), aThrowable );
}
}
case DEBUG -> {
if ( _logger.isDebugEnabled() ) {
_logger.debug( MessageFormat.format( aMessage, aArguments ), aThrowable );
}
}
case TRACE -> {
if ( _logger.isTraceEnabled() ) {
_logger.trace( MessageFormat.format( aMessage, aArguments ), aThrowable );
}
}
case DISCARD -> {
}
case NONE -> {
if ( _logger.isInfoEnabled() ) {
_logger.info( MessageFormat.format( aMessage, aArguments ), aThrowable );
}
}
default -> {
if ( _logger.isInfoEnabled() ) {
_logger.info( MessageFormat.format( aMessage, aArguments ), aThrowable );
}
}
}
}
}
/**
* {@inheritDoc}
*/
@Override
public boolean isLog( LogPriority aPriority ) {
if ( _runtimeLogger != null ) {
return _runtimeLogger.isLog( aPriority );
}
else {
return aPriority.getPriority() >= getLogPriority().getPriority() && aPriority.getPriority() >= 0;
}
}
/**
* {@inheritDoc}
*/
@Override
public void trace( String aMessage ) {
if ( _runtimeLogger != null ) {
_runtimeLogger.trace( aMessage );
}
else {
_logger.trace( aMessage );
}
}
/**
* {@inheritDoc}
*/
@Override
public void trace( String aMessage, Object... aArguments ) {
if ( _runtimeLogger != null ) {
_runtimeLogger.trace( MessageFormat.format( aMessage, aArguments ) );
}
else {
_logger.trace( MessageFormat.format( aMessage, aArguments ) );
}
}
/**
* {@inheritDoc}
*/
@Override
public boolean isLogTrace() {
if ( _runtimeLogger != null ) {
return _runtimeLogger.isLogTrace();
}
else {
return isLog( LogPriority.TRACE );
}
}
/**
* {@inheritDoc}
*/
@Override
public void debug( String aMessage ) {
if ( _runtimeLogger != null ) {
_runtimeLogger.debug( aMessage );
}
else {
_logger.debug( aMessage );
}
}
/**
* {@inheritDoc}
*/
@Override
public void debug( String aMessage, Object... aArguments ) {
if ( _runtimeLogger != null ) {
_runtimeLogger.debug( MessageFormat.format( aMessage, aArguments ) );
}
else {
_logger.debug( MessageFormat.format( aMessage, aArguments ) );
}
}
/**
* {@inheritDoc}
*/
@Override
public boolean isLogDebug() {
if ( _runtimeLogger != null ) {
return _runtimeLogger.isLogDebug();
}
else {
return isLog( LogPriority.DEBUG );
}
}
/**
* {@inheritDoc}
*/
@Override
public void info( String aMessage ) {
if ( _runtimeLogger != null ) {
_runtimeLogger.info( aMessage );
}
else {
_logger.info( aMessage );
}
}
/**
* {@inheritDoc}
*/
@Override
public void info( String aMessage, Object... aArguments ) {
if ( _runtimeLogger != null ) {
_runtimeLogger.info( MessageFormat.format( aMessage, aArguments ) );
}
else {
_logger.info( MessageFormat.format( aMessage, aArguments ) );
}
}
/**
* {@inheritDoc}
*/
@Override
public boolean isLogInfo() {
if ( _runtimeLogger != null ) {
return _runtimeLogger.isLogInfo();
}
else {
return isLog( LogPriority.INFO );
}
}
/**
* {@inheritDoc}
*/
@Override
public void notice( String aMessage ) {
if ( _runtimeLogger != null ) {
_runtimeLogger.notice( aMessage );
}
else {
_logger.info( aMessage );
}
}
/**
* {@inheritDoc}
*/
@Override
public void notice( String aMessage, Object... aArguments ) {
if ( _runtimeLogger != null ) {
_runtimeLogger.notice( MessageFormat.format( aMessage, aArguments ) );
}
else {
_logger.info( MessageFormat.format( aMessage, aArguments ) );
}
}
/**
* {@inheritDoc}
*/
@Override
public boolean isLogNotice() {
if ( _runtimeLogger != null ) {
return _runtimeLogger.isLogNotice();
}
else {
return isLog( LogPriority.NOTICE );
}
}
/**
* {@inheritDoc}
*/
@Override
public void warn( String aMessage ) {
if ( _runtimeLogger != null ) {
_runtimeLogger.warn( aMessage );
}
else {
_logger.warn( aMessage );
}
}
/**
* {@inheritDoc}
*/
@Override
public void warn( String aMessage, Object... aArguments ) {
if ( _runtimeLogger != null ) {
_runtimeLogger.warn( MessageFormat.format( aMessage, aArguments ) );
}
else {
_logger.warn( MessageFormat.format( aMessage, aArguments ) );
}
}
/**
* {@inheritDoc}
*/
@Override
public void warn( String aMessage, Throwable aThrowable ) {
if ( _runtimeLogger != null ) {
_runtimeLogger.warn( aMessage, aThrowable );
}
else {
_logger.warn( aMessage, aThrowable );
}
}
/**
* {@inheritDoc}
*/
@Override
public void warn( String aMessage, Throwable aThrowable, Object... aArguments ) {
if ( _runtimeLogger != null ) {
_runtimeLogger.warn( MessageFormat.format( aMessage, aArguments ) );
}
else {
_logger.warn( MessageFormat.format( aMessage, aArguments ), aThrowable );
}
}
/**
* {@inheritDoc}
*/
@Override
public boolean isLogWarn() {
if ( _runtimeLogger != null ) {
return _runtimeLogger.isLogWarn();
}
else {
return isLog( LogPriority.WARN );
}
}
/**
* {@inheritDoc}
*/
@Override
public void error( String aMessage ) {
if ( _runtimeLogger != null ) {
_runtimeLogger.error( aMessage );
}
else {
_logger.error( aMessage );
}
}
/**
* {@inheritDoc}
*/
@Override
public void error( String aMessage, Object... aArguments ) {
if ( _runtimeLogger != null ) {
_runtimeLogger.error( MessageFormat.format( aMessage, aArguments ) );
}
else {
_logger.error( MessageFormat.format( aMessage, aArguments ) );
}
}
/**
* {@inheritDoc}
*/
@Override
public void error( String aMessage, Throwable aThrowable ) {
if ( _runtimeLogger != null ) {
_runtimeLogger.error( aMessage, aThrowable );
}
else {
_logger.error( aMessage, aThrowable );
}
}
/**
* {@inheritDoc}
*/
@Override
public void error( String aMessage, Throwable aThrowable, Object... aArguments ) {
if ( _runtimeLogger != null ) {
_runtimeLogger.error( aMessage, aThrowable, aArguments );
}
else {
_logger.error( MessageFormat.format( aMessage, aArguments ), aThrowable );
}
}
/**
* {@inheritDoc}
*/
@Override
public boolean isLogError() {
if ( _runtimeLogger != null ) {
return _runtimeLogger.isLogError();
}
else {
return isLog( LogPriority.ERROR );
}
}
/**
* {@inheritDoc}
*/
@Override
public void critical( String aMessage ) {
if ( _runtimeLogger != null ) {
_runtimeLogger.critical( aMessage );
}
else {
_logger.error( aMessage );
}
}
/**
* {@inheritDoc}
*/
@Override
public void critical( String aMessage, Object... aArguments ) {
if ( _runtimeLogger != null ) {
_runtimeLogger.critical( MessageFormat.format( aMessage, aArguments ) );
}
else {
_logger.error( MessageFormat.format( aMessage, aArguments ) );
}
}
/**
* {@inheritDoc}
*/
@Override
public void critical( String aMessage, Throwable aThrowable ) {
if ( _runtimeLogger != null ) {
_runtimeLogger.critical( aMessage, aThrowable );
}
else {
_logger.error( aMessage, aThrowable );
}
}
/**
* {@inheritDoc}
*/
@Override
public void critical( String aMessage, Throwable aThrowable, Object... aArguments ) {
if ( _runtimeLogger != null ) {
_runtimeLogger.critical( aMessage, aThrowable, aArguments );
}
else {
_logger.error( MessageFormat.format( aMessage, aArguments ), aThrowable );
}
}
/**
* {@inheritDoc}
*/
@Override
public boolean isLogCritical() {
if ( _runtimeLogger != null ) {
return _runtimeLogger.isLogCritical();
}
else {
return isLog( LogPriority.CRITICAL );
}
}
/**
* {@inheritDoc}
*/
@Override
public void alert( String aMessage ) {
if ( _runtimeLogger != null ) {
_runtimeLogger.alert( aMessage );
}
else {
_logger.error( aMessage );
}
}
/**
* {@inheritDoc}
*/
@Override
public void alert( String aMessage, Object... aArguments ) {
if ( _runtimeLogger != null ) {
_runtimeLogger.alert( MessageFormat.format( aMessage, aArguments ) );
}
else {
_logger.error( MessageFormat.format( aMessage, aArguments ) );
}
}
/**
* {@inheritDoc}
*/
@Override
public void alert( String aMessage, Throwable aThrowable ) {
if ( _runtimeLogger != null ) {
_runtimeLogger.alert( aMessage, aThrowable );
}
else {
_logger.error( aMessage, aThrowable );
}
}
/**
* {@inheritDoc}
*/
@Override
public void alert( String aMessage, Throwable aThrowable, Object... aArguments ) {
if ( _runtimeLogger != null ) {
_runtimeLogger.alert( aMessage, aThrowable, aArguments );
}
else {
_logger.error( MessageFormat.format( aMessage, aArguments ), aThrowable );
}
}
/**
* {@inheritDoc}
*/
@Override
public boolean isLogAlert() {
if ( _runtimeLogger != null ) {
return _runtimeLogger.isLogAlert();
}
else {
return isLog( LogPriority.ALERT );
}
}
/**
* {@inheritDoc}
*/
@Override
public void panic( String aMessage ) {
if ( _runtimeLogger != null ) {
_runtimeLogger.panic( aMessage );
}
else {
_logger.error( aMessage );
}
}
/**
* {@inheritDoc}
*/
@Override
public void panic( String aMessage, Object... aArguments ) {
if ( _runtimeLogger != null ) {
_runtimeLogger.panic( MessageFormat.format( aMessage, aArguments ) );
}
else {
_logger.error( MessageFormat.format( aMessage, aArguments ) );
}
}
/**
* {@inheritDoc}
*/
@Override
public void panic( String aMessage, Throwable aThrowable ) {
if ( _runtimeLogger != null ) {
_runtimeLogger.panic( aMessage, aThrowable );
}
else {
_logger.error( aMessage, aThrowable );
}
}
/**
* {@inheritDoc}
*/
@Override
public void panic( String aMessage, Throwable aThrowable, Object... aArguments ) {
if ( _runtimeLogger != null ) {
_runtimeLogger.panic( aMessage, aThrowable, aArguments );
}
else {
_logger.error( MessageFormat.format( aMessage, aArguments ), aThrowable );
}
}
/**
* {@inheritDoc}
*/
@Override
public boolean isLogPanic() {
if ( _runtimeLogger != null ) {
return _runtimeLogger.isLogPanic();
}
else {
return isLog( LogPriority.PANIC );
}
}
// /////////////////////////////////////////////////////////////////////////
// HELPER:
// /////////////////////////////////////////////////////////////////////////
/**
* Returns true if the caller's class name contains any logger related
* package name part in its package path.
*
* @param aCaller The caller for which to test.
*
* @return True in case the caller's package declaration contains any logger
* package name part.
*/
private static boolean containsLoggerPackagePart( StackTraceElement aCaller ) {
final String theClassName = aCaller.getClassName();
for ( String ePart : LOGGER_PACKAGE_PARTS ) {
if ( theClassName.contains( ePart ) ) {
return true;
}
}
return false;
}
/**
* Try to skip any logging framework's factory or whatsoever
* {@link StackTraceElement} instances.
*
* @param aCaller The caller for which to skip the unwanted
* {@link StackTraceElement} instances.
*
* @return A non logging framework {@link StackTraceElement} or the one
* passed.
*/
static StackTraceElement probeTillNoneLoggerElement( StackTraceElement aCaller ) {
StackTraceElement eCaller = aCaller;
while ( eCaller != null && containsLoggerPackagePart( eCaller ) ) {
eCaller = Execution.toHeurisitcCallerStackTraceElement( eCaller );
}
if ( eCaller != null ) {
aCaller = eCaller;
}
return aCaller;
}
/**
* Tries to extract an encapsulated {@link RuntimeLogger} instance.
*
* @param aLogger the logger
*/
private void toRuntimeLogger( Logger aLogger ) {
if ( ( aLogger instanceof RuntimeLoggerAccessor ) && ( (RuntimeLoggerAccessor) aLogger ).getRuntimeLogger() != null ) {
// -----------------------------------------------------------------
// To avoid loss of priority level detail, use underlying
// RuntimeLogger where possible, the Slf4jRuntimeLoggerAdapterImpl
// provides access to the wrapped RuntimeLogger:
// -----------------------------------------------------------------
_runtimeLogger = ( (RuntimeLoggerAccessor) aLogger ).getRuntimeLogger();
}
else {
_logger = aLogger;
}
}
}