com.quartzdesk.api.agent.log.jul.JulInterceptionHandler Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of quartzdesk-api Show documentation
Show all versions of quartzdesk-api Show documentation
QuartzDesk Public API library required for QuartzDesk Standard and Enterprise edition installations. This library must be placed on the classpath of the Quartz scheduler based application that is managed by QuartzDesk. It is important that this library is loaded by the same classloader that loads the Quartz scheduler API used by the application.
/*
* Copyright (c) 2013-2019 QuartzDesk.com. All Rights Reserved.
* QuartzDesk.com PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package com.quartzdesk.api.agent.log.jul;
import com.quartzdesk.api.agent.log.LoggingInterceptorWrapper;
import com.quartzdesk.api.agent.log.LoggingInterceptorWrapperException;
import com.quartzdesk.api.agent.log.WorkerThreadLoggingInterceptorRegistry;
import java.util.logging.ErrorManager;
import java.util.logging.Filter;
import java.util.logging.Formatter;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.LogManager;
import java.util.logging.LogRecord;
import java.util.logging.SimpleFormatter;
/**
* Implementation of a Java util logging handler that passes the log records to the QuartzDesk JVM agent that
* intercepts log messages produced by executed jobs.
*
* ==== Example logging.properties ====
* # Handlers
* handlers = ..., com.quartzdesk.api.common.log.jul.JulInterceptionHandler
*
* # QuartzDesk Agent interception handler
* # com.quartzdesk.api.agent.log.jul.JulInterceptionHandler.level = ALL
* # com.quartzdesk.api.agent.log.jul.JulInterceptionHandler.formatter = formatter class
* # com.quartzdesk.api.agent.log.jul.JulInterceptionHandler.filter = filter class
*
* ...
* ====
*
*
* This implementation is not statically bound to the QuartzDesk JVM Agent API, nor to the domain object API.
* Therefore it is safe to use this handler on JVMs running without an installed QuartzDesk JVM Agent.
*
* @version $Id:$
* @see LoggingInterceptorWrapper
*/
public class JulInterceptionHandler
extends Handler
{
private LoggingInterceptorWrapper loggingInterceptor;
/**
* Flag indicating that the logging interceptor failed to initialize.
*/
private boolean loggingInterceptorInitError;
/**
* Creates a new {@link JulInterceptionHandler} instance.
*/
public JulInterceptionHandler()
{
String cname = getClass().getName();
setLevel( getLevelProperty( cname + ".level", Level.INFO ) );
setFilter( getFilterProperty( cname + ".filter", null ) );
setFormatter( getFormatterProperty( cname + ".formatter", new SimpleFormatter() ) );
/*
* The following code cannot be here, because JUL handlers are instantiated BEFORE JVM the QuartzDesk JVM Agent.
* Code moved to the publish method.
*/
// loggingInterceptor = LoggingInterceptorWrapper.create();
}
@Override
public void close()
throws SecurityException
{
loggingInterceptor = null;
}
@Override
public void flush()
{
// no op
}
/**
* If the QuartzDesk agent's logging interceptor wishes to intercept the specified log record, then this method
* formats the log record and passes the result to the logging interceptor.
*
* @param record a log record.
*/
@Override
public void publish( LogRecord record )
{
if ( loggingInterceptorInitError )
return;
// lazy initialization of the loggingInterceptor
if ( loggingInterceptor == null )
{
try
{
loggingInterceptor = LoggingInterceptorWrapper.create();
}
catch ( LoggingInterceptorWrapperException e )
{
loggingInterceptorInitError = true;
// reportError(
// "Cannot initialize " + LoggingInterceptorWrapper.class.getName() + ". Handler " + getClass().getName() +
// " will be disabled.", e, ErrorManager.GENERIC_FAILURE );
reportError(
"Cannot initialize " + LoggingInterceptorWrapper.class.getName() + ". Handler " + getClass().getName() +
" will be disabled. Cause: " + e.getMessage(), null, ErrorManager.GENERIC_FAILURE );
}
}
// ensure that this log record should be logged by this Handler
if ( loggingInterceptor != null && isLoggable( record ) )
{
Long threadId = (long) record.getThreadID();
/*
* The emitter thread can be a worker thread (a thread created / used by the main job thread).
*/
Long jobThreadId = WorkerThreadLoggingInterceptorRegistry.INSTANCE.getJobThreadForWorkerThread( threadId );
if ( jobThreadId != null )
{
threadId = jobThreadId;
}
if ( loggingInterceptor.isIntercepting( threadId ) )
{
LoggingInterceptorWrapper.MessagePriority priority = convertLevel2Priority( record.getLevel() );
String message = getFormatter().format( record );
loggingInterceptor.intercept( threadId, priority, message );
}
}
}
/**
* Returns the {@link LoggingInterceptorWrapper.MessagePriority} for the specified Log4J level.
*
* @param level a Java util logging log level.
* @return the {@link LoggingInterceptorWrapper.MessagePriority} for the specified Log4J level.
*/
protected LoggingInterceptorWrapper.MessagePriority convertLevel2Priority( Level level )
{
if ( level.equals( Level.FINEST ) )
return LoggingInterceptorWrapper.MessagePriority.TRACE;
else if ( level.equals( Level.FINER ) )
return LoggingInterceptorWrapper.MessagePriority.TRACE;
else if ( level.equals( Level.FINE ) )
return LoggingInterceptorWrapper.MessagePriority.DEBUG;
else if ( level.equals( Level.CONFIG ) )
return LoggingInterceptorWrapper.MessagePriority.INFO;
else if ( level.equals( Level.INFO ) )
return LoggingInterceptorWrapper.MessagePriority.INFO;
else if ( level.equals( Level.WARNING ) )
return LoggingInterceptorWrapper.MessagePriority.WARN;
else if ( level.equals( Level.SEVERE ) )
return LoggingInterceptorWrapper.MessagePriority.ERROR;
else
{
reportError( "Cannot map logging level: " + level + ". Using default message priority: " +
LoggingInterceptorWrapper.DEFAULT_MESSAGE_PRIORITY, null, ErrorManager.GENERIC_FAILURE );
return LoggingInterceptorWrapper.DEFAULT_MESSAGE_PRIORITY;
}
}
/**
* Returns the filter instance of the class named by the "name" property. If the property is not defined or has
* problems we return the defaultValue.
*
* Method inspired by the {@code getFilterProperty} method in {@link java.util.logging.StreamHandler}.
*
*
* @param name a logging config property with filter class name.
* @param defaultValue the default filter.
* @return the filter.
*/
protected Filter getFilterProperty( String name, Filter defaultValue )
{
LogManager manager = LogManager.getLogManager();
String val = manager.getProperty( name );
try
{
if ( val != null )
{
Class> clz = ClassLoader.getSystemClassLoader().loadClass( val );
return (Filter) clz.newInstance();
}
}
catch ( Exception ex )
{
// We got one of a variety of exceptions in creating the
// class or creating an instance.
// Drop through.
}
// We got an exception. Return the defaultValue.
return defaultValue;
}
/**
* Returns the formatter instance of the class named by the "name" property. If the property is not defined or has
* problems we return the defaultValue.
*
* Method inspired by the {@code getFormatterProperty} method in {@link java.util.logging.StreamHandler}.
*
*
* @param name a logging config property with formatter class name.
* @param defaultValue the default formatter.
* @return the formatter.
*/
protected Formatter getFormatterProperty( String name, Formatter defaultValue )
{
LogManager manager = LogManager.getLogManager();
String val = manager.getProperty( name );
try
{
if ( val != null )
{
Class> clz = ClassLoader.getSystemClassLoader().loadClass( val );
return (Formatter) clz.newInstance();
}
}
catch ( Exception ex )
{
// We got one of a variety of exceptions in creating the
// class or creating an instance.
// Drop through.
}
// We got an exception. Return the defaultValue.
return defaultValue;
}
/**
* Returns the level for this handler named by the "name". If the property is not defined, then we return the
* defaultValue.
*
* Method inspired by the {@code getLevelProperty} method in {@link java.util.logging.StreamHandler}.
*
*
* @param name a logging config property with level name.
* @param defaultValue the default level.
* @return the level.
*/
protected Level getLevelProperty( String name, Level defaultValue )
{
LogManager manager = LogManager.getLogManager();
String val = manager.getProperty( name );
if ( val == null )
{
return defaultValue;
}
try
{
return Level.parse( val.trim() );
}
catch ( Exception ex )
{
return defaultValue;
}
}
}